添加回复弹幕的用户名称

main
fanpt 3 weeks ago
parent ff7a44477e
commit d48c86fbd1

@ -352,7 +352,7 @@ class DouyinLiveWebReply:
buffer += char buffer += char
if char in self.punctuation: if char in self.punctuation:
if len(buffer.strip()) < 10: if len(buffer.strip()) < 10:
continue # 不够长,继续缓冲 continue
yield buffer.strip() yield buffer.strip()
buffer = '' buffer = ''
if buffer.strip(): if buffer.strip():
@ -388,10 +388,6 @@ class DouyinLiveWebReply:
) )
def post_to_human_sync(self, text: str): def post_to_human_sync(self, text: str):
"""
同步调用post_to_human
:param text: 要发送的文本内容
"""
response = requests.post( response = requests.post(
f'{self.live_chat_config.livetalking_address}/human', f'{self.live_chat_config.livetalking_address}/human',
json={ json={
@ -408,17 +404,13 @@ class DouyinLiveWebReply:
message_count = self.live_chat_config.messages(batch_number) message_count = self.live_chat_config.messages(batch_number)
if message_count == 0: if message_count == 0:
logger.info(f'生成系统文案batch_number: {batch_number}') logger.info(f'生成系统文案batch_number: {batch_number}')
# 结合原始样例话术拼接提示词调用Ollama生成洗稿后的话术
system_messages = self.live_chat_config.system_messages system_messages = self.live_chat_config.system_messages
llm_prompt = self.live_chat_config.refine_system_message_prompt.format( llm_prompt = self.live_chat_config.refine_system_message_prompt.format(
content=system_messages) content=system_messages)
logger.info(f'llm_prompt: {llm_prompt}') logger.info(f'llm_prompt: {llm_prompt}')
reply_messages = self._llm(llm_prompt, False) reply_messages = self._llm(llm_prompt, False)
# 处理reply_messages先转换为json对象将key和value分别对应type和message存入sqlite message表中并统一给batch_number赋值为0
# 正则匹配处理reply_messages只保留大括号及其范围内的字符串
reply_messages = re.findall(r'\{.*?\}', reply_messages, re.DOTALL)[0] reply_messages = re.findall(r'\{.*?\}', reply_messages, re.DOTALL)[0]
reply_messages = json.loads(reply_messages) reply_messages = json.loads(reply_messages)
# 遍历reply_messages对象insert message
for _type, message in reply_messages.items(): for _type, message in reply_messages.items():
self.live_chat_config.insert_message(message, _type, batch_number) self.live_chat_config.insert_message(message, _type, batch_number)
logger.info(f'入库文案:{_type} | {message}') logger.info(f'入库文案:{_type} | {message}')
@ -427,10 +419,11 @@ class DouyinLiveWebReply:
""" """
优先从用户交互队列中取提示词如果没有用户交互的数据则输出系统提示词 优先从用户交互队列中取提示词如果没有用户交互的数据则输出系统提示词
""" """
live_chat_config.update_chat_enable_status('已启动') # 这里修正为使用 self.live_chat_config
self.live_chat_config.update_chat_enable_status('已启动')
logger.info(f'livetalking address -> {self.live_chat_config.livetalking_address}') logger.info(f'livetalking address -> {self.live_chat_config.livetalking_address}')
logger.info(f'ollama_address -> {self.live_chat_config.ollama_address}') logger.info(f'ollama_address -> {self.live_chat_config.ollama_address}')
# 加一个计数器统计is_speaking连续为False的次数如果超过10次才算真正的未在说话
while True: while True:
try: try:
is_speaking = self.config['is_speaking'] is_speaking = self.config['is_speaking']
@ -438,8 +431,16 @@ class DouyinLiveWebReply:
prompt_data = self.queue.get(False) prompt_data = self.queue.get(False)
if prompt_data is not None: if prompt_data is not None:
product_name, product_specification, product_description = self.live_chat_config.product_info product_name, product_specification, product_description = self.live_chat_config.product_info
# live_chat: 弹幕
message_type, prompt, live_chat = prompt_data # 兼容老/新两种数据结构:
# 老结构: (message_type, prompt, live_chat)
# 新结构: (message_type, prompt, live_chat, user_name)
if isinstance(prompt_data, tuple) and len(prompt_data) == 4:
message_type, prompt, live_chat, sender_name = prompt_data
else:
message_type, prompt, live_chat = prompt_data
sender_name = None
if message_type == MessageType.ENTER_LIVE_ROOM.value: if message_type == MessageType.ENTER_LIVE_ROOM.value:
if random.random() >= self.live_chat_config.enter_live_room_prob / 100: if random.random() >= self.live_chat_config.enter_live_room_prob / 100:
continue continue
@ -475,32 +476,33 @@ class DouyinLiveWebReply:
prompt = prompt.format(product_name=product_name, prompt = prompt.format(product_name=product_name,
product_specification=product_specification, product_specification=product_specification,
product_description=product_description) product_description=product_description)
if live_chat is not None: if live_chat is not None:
logger.info(f'弹幕: {live_chat}') logger.info(f'弹幕({sender_name}): {live_chat}')
llm_output = self._llm( llm_output = self._llm(
self.live_chat_config.product_related_prompt.format(content=live_chat)) self.live_chat_config.product_related_prompt.format(content=live_chat))
logger.info(f'判断弹幕是否违反中国大陆法律和政策: {llm_output}') logger.info(f'判断弹幕是否违反中国大陆法律和政策: {llm_output}')
if llm_output != '': if llm_output != '':
continue continue
reply_message = self._llm(prompt, False) reply_message = self._llm(prompt, False)
self.response_queue.put(reply_message) # 这里把“回复内容 + 发送者昵称”一起塞进 response_queue
self.response_queue.put((reply_message, sender_name))
else: else:
# 用户交互队列为空,输出系统文案和文案
if not self.live_chat_config.next_reply_message: if not self.live_chat_config.next_reply_message:
logger.info('文案已用完,重新生成文案') logger.info('文案已用完,重新生成文案')
self.live_chat_config.flush_message() self.live_chat_config.flush_message()
self.generate_messages(1) self.generate_messages(1)
continue continue
else: else:
# 调用Livetalking说话 # 不在说话 -> 从队列/库里取一句话播报
# 判断response_queue是否为空如果不为空则取出回复内容并调用livetalking否则从数据库中取出文案
reply_message = ''
# 判断是否有需要回复的弹幕
if not self.response_queue.empty(): if not self.response_queue.empty():
reply_message = self.response_queue.get() reply_message, from_user = self.response_queue.get()
reply_message = self.reply_message_postprocess(reply_message) reply_message = self.reply_message_postprocess(reply_message)
logger.info(f"开始播放回复弹幕:{reply_message}") if from_user:
logger.info(f"开始播放回复弹幕({from_user}{reply_message}")
else:
logger.info(f"开始播放回复弹幕:{reply_message}")
else: else:
precedence_message = self.live_chat_config.precedence_reply_message precedence_message = self.live_chat_config.precedence_reply_message
if not precedence_message: if not precedence_message:
@ -511,23 +513,17 @@ class DouyinLiveWebReply:
self.generate_messages(1) self.generate_messages(1)
continue continue
reply_message, _id = message reply_message, _id = message
# 状态改为1
logger.info(f'更新文案id:{_id}状态为: 1') logger.info(f'更新文案id:{_id}状态为: 1')
self.live_chat_config.update_next_reply_status(1, _id) self.live_chat_config.update_next_reply_status(1, _id)
else: else:
reply_message, _id = precedence_message reply_message, _id = precedence_message
# 置空优先文案
self.live_chat_config.flush_precedence_reply_message() self.live_chat_config.flush_precedence_reply_message()
logger.info(f"开始播放系统文案:{reply_message}") logger.info(f"开始播放系统文案:{reply_message}")
# 判断self.response_queue.empty()true则打印开始播放弹幕回复false则打印开始播放系统文案
# logger.info(f'开始播放{"弹幕回复" if not self.response_queue.empty() else "系统文案"}: {reply_message}')
self.post_to_human_sync(reply_message) self.post_to_human_sync(reply_message)
# 等0.5秒再检测
time.sleep(1) time.sleep(1)
except Exception: except Exception:
# 发生异常,输出系统文案
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
time.sleep(5) time.sleep(5)
system_messages = self.live_chat_config.system_messages system_messages = self.live_chat_config.system_messages

@ -18,7 +18,7 @@ def parse_chat_msg(payload, queue):
if not content.strip(): if not content.strip():
return return
prompt = live_chat_config.chat_prompt.format(content=content, product_name='{product_name}', product_specification='{product_specification}', product_description='{product_description}') prompt = live_chat_config.chat_prompt.format(content=content, product_name='{product_name}', product_specification='{product_specification}', product_description='{product_description}')
queue.put((MessageType.CHAT.value, prompt, content)) queue.put((MessageType.CHAT.value, prompt, content, user_name))
# logger.info(f"【聊天msg】[{user_id}]{user_name}: {content}") # logger.info(f"【聊天msg】[{user_id}]{user_name}: {content}")
# logger.info(f"队列数量: {queue.qsize()}") # logger.info(f"队列数量: {queue.qsize()}")

Loading…
Cancel
Save