return false;
}
- // 再次验证文件是否存在(双重检查)
+ // 检查文件是否存在(宽松检查)
if (access(videoPath, F_OK) != 0) {
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::SwitchExpressionVideo: file does not exist: %s", videoPath);
return false;
}
- // 检查文件大小,确保文件不为空
+ // 尝试检查文件大小(非强制)
struct stat fileStat;
- if (stat(videoPath, &fileStat) != 0) {
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::SwitchExpressionVideo: cannot get file stat: %s", videoPath);
- return false;
- }
-
- if (fileStat.st_size == 0) {
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::SwitchExpressionVideo: file is empty: %s", videoPath);
- return false;
+ if (stat(videoPath, &fileStat) == 0) {
+ if (fileStat.st_size == 0) {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::SwitchExpressionVideo: file is empty: %s", videoPath);
+ return false;
+ }
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::SwitchExpressionVideo: file size: %ld bytes", fileStat.st_size);
+ } else {
+ WEARABLE_LOGW(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::SwitchExpressionVideo: cannot get file stat for %s, proceeding anyway", videoPath);
}
// 预处理文件路径,确保realpath能够成功
// 通过图形服务调用 ThunderBirdMainView 的 SwitchVideo 函数
// 注意:PostGraphicEvent 是异步的,这里直接返回 true 表示调用已提交
- //GraphicService::GetInstance()->PostGraphicEvent(
- // [normalizedPath]() {
+ GraphicService::GetInstance()->PostGraphicEvent(
+ [normalizedPath]() {
if (ThunderBirdMainView::GetInstance()) {
ThunderBirdMainView::GetInstance()->SwitchVideo(normalizedPath.c_str());
+ } else {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::SwitchExpressionVideo: ThunderBirdMainView instance is null");
}
- //});
+ });
return true; // 异步调用,返回 true 表示调用已提交
}
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleDownloadFile: Unknown download type: %d", type);
break;
}
- //do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_WS_ENTER_SLEEP, NULL, 0);
- AI_ForceInterrupt();
+
+ // 确保屏幕保持亮屏状态,避免下载过程中息屏
+ uapi_set_screen_on_api(); // 亮屏
+
+ // 发送下载开始通知,但不强制中断AI语音(避免息屏)
ln_ws_send_voice_chat_interrupt("开始下载");
+
+ // 切换到OTA界面
NativeAbility::GetInstance().ChangeSlice(VIEW_OTA);
}
void ThunderBirdModel::HandleAudioPlaybackEnd()
{
+ //return;//确保稳定性该版本不使用音频播放结束处理
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleAudioPlaybackEnd");
int currentSubView = ThunderBirdMainView::GetInstance()->GetCurrentSubView();
if(ThunderBirdDialogueView::GetInstance() && currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING)
{
ThunderBirdDialogueView::GetInstance()->AudioPlaybackEnd();
}
-
- // 重置文本处理标志,允许下一轮对话的第一个文本直接显示
- m_hasTextProcessing = false;
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "音频播放结束,重置文本处理标志");
}
+ // 将英文表情映射到英文文件名
+ std::string ThunderBirdModel::MapEmotionToFileName(const char* emotion)
+ {
+ if (emotion == nullptr) return "Smile"; // 默认表情
+
+ std::string emotionStr(emotion);
+
+ // 根据第二张图片的英文表情映射到第一张图片的英文文件名
+ if (emotionStr == "happy") return "Smile";
+ else if (emotionStr == "laughing") return "Laugh";
+ else if (emotionStr == "angry") return "Angry";
+ else if (emotionStr == "wronged") return "Grievance";
+ else if (emotionStr == "heartbeat") return "Heartbeat";
+ else if (emotionStr == "awkward") return "Embarrassed";
+ else if (emotionStr == "confused") return "Doubt";
+ else if (emotionStr == "shocked") return "Shocked";
+ else if (emotionStr == "winking") return "CloseEyes";
+ else if (emotionStr == "crying") return "Tears";
+ else if (emotionStr == "blowing-kiss") return "Kiss";
+ else if (emotionStr == "mischievous") return "Naughty";
+ else if (emotionStr == "speechless") return "Speechless";
+ else if (emotionStr == "dizzy") return "Dizzy";
+ else if (emotionStr == "thinking") return "Think";
+ else if (emotionStr == "sleeppy") return "Sleepy";
+ else if (emotionStr == "working") return "WorkStudy";
+ else if (emotionStr == "exercising") return "Exercise";
+ else if (emotionStr == "playing") return "Play";
+ else if (emotionStr == "daydreaming") return "Stare Blankly";
+ else {
+ // 如果传入的已经是文件名格式,直接返回
+ return emotionStr;
+ }
+ }
+
// NPC表情变化处理函数
void ThunderBirdModel::HandleNpcEmotionChange(const char* emotion)
{
+ //return;//确保稳定性该版本不使用NPC表情变化
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleNpcEmotionChange: %s", emotion ? emotion : "NULL");
if (emotion == nullptr || strlen(emotion) == 0) {
// 记录新的对话界面表情
m_dialogueExpression = emotion;
- // 切换表情
- //if(emotion == "winking")
- std::string expressionPath = "/user/userdata/leiniao/emoji/" + eyesShape_ + "/" + eyesColor_ + "/" + "thinking" + ".mp4";
+ // 切换表情 - 根据眼睛颜色和形状判断是否为默认表情
+ std::string expressionPath;
+ if(eyesColor_.empty() == true || eyesShape_.empty() == true) {
+ // 默认表情
+ std::string emotionFileName = MapEmotionToFileName(emotion);
+ expressionPath = "/user/res/video/Default/" + emotionFileName + ".mp4";
+ } else {
+ // 非默认表情
+ if(m_currentExpression == "winking") {
+ // 如果为眨眼表情,则在默认文件目录里面
+ expressionPath = "/user/res/video/CloseEyes/" + eyesShape_ + "/" + eyesColor_ + ".mp4";
+ } else {
+ // 非眨眼表情,则在下载文件目录里面
+ expressionPath = "/user/userdata/leiniao/emoji/" + eyesShape_ + "/" + eyesColor_ + "/" + m_currentExpression + ".mp4";
+ }
+ }
+
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "NPC表情: %s", expressionPath.c_str());
//判断表情文件是否存在
if(access(expressionPath.c_str(), F_OK) != -1)
// 时间线状态变化处理函数
void ThunderBirdModel::HandleTimelineStatusChange(const char* description, const char* emotion)
{
+ //return;//确保稳定性该版本不使用时间线状态变化
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleTimelineStatusChange");
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Description: %s", description ? description : "NULL");
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Emotion: %s", emotion ? emotion : "NULL");
//为默认表情
if(eyesColor_.empty() == true || eyesShape_.empty() == true)
{
- expressionPath = "/user/res/video/Default/"+ m_currentExpression + ".mp4";
+ std::string emotionFileName = MapEmotionToFileName(m_currentExpression.c_str());
+ expressionPath = "/user/res/video/Default/"+ emotionFileName + ".mp4";
SwitchExpressionVideo(expressionPath.c_str());
}
else//非默认表情
{
- if(m_currentExpression == "CloseEyes")//如果为眨眼表情,则在默认文件目录里面
+ if(m_currentExpression == "winking")//如果为眨眼表情,则在默认文件目录里面
{
expressionPath = "/user/res/video/CloseEyes/" + eyesShape_ + "/" + eyesColor_ + ".mp4";
}
while (!m_audioTextQueue.empty()) {
m_audioTextQueue.pop();
}
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ClearAudioTextQueue: 音频文本队列已清空");
+ // 重置文本处理标志,允许下一轮对话的第一个文本直接显示
+ m_hasTextProcessing = false;
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::ClearAudioTextQueue: 音频文本队列已清空,重置文本处理标志");
}
//夜间更新处理