根据文本情绪权重进行表情切换处理,积极情绪优先

This commit is contained in:
Sakura-RanChen
2025-04-27 11:15:58 +08:00
parent 80be8b2eaa
commit 48427e330f
2 changed files with 170 additions and 11 deletions
@@ -4,14 +4,49 @@ import asyncio
import time
from core.utils.util import (
get_string_no_punctuation_or_emoji,
analyze_emotion
)
TAG = __name__
logger = setup_logging()
emoji_map = {
'neutral': '😶',
'happy': '🙂',
'laughing': '😆',
'funny': '😂',
'sad': '😔',
'angry': '😠',
'crying': '😭',
'loving': '😍',
'embarrassed': '😳',
'surprised': '😲',
'shocked': '😱',
'thinking': '🤔',
'winking': '😉',
'cool': '😎',
'relaxed': '😌',
'delicious': '🤤',
'kissy': '😘',
'confident': '😏',
'sleepy': '😴',
'silly': '😜',
'confused': '🙄'
}
async def sendAudioMessage(conn, audios, text, text_index=0):
# 发送句子开始消息
emotion = analyze_emotion(text)
emoji = emoji_map.get(emotion, '🙂') # 默认使用笑脸
await conn.websocket.send(json.dumps(
{
"type": "llm",
"text": emoji,
"emotion": emotion,
"session_id": conn.session_id,
}
)
)
if text_index == conn.tts_first_text_index:
logger.bind(tag=TAG).info(f"发送第一段语音: {text}")
await send_tts_message(conn, "sentence_start", text)
@@ -86,14 +121,4 @@ async def send_stt_message(conn, text):
await conn.websocket.send(
json.dumps({"type": "stt", "text": stt_text, "session_id": conn.session_id})
)
await conn.websocket.send(
json.dumps(
{
"type": "llm",
"text": "😊",
"emotion": "happy",
"session_id": conn.session_id,
}
)
)
await send_tts_message(conn, "start")
+135 -1
View File
@@ -7,7 +7,29 @@ from typing import Dict, Any
from core.utils import tts, llm, intent, memory, vad, asr
TAG = __name__
emoji_map = {
'neutral': '😶',
'happy': '🙂',
'laughing': '😆',
'funny': '😂',
'sad': '😔',
'angry': '😠',
'crying': '😭',
'loving': '😍',
'embarrassed': '😳',
'surprised': '😲',
'shocked': '😱',
'thinking': '🤔',
'winking': '😉',
'cool': '😎',
'relaxed': '😌',
'delicious': '🤤',
'kissy': '😘',
'confident': '😏',
'sleepy': '😴',
'silly': '😜',
'confused': '🙄'
}
def get_local_ip():
try:
@@ -329,3 +351,115 @@ def initialize_modules(
logger.bind(tag=TAG).info(f"初始化组件: prompt成功 {modules['prompt'][:50]}...")
return modules
def analyze_emotion(text):
"""
分析文本情感并返回对应的emoji名称
"""
if not text or not isinstance(text, str):
return 'neutral'
original_text = text
text = text.lower().strip()
# 检查是否包含现有emoji
for emotion, emoji in emoji_map.items():
if emoji in original_text:
return emotion
# 标点符号分析
has_exclamation = '!' in original_text or '' in original_text
has_question = '?' in original_text or '' in original_text
has_ellipsis = '...' in original_text or '' in original_text
# 定义情感关键词映射(扩展版)
emotion_keywords = {
'happy': ['开心', '高兴', '快乐', '愉快', '幸福', '满意', '', '', '不错', '完美', '棒极了', '太好了',
'好呀', '好的'],
'laughing': ['哈哈', '哈哈哈', '呵呵', '嘿嘿', '嘻嘻', '笑死', '太好笑了', '笑死我了', '笑死我了', '笑抽了'],
'funny': ['搞笑', '滑稽', '', '幽默', '笑点', '段子', '笑话', '太逗了'],
'sad': ['伤心', '难过', '悲哀', '悲伤', '忧郁', '郁闷', '沮丧', '失望', '想哭', '难受', '不开心', '', '呜呜'],
'angry': ['生气', '愤怒', '气死', '讨厌', '烦人', '可恶', '烦死了', '恼火', '暴躁', '火大', '愤怒', '气炸了'],
'crying': ['哭泣', '泪流', '大哭', '伤心欲绝', '泪目', '流泪', '哭死', '哭晕', '想哭', '泪崩'],
'loving': ['爱你', '喜欢', '', '亲爱的', '宝贝', '么么哒', '抱抱', '想你', '思念', '最爱', '亲亲', '喜欢你'],
'embarrassed': ['尴尬', '不好意思', '害羞', '脸红', '难为情', '社死', '丢脸', '出丑'],
'surprised': ['惊讶', '吃惊', '天啊', '哇塞', '', '居然', '竟然', '没想到', '出乎意料'],
'shocked': ['震惊', '吓到', '惊呆了', '不敢相信', '震撼', '吓死', '恐怖', '害怕', '吓人'],
'thinking': ['思考', '考虑', '想一下', '琢磨', '沉思', '冥想', '', '思考中', '在想'],
'winking': ['调皮', '眨眼', '你懂的', '坏笑', '邪恶', '奸笑', '使眼色'],
'cool': ['', '', '厉害', '棒极了', '真棒', '牛逼', '', '优秀', '杰出', '出色', '完美'],
'relaxed': ['放松', '舒服', '惬意', '悠闲', '轻松', '舒适', '安逸', '自在'],
'delicious': ['好吃', '美味', '', '', '可口', '香甜', '大餐', '大快朵颐', '流口水', '垂涎'],
'kissy': ['亲亲', '么么', '', 'mua', 'muah', '亲一下', '飞吻'],
'confident': ['自信', '肯定', '确定', '毫无疑问', '当然', '必须的', '毫无疑问', '确信', '坚信'],
'sleepy': ['', '睡觉', '晚安', '想睡', '好累', '疲惫', '疲倦', '困了', '想休息', '睡意'],
'silly': ['', '', '', '', '', '', '憨憨', '傻乎乎', '呆萌'],
'confused': ['疑惑', '不明白', '不懂', '困惑', '疑问', '为什么', '怎么回事', '啥意思', '不清楚']
}
# 特殊句型判断(扩展版)
# 赞美他人
if any(phrase in text for phrase in
['你真', '你好', '您真', '你真棒', '你好厉害', '你太强了', '你真好', '你真聪明']):
return 'loving'
# 自我赞美
if any(phrase in text for phrase in ['我真', '我最', '我太棒了', '我厉害', '我聪明', '我优秀']):
return 'cool'
# 晚安/睡觉相关
if any(phrase in text for phrase in ['睡觉', '晚安', '睡了', '好梦', '休息了', '去睡了']):
return 'sleepy'
# 疑问句
if has_question and not has_exclamation:
return 'thinking'
# 强烈情感(感叹号)
if has_exclamation and not has_question:
# 检查是否是积极内容
positive_words = emotion_keywords['happy'] + emotion_keywords['laughing'] + emotion_keywords['cool']
if any(word in text for word in positive_words):
return 'laughing'
# 检查是否是消极内容
negative_words = emotion_keywords['angry'] + emotion_keywords['sad'] + emotion_keywords['crying']
if any(word in text for word in negative_words):
return 'angry'
return 'surprised'
# 省略号(表示犹豫或思考)
if has_ellipsis:
return 'thinking'
# 关键词匹配(带权重)
emotion_scores = {emotion: 0 for emotion in emoji_map.keys()}
# 给匹配到的关键词加分
for emotion, keywords in emotion_keywords.items():
for keyword in keywords:
if keyword in text:
emotion_scores[emotion] += 1
# 给长文本中的重复关键词额外加分
if len(text) > 20: # 长文本
for emotion, keywords in emotion_keywords.items():
for keyword in keywords:
emotion_scores[emotion] += text.count(keyword) * 0.5
# 根据分数选择最可能的情感
max_score = max(emotion_scores.values())
if max_score == 0:
return 'happy' # 默认
# 可能有多个情感同分,根据上下文选择最合适的
top_emotions = [e for e, s in emotion_scores.items() if s == max_score]
# 如果多个情感同分,使用以下优先级
priority_order = [
'laughing', 'crying', 'angry', 'surprised', 'shocked', # 强烈情感优先
'loving', 'happy', 'funny', 'cool', # 积极情感
'sad', 'embarrassed', 'confused', # 消极情感
'thinking', 'winking', 'relaxed', # 中性情感
'delicious', 'kissy', 'confident', 'sleepy', 'silly' # 特殊场景
]
for emotion in priority_order:
if emotion in top_emotions:
return emotion
return top_emotions[0] # 如果都不在优先级列表里,返回第一个