From af65fe0c5b11a53806d75d336476dabe9f8dcc3b Mon Sep 17 00:00:00 2001 From: luozheng <1732036298@qq.com> Date: Wed, 5 Nov 2025 17:31:45 +0800 Subject: [PATCH] =?utf8?q?ln:=201.ota=E7=95=8C=E9=9D=A2=E6=B7=BB=E5=8A=A0?= =?utf8?q?=E5=8D=87=E7=BA=A7=E6=8F=8F=E8=BF=B0=E6=9B=B4=E6=96=B0=202.?= =?utf8?q?=E8=A7=A3=E5=86=B3=E6=97=A5=E7=A8=8B=E7=95=8C=E9=9D=A2=E6=97=A0?= =?utf8?q?=E8=AF=AD=E9=9F=B3=E6=92=AD=E6=94=BE=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../nativeui/include/uiservice/ui_service.h | 1 + .../nativeapp/nativeui/ota/include/OtaModel.h | 5 + .../nativeapp/nativeui/ota/src/OtaModel.cpp | 10 + .../nativeui/ota/src/OtaNormalView.cpp | 3 +- .../nativeui/ota/src/OtaObviousView.cpp | 3 +- .../nativeui/ota/src/OtaUpdateNowView.cpp | 3 +- .../nativeui/uiservice/src/ui_service.cpp | 11 + code/sdk/zhihui/leiniao/imsl_ln/ln_api_ota.c | 41 ++- .../zhihui/leiniao/imsl_ln/ln_api_schedule.c | 4 +- .../zhihui/leiniao/ln_api_cpp/CMakeLists.txt | 4 + .../leiniao/ln_api_cpp/ln_api_interface.cpp | 7 + .../leiniao/ln_api_cpp/ln_api_interface.h | 2 + .../leiniao/ln_api_cpp/ln_audio_simple.cpp | 264 ++++++++++++++++++ .../leiniao/ln_api_cpp/ln_audio_simple.h | 49 ++++ 14 files changed, 395 insertions(+), 12 deletions(-) create mode 100644 code/sdk/zhihui/leiniao/ln_api_cpp/ln_audio_simple.cpp create mode 100644 code/sdk/zhihui/leiniao/ln_api_cpp/ln_audio_simple.h diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/include/uiservice/ui_service.h b/code/sdk/application/wearable/ln/nativeapp/nativeui/include/uiservice/ui_service.h index a7ce3d1ba..c95087847 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/include/uiservice/ui_service.h +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/include/uiservice/ui_service.h @@ -72,6 +72,7 @@ typedef enum { HAND_AUDIO_RECORDING_END_NOTIFY, // 录音结束通知 HAND_NPC_EMOTION_CHANGE_NOTIFY, // npc表情变化通知 HAND_TIMELINE_STATUS_CHANGE_NOTIFY, // 时间线状态变化通知 + HAND_UPGRADE_DESCRIPTION_NOTIFY, // 升级描述通知 MAX_NUM_HANDLER, } UiServiceMsgId; diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/include/OtaModel.h b/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/include/OtaModel.h index 5618ccfea..6a034274a 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/include/OtaModel.h +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/include/OtaModel.h @@ -72,6 +72,9 @@ namespace OHOS void HandleDownloadProgress(int progress); void HandleDownloadEta(int seconds); void HandleDownloadFail(int type); + + void SetUpgradeDescription(const std::string& description); + std::string GetUpgradeDescription() const; private: OtaModel(); virtual ~OtaModel(); @@ -92,6 +95,8 @@ namespace OHOS // 夜间更新状态 bool m_nightUpdateEnabled; // 夜间更新是否启用 + + std::string m_upgradeDescription; // 升级描述 }; } diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaModel.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaModel.cpp index 505d062ce..c0a8bccff 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaModel.cpp +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaModel.cpp @@ -497,4 +497,14 @@ namespace OHOS UtilsSetValue("night_update_enabled", "0"); WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OtaModel: Night update status cleared from KV storage"); } + + void OtaModel::SetUpgradeDescription(const std::string& description) + { + m_upgradeDescription = description; + } + + std::string OtaModel::GetUpgradeDescription() const + { + return m_upgradeDescription; + } } diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaNormalView.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaNormalView.cpp index cbe21bf0b..448941275 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaNormalView.cpp +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaNormalView.cpp @@ -5,6 +5,7 @@ */ #include "ota/include/OtaNormalView.h" #include "ota/include/OtaPresenter.h" +#include "ota/include/OtaModel.h" #include "wearable_log.h" namespace OHOS @@ -62,7 +63,7 @@ namespace OHOS LittleTextLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); LittleTextLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 18); LittleTextLabel->SetStyle(STYLE_TEXT_COLOR, 0xffcccccc); - LittleTextLabel->SetText("全新功能已推出,现在Amby可以哄你睡觉"); + LittleTextLabel->SetText(OtaModel::GetInstance()->GetUpgradeDescription().c_str()); LittleTextLabel->SetVisible(true); group->Add(LittleTextLabel); } diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaObviousView.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaObviousView.cpp index 51ddb48ef..fe5c90fe8 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaObviousView.cpp +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaObviousView.cpp @@ -5,6 +5,7 @@ */ #include "ota/include/OtaObviousView.h" #include "ota/include/OtaPresenter.h" +#include "ota/include/OtaModel.h" #include "wearable_log.h" namespace OHOS @@ -64,7 +65,7 @@ namespace OHOS LittleTextLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); LittleTextLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 18); LittleTextLabel->SetStyle(STYLE_TEXT_COLOR, 0xffcccccc); - LittleTextLabel->SetText("全新功能已推出,现在Amby可以哄你睡觉"); + LittleTextLabel->SetText(OtaModel::GetInstance()->GetUpgradeDescription().c_str()); LittleTextLabel->SetLineBreakMode(UILabel::LINE_BREAK_WRAP); LittleTextLabel->SetVisible(true); group->Add(LittleTextLabel); diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaUpdateNowView.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaUpdateNowView.cpp index c41183e32..6e0ea54fa 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaUpdateNowView.cpp +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/ota/src/OtaUpdateNowView.cpp @@ -5,6 +5,7 @@ */ #include "ota/include/OtaUpdateNowView.h" #include "ota/include/OtaPresenter.h" +#include "ota/include/OtaModel.h" #include "wearable_log.h" namespace OHOS @@ -65,7 +66,7 @@ namespace OHOS LittleTextLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER); LittleTextLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 18); LittleTextLabel->SetStyle(STYLE_TEXT_COLOR, 0xffcccccc); - LittleTextLabel->SetText("为保障您的产品安全,部分功能将在更新后恢复使用"); + LittleTextLabel->SetText(OtaModel::GetInstance()->GetUpgradeDescription().c_str()); LittleTextLabel->SetVisible(true); group->Add(LittleTextLabel); } diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/uiservice/src/ui_service.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/uiservice/src/ui_service.cpp index 79dcafe7c..c29510ecd 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/uiservice/src/ui_service.cpp +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/uiservice/src/ui_service.cpp @@ -108,6 +108,7 @@ static void HandAudioRecordingStartNotify(Request *request); static void HandAudioRecordingEndNotify(Request *request); static void HandNpcEmotionChangeNotify(Request *request); static void HandTimelineStatusChangeNotify(Request *request); +static void HandUpgradeDescriptionNotify(Request *request); // 消息处理程序项数组(每个消息类型对应一个处理函数,函数名以 Handle 开头) MsgHandlerEntry msgHandlers[] = { {HANDLE_JUMP_OTA_VIEW, HandleJumpOtaView}, @@ -132,6 +133,7 @@ MsgHandlerEntry msgHandlers[] = { {HAND_AUDIO_RECORDING_END_NOTIFY,HandAudioRecordingEndNotify}, {HAND_NPC_EMOTION_CHANGE_NOTIFY,HandNpcEmotionChangeNotify}, {HAND_TIMELINE_STATUS_CHANGE_NOTIFY,HandTimelineStatusChangeNotify}, + {HAND_UPGRADE_DESCRIPTION_NOTIFY,HandUpgradeDescriptionNotify}, }; /* -------------------------------------------------------------------------- */ void ScreenTurnOn(int32_t timeout) @@ -777,6 +779,15 @@ void HandTimelineStatusChangeNotify(Request *request) } }); } + +void HandUpgradeDescriptionNotify(Request *request) +{ + WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandUpgradeDescriptionNotify msg_id = %d", request->msgId); + std::string description(static_cast(request->data), request->len); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandUpgradeDescriptionNotify description = %s", description.c_str()); + GraphicService::GetInstance()->PostGraphicEvent( + std::bind(&OHOS::OtaModel::SetUpgradeDescription,OHOS::OtaModel::GetInstance(), description.c_str())); +} /* -------------------------------------------------------------------------- */ #ifdef __cplusplus } diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_ota.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_ota.c index f394b3986..ea53de298 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_ota.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_ota.c @@ -160,11 +160,33 @@ static void ln_handle_ota_task_response(const char *json_buf, int json_len) return; } + /* + { + "errorCode": null, + "message": null, + "data": { + "updateId": 123, 升级任务ID + "sourceVersion": "1.0.0", 源版本号 + "targetVersion": "1.1.0", 目标版本号 + "updateType": 1, 升级类型,0:紧急修复,1:重要更新,2:普通更新 + "packageId": 456, 升级包ID + "packageUrl": "https://example.com/firmware/update_1.1.0.bin", 升级包下载URL + "packageMd5": "a1b2c3d4e5f6789012345678901234567890", 升级包MD5校验值 + "packageSize": 1048576, 升级包大小(字节) + "description": "升级描述" 升级描述 + } + } + */ + + cJSON *updateId = cJSON_GetObjectItem(data, "updateId"); + cJSON *sourceVersion = cJSON_GetObjectItem(data, "sourceVersion"); cJSON *targetVersion = cJSON_GetObjectItem(data, "targetVersion"); cJSON *updateType = cJSON_GetObjectItem(data, "updateType"); + cJSON *packageId = cJSON_GetObjectItem(data, "packageId"); cJSON *packageUrl = cJSON_GetObjectItem(data, "packageUrl"); cJSON *packageMd5 = cJSON_GetObjectItem(data, "packageMd5"); cJSON *packageSize = cJSON_GetObjectItem(data, "packageSize"); + cJSON *description = cJSON_GetObjectItem(data, "description"); uapi_ln_set_ota_package_size(packageSize ? (int)packageSize->valuedouble : 0); if (!(targetVersion && cJSON_IsString(targetVersion) && updateType && (cJSON_IsNumber(updateType) || cJSON_IsString(updateType)))) @@ -181,10 +203,11 @@ static void ln_handle_ota_task_response(const char *json_buf, int json_len) else if (cJSON_IsString(updateType)) ut = atoi(updateType->valuestring); g_ln_last_update_type = ut; - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"[OTA] task parsed: targetVersion=%s updateType=%d url=%s md5=%s", + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"[OTA] task parsed: targetVersion=%s updateType=%d url=%s md5=%s description=%s", targetVersion->valuestring, ut, (packageUrl && cJSON_IsString(packageUrl)) ? packageUrl->valuestring : "", - (packageMd5 && cJSON_IsString(packageMd5)) ? packageMd5->valuestring : ""); + (packageMd5 && cJSON_IsString(packageMd5)) ? packageMd5->valuestring : "", + (description && cJSON_IsString(description)) ? description->valuestring : ""); /* 记录必要字段供后续 AT^LN_OTA_DOWNLOAD 使用 */ if (g_ln_last_target_version) { free(g_ln_last_target_version); g_ln_last_target_version = NULL; } if (g_ln_last_package_url) { free(g_ln_last_package_url); g_ln_last_package_url = NULL; } @@ -210,21 +233,23 @@ static void ln_handle_ota_task_response(const char *json_buf, int json_len) if (g_ln_last_package_size < 0) g_ln_last_package_size = 0; } - if (ut == 1) + if (description && cJSON_IsString(description)) { + push_upgrade_description_notification(description->valuestring); + } else { + push_upgrade_description_notification(""); + } + + if (ut == 0) { /* 强制升级:直接触发下载 */ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"[OTA] force upgrade: trigger download(强制升级:直接触发下载)"); push_ota_status(OTA_UI_STATUS_FORCE_START); } - else if (ut == 0) + else { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"[OTA] optional upgrade: waiting for user confirmation(可选升级:等待用户确认)"); push_ota_status(OTA_UI_STATUS_OPTIONAL_START); } - else - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"[OTA] unknown updateType, skip"); - } cJSON_Delete(root); free(text); 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 2353a6b36..ed8b78e5d 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_schedule.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_schedule.c @@ -7,6 +7,7 @@ #include "wearable_log.h" #include "ai_media.h" #include "audio_stream_player.h" +#include "ln_audio_simple.h" ScheduleReminder g_schedule_reminder = {0}; ScheduleReminderConfig g_schedule_reminder_config = {0}; @@ -232,9 +233,10 @@ 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); + ln_audio_simple_play(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 2ac4dd987..2ca54bd51 100644 --- a/code/sdk/zhihui/leiniao/ln_api_cpp/CMakeLists.txt +++ b/code/sdk/zhihui/leiniao/ln_api_cpp/CMakeLists.txt @@ -16,12 +16,16 @@ ${ROOT_DIR}/middleware/services/media/foundation/audiomanager/frameworks/audiost ${ROOT_DIR}/middleware/services/media/foundation/sample/wrapper ${ROOT_DIR}/middleware/services/media/foundation/utils/include ${ROOT_DIR}/application/wearable/ln/nativeapp/nativeui/ +${ROOT_DIR}/open_source/openharmony/foundation/multimedia/player/interfaces/kits/ +${ROOT_DIR}/middleware/services/gui/uikit/surface/interfaces/kits/ +${ROOT_DIR}/open_source/openharmony/drivers/peripheral/display/interfaces/include/ ) 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 +${CMAKE_CURRENT_SOURCE_DIR}/ln_audio_simple.cpp ) set(SOURCES diff --git a/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.cpp b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.cpp index 351949246..bfa7c578e 100644 --- a/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.cpp +++ b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.cpp @@ -298,6 +298,13 @@ void push_timeline_status_change_notification(const char *description, const cha (void)snprintf(payload, sizeof(payload) - 1, "%s|%s", d, e); SendMsgToUIService(HAND_TIMELINE_STATUS_CHANGE_NOTIFY, 0, (void *)payload, (int32_t)strlen(payload)); } + +//推送升级描述 +void push_upgrade_description_notification(const char *description) +{ + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[UPGRADE_DESCRIPTION] description=%s", description); + SendMsgToUIService(HAND_UPGRADE_DESCRIPTION_NOTIFY, 0, (void *)description, (int32_t)strlen(description)); +} #ifdef __cplusplus }; #endif \ No newline at end of file diff --git a/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h index befc686fd..e6cccc3e3 100644 --- a/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h +++ b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h @@ -111,6 +111,8 @@ void push_audio_recording_end_notification(void); void push_npc_emotion_change_notification(const char *emotion); //通知时间线状态变化 void push_timeline_status_change_notification(const char *description, const char *emotion); +//推送升级描述 +void push_upgrade_description_notification(const char *description); #ifdef __cplusplus } #endif diff --git a/code/sdk/zhihui/leiniao/ln_api_cpp/ln_audio_simple.cpp b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_audio_simple.cpp new file mode 100644 index 000000000..95ff3a3db --- /dev/null +++ b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_audio_simple.cpp @@ -0,0 +1,264 @@ +#include +#include +/* C 接口头文件 */ +#include "ln_audio_simple.h" +#include +#include +#include +#include +#include +#include +#include +/* 引入播放器相关头文件 */ +#include "player.h" +#include "source.h" +#include "audio_manager.h" +#include +#include +#include +#include + +using OHOS::Media::Player; +using OHOS::Media::Source; +using namespace OHOS::Media; +using namespace ::Audio; +using Audio::AudioManager; + + + +typedef struct +{ + std::shared_ptr player; + std::shared_ptr source; + std::map header; + + AudioSession sessionId; + std::shared_ptr interrupt; + std::shared_ptr interruptListener; + + bool audio_initialized; + bool is_activate_audio_interrupt; + bool is_playing; + bool is_paused; +} ln_audio_simple_impl_t; + +static ln_audio_simple_impl_t g_simple = {0}; + +class SimpleSingleInterruptListener : public InterruptListener +{ +public: + SimpleSingleInterruptListener(ln_audio_simple_impl_t *impl) : impl_(impl) {} + + void OnInterrupt(int32_t type, int32_t hint) override + { + if (!impl_) return; + if (type == INTERRUPT_TYPE_BEGIN && hint == INTERRUPT_HINT_PAUSE) + { + if (impl_->is_playing && impl_->player) + { + impl_->player->Pause(); + impl_->is_paused = true; + } + } + else if (type == INTERRUPT_TYPE_END && hint == INTERRUPT_HINT_RESUME) + { + if (impl_->is_playing && impl_->player && impl_->is_paused) + { + impl_->player->Play(); + impl_->is_paused = false; + } + } + else if (type == INTERRUPT_TYPE_BEGIN && hint == INTERRUPT_HINT_STOP) + { + if (impl_->is_playing && impl_->player) + { + impl_->player->Stop(); + impl_->is_playing = false; + } + } + } + +private: + ln_audio_simple_impl_t *impl_; +}; + +static bool AudioInitOnce(void) +{ + if (g_simple.audio_initialized) + return true; + + AudioManager &amInstance = AudioManager::GetInstance(); + if (!amInstance.Initialize()) + { + printf("[LN_AUDIO_SIMPLE] AudioManager Initialize failed\n"); + return false; + } + + g_simple.player = std::make_shared(); + if (!g_simple.player) + { + printf("[LN_AUDIO_SIMPLE] Player create failed\n"); + return false; + } + + g_simple.audio_initialized = true; + g_simple.is_activate_audio_interrupt = false; + g_simple.is_playing = false; + g_simple.is_paused = false; + return true; +} + +static bool EnsureAudioInterrupt() +{ + if (g_simple.is_activate_audio_interrupt) + return true; + + AudioManager &amInstance = AudioManager::GetInstance(); + g_simple.sessionId = amInstance.MakeSessionId(); + if (g_simple.sessionId == AUDIO_SESSION_ID_NONE) + { + printf("[LN_AUDIO_SIMPLE] MakeSessionId failed\n"); + return false; + } + + g_simple.interruptListener = std::make_shared(&g_simple); + g_simple.interrupt = std::make_shared(); + g_simple.interrupt->streamType = AUDIO_STREAM_ALARM_CLOCK; + g_simple.interrupt->sessionID = g_simple.sessionId; + g_simple.interrupt->interruptListener = g_simple.interruptListener; + + if (amInstance.ActivateAudioInterrupt(*g_simple.interrupt) == INTERRUPT_FAILED) + { + printf("[LN_AUDIO_SIMPLE] ActivateAudioInterrupt failed\n"); + return false; + } + + g_simple.is_activate_audio_interrupt = true; + return true; +} + +static void ClearAudioInterrupt() +{ + if (g_simple.is_activate_audio_interrupt && g_simple.interrupt && g_simple.sessionId != AUDIO_SESSION_ID_NONE) + { + AudioManager &amInstance = AudioManager::GetInstance(); + amInstance.DeactivateAudioInterrupt(*g_simple.interrupt); + g_simple.is_activate_audio_interrupt = false; + } + g_simple.interrupt.reset(); + g_simple.interruptListener.reset(); +} + +extern "C" { + +int ln_audio_simple_play(const char *file_path) +{ + if (!file_path || file_path[0] == '\0') + { + printf("[LN_AUDIO_SIMPLE] invalid file path\n"); + return -1; + } + + if (!AudioInitOnce()) + return -2; + + // 若正在播放,先停止 + (void)ln_audio_simple_stop(); + + // 设置音频源 + g_simple.source = std::make_shared(file_path, g_simple.header); + if (!g_simple.source) + { + printf("[LN_AUDIO_SIMPLE] create Source failed\n"); + return -3; + } + + int32_t ret; + ret = g_simple.player->SetSource(*g_simple.source); + if (ret != 0) + { + printf("[LN_AUDIO_SIMPLE] SetSource failed: %d\n", ret); + g_simple.player->Reset(); + return -4; + } + + g_simple.player->EnableSingleLooping(false); + g_simple.player->SetAudioStreamType(AUDIO_STREAM_ALARM_CLOCK); + + ret = g_simple.player->Prepare(); + if (ret != 0) + { + printf("[LN_AUDIO_SIMPLE] Prepare failed: %d\n", ret); + g_simple.player->Reset(); + return -5; + } + + if (!EnsureAudioInterrupt()) + { + g_simple.player->Reset(); + return -6; + } + + ret = g_simple.player->SetAudioSessionId(g_simple.sessionId); + if (ret != 0) + { + printf("[LN_AUDIO_SIMPLE] SetAudioSessionId failed: %d\n", ret); + g_simple.player->Reset(); + ClearAudioInterrupt(); + return -7; + } + + ret = g_simple.player->Play(); + if (ret != 0) + { + printf("[LN_AUDIO_SIMPLE] Play failed: %d\n", ret); + g_simple.player->Stop(); + g_simple.player->Reset(); + ClearAudioInterrupt(); + return -8; + } + + g_simple.is_playing = true; + g_simple.is_paused = false; + printf("[LN_AUDIO_SIMPLE] started: %s\n", file_path); + return 0; +} + +int ln_audio_simple_stop(void) +{ + if (!g_simple.player) + return 0; + + int32_t state = 0; + (void)g_simple.player->GetPlayerState(state); + + if (state == PLAYER_STARTED || state == PLAYER_PLAYBACK_COMPLETE) + { + (void)g_simple.player->Stop(); + (void)g_simple.player->Reset(); + } + else if (state == PLAYER_PAUSED || state == PLAYER_IDLE) + { + (void)g_simple.player->Reset(); + } + else + { + (void)g_simple.player->Stop(); + (void)g_simple.player->Reset(); + } + + ClearAudioInterrupt(); + + g_simple.is_playing = false; + g_simple.is_paused = false; + return 0; +} + +bool ln_audio_simple_is_playing(void) +{ + return g_simple.is_playing; +} + +} // extern "C" + + diff --git a/code/sdk/zhihui/leiniao/ln_api_cpp/ln_audio_simple.h b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_audio_simple.h new file mode 100644 index 000000000..70eaf9c57 --- /dev/null +++ b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_audio_simple.h @@ -0,0 +1,49 @@ +/* + * 简易音频播放接口(C) + * 设计目标:简单、稳定,用一行代码播放单个本地音频文件 + * 用法示例: + * ln_audio_simple_play("/user/audio/demo.mp3"); + * // ... 需要中断播放时: + * ln_audio_simple_stop(); + * // 查询是否还在播放: + * // if (ln_audio_simple_is_playing()) { ... } + */ + +#ifndef LN_AUDIO_SIMPLE_H +#define LN_AUDIO_SIMPLE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * 播放本地音频文件(目前支持常见压缩音频,如 mp3,由底层流式播放器解码) + * 参数: + * file_path - 音频文件的绝对路径 + * 返回: + * 0 成功启动播放(异步) + * <0 失败 + */ +int ln_audio_simple_play(const char *file_path); + +/* + * 主动停止播放(同步停止,确保资源释放) + * 返回:0 成功,<0 失败 + */ +int ln_audio_simple_stop(void); + +/* + * 查询当前是否处于播放中 + */ +bool ln_audio_simple_is_playing(void); + +#ifdef __cplusplus +} +#endif + +#endif /* LN_AUDIO_SIMPLE_H */ + + -- 2.17.1