From: luozheng <1732036298@qq.com> Date: Tue, 21 Oct 2025 04:07:20 +0000 (+0800) Subject: ln:解决日程音频不播放问题,播放完后销毁播放线程 X-Git-Tag: V1.0.9_20251128_194606_LN~190 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=e62cfcef1d8690049038e2232c8355feeda666d9;p=mirrors%2FFD230.git ln:解决日程音频不播放问题,播放完后销毁播放线程 --- diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_schedule.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_schedule.c index 9b79fde49..519afb65d 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_schedule.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_schedule.c @@ -6,6 +6,7 @@ #include "vibrator_service.h" #include "wearable_log.h" #include "ai_media.h" +#include "audio_stream_player.h" ScheduleReminder g_schedule_reminder = {0}; ScheduleReminderConfig g_schedule_reminder_config = {0}; @@ -225,7 +226,9 @@ void ln_parse_schedule_reminder(const char *json_buf, int json_len) WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[JSON_PARSE] vibration:不执行震动\n"); } // 从文件中读取数据放到音频流内 - play_mp3_audio_from_file(LN_REMINDER_AUDIO_FILE); + // play_mp3_audio_from_file(LN_REMINDER_AUDIO_FILE); + // 下载成功后 + ln_audio_player_play_file(LN_REMINDER_AUDIO_FILE); } else { diff --git a/code/sdk/zhihui/leiniao/ln_api_cpp/CMakeLists.txt b/code/sdk/zhihui/leiniao/ln_api_cpp/CMakeLists.txt index 3db202a2e..2ac4dd987 100644 --- a/code/sdk/zhihui/leiniao/ln_api_cpp/CMakeLists.txt +++ b/code/sdk/zhihui/leiniao/ln_api_cpp/CMakeLists.txt @@ -21,6 +21,7 @@ ${ROOT_DIR}/application/wearable/ln/nativeapp/nativeui/ set(AI_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/audio_stream_player.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ln_api_interface.cpp +${CMAKE_CURRENT_SOURCE_DIR}/audio_stream_player.cpp ) set(SOURCES diff --git a/code/sdk/zhihui/leiniao/ln_api_cpp/audio_stream_player.cpp b/code/sdk/zhihui/leiniao/ln_api_cpp/audio_stream_player.cpp index 5b6b6a95e..a3650148a 100644 --- a/code/sdk/zhihui/leiniao/ln_api_cpp/audio_stream_player.cpp +++ b/code/sdk/zhihui/leiniao/ln_api_cpp/audio_stream_player.cpp @@ -7,10 +7,10 @@ #include "audio_stream_player.h" #include +#include #include #include #include -#include // 包含音频管理相关头文件 #include "audio_manager_c_wrapper.h" @@ -246,7 +246,7 @@ int32_t AudioStreamPlayerInit(AudioStreamPlayerHandle handle, } // 激活音频中断 - if (AudioManagerActivateInterrupt(AUDIO_STREAM_VOICE_ASSISTANT, sessionId) == INTERRUPT_FAILED) + if (AudioManagerActivateInterrupt(AUDIO_STREAM_ALARM_CLOCK, sessionId) == INTERRUPT_FAILED) { MEDIA_ERR_LOG("AudioStreamPlayerInit: failed to activate audio interrupt"); return -1; @@ -259,7 +259,7 @@ int32_t AudioStreamPlayerInit(AudioStreamPlayerHandle handle, renderConfig.linkDir = AUDIO_UP_LINK; // 上行链路,用于播放 renderConfig.sampleRate = ctx->config.sampleRate; renderConfig.sessionID = sessionId; - renderConfig.streamType = AUDIO_STREAM_VOICE_ASSISTANT; + renderConfig.streamType = AUDIO_STREAM_ALARM_CLOCK; // 初始化音频输出流 int32_t ret = AudioStreamOutInit(renderConfig); @@ -311,7 +311,7 @@ int32_t AudioStreamPlayerStart(AudioStreamPlayerHandle handle) task_cfg.create_queue_handle = CreateAudioStreamQueue; task_cfg.attr.name = "AudioStreamPlayThread"; task_cfg.attr.priority = (osPriority_t)16; - task_cfg.attr.stack_size = 0x2000; // 8KB + task_cfg.attr.stack_size = 0x1000; // 8KB task_cfg.func = AudioStreamPlayThread; task_cfg.use_mem = USE_EXTEND_MEM; extern errcode_t uapi_create_osThread_custom(app_task_definition_t * task_cfg); @@ -587,7 +587,7 @@ int32_t AudioStreamPlayerSetVolume(AudioStreamPlayerHandle handle, float volume) AudioStreamPlayerContext *ctx = (AudioStreamPlayerContext *)handle; ctx->volume = volume; // 设置音频流音量 - 使用AudioManagerSetVolume - AudioManagerSetVolume(AUDIO_STREAM_VOICE_ASSISTANT, (int32_t)(volume * 100)); + AudioManagerSetVolume(AUDIO_STREAM_ALARM_CLOCK, (int32_t)(volume * 100)); WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"AudioStreamPlayerSetVolume: set to %.2f", volume); return 0; } @@ -713,6 +713,74 @@ int32_t ln_audio_player_get_stats(AudioStreamStats* stats) return AudioStreamPlayerGetStats(g_ln_audio_player, stats); } +uint32_t ln_audio_player_stop(void) +{ + if (g_ln_audio_player == nullptr) { + return ERRCODE_SUCC; + } + (void)AudioStreamPlayerDestroy(g_ln_audio_player); + g_ln_audio_player = nullptr; + return ERRCODE_SUCC; +} + +uint32_t ln_audio_player_play_file(const char *file_path) +{ + if (file_path == nullptr) { + return ERRCODE_FAIL; + } + + FILE *file = fopen(file_path, "rb"); + if (file == nullptr) { + return ERRCODE_FAIL; + } + + if (ln_audio_player_init() != ERRCODE_SUCC) { + fclose(file); + return ERRCODE_FAIL; + } + + // 获取文件大小(可用于完成判定的辅助) + long file_size = 0; + long current_pos = ftell(file); + if (current_pos >= 0) { + (void)fseek(file, 0, SEEK_END); + file_size = ftell(file); + (void)fseek(file, 0, SEEK_SET); + } + + const size_t CHUNK_SIZE = 1024; // 与现有用法一致 + uint8_t buffer[CHUNK_SIZE]; + size_t read_len; + while ((read_len = fread(buffer, 1, CHUNK_SIZE, file)) > 0) { + if (ln_audio_player_write(buffer, (uint32_t)read_len) != 0) { + fclose(file); + (void)ln_audio_player_stop(); + return ERRCODE_FAIL; + } + } + fclose(file); + + // 先等待播放队列清空 + const int wait_step_us = 50 * 1000; // 50ms + for (;;) { + AudioStreamStats stats = {0}; + if (ln_audio_player_get_stats(&stats) == 0) { + if (stats.queueCurrentSize == 0) { + break; + } + } + usleep(wait_step_us); + } + + // 再额外等待尾部缓冲播放完成,避免被立即Stop打断结尾 + const int tail_grace_us = 2000 * 1000; // 2s + usleep(tail_grace_us); + + // 停止并销毁,确保线程回收 + (void)ln_audio_player_stop(); + return ERRCODE_SUCC; +} + #ifdef __cplusplus }; #endif \ No newline at end of file diff --git a/code/sdk/zhihui/leiniao/ln_api_cpp/audio_stream_player.h b/code/sdk/zhihui/leiniao/ln_api_cpp/audio_stream_player.h index 2da912191..8cf03d2f0 100644 --- a/code/sdk/zhihui/leiniao/ln_api_cpp/audio_stream_player.h +++ b/code/sdk/zhihui/leiniao/ln_api_cpp/audio_stream_player.h @@ -153,6 +153,19 @@ int32_t ln_audio_player_get_stats(AudioStreamStats* stats); uint32_t ln_audio_player_pause(void); uint32_t ln_audio_player_resume(void); +/** + * @brief 播放指定音频文件(阻塞至播放完成并关闭播放线程) + * @param file_path 音频文件路径 + * @return ERRCODE_SUCC 成功,ERRCODE_FAIL 失败 + */ +uint32_t ln_audio_player_play_file(const char *file_path); + +/** + * @brief 立即停止并销毁播放器(如已初始化) + * @return ERRCODE_SUCC + */ +uint32_t ln_audio_player_stop(void); + #ifdef __cplusplus } #endif