* @Author: luozheng 1732036298@qq.com\r
* @Date: 2024-04-07 18:15:53\r
* @LastEditors: luozheng 1732036298@qq.com\r
- * @LastEditTime: 2024-04-08 19:42:10\r
+ * @LastEditTime: 2024-04-09 15:27:19\r
* @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/countdown/include/CountDownModel.h\r
*/\r
#ifndef COUNTDOWN_MODEL_H\r
#define COUNTDOWN_MODEL_H\r
\r
#include <iostream>\r
+#include "source.h"\r
+#include "audio_manager.h"\r
+#include "../../../../../../middleware/services/media/foundation/player/interfaces/kits/player.h"\r
namespace OHOS\r
{\r
+ using OHOS::Media::Player;\r
+ using OHOS::Media::Source;\r
+ using namespace OHOS::Media;\r
+ using namespace Audio;\r
+ using Audio::AudioManager;\r
+\r
+ // 计时器铃声播放监听类\r
+ class CountDownRingPlayerListener : public InterruptListener\r
+ {\r
+ public:\r
+ CountDownRingPlayerListener() {}\r
+ ~CountDownRingPlayerListener() {}\r
+\r
+ void SetOwner(std::shared_ptr<Player> player);\r
+ void RestFlag();\r
+ bool IsPaused();\r
+ bool IsDelayed();\r
+ bool IsResumed();\r
+ bool IsBeginStopped();\r
+ bool IsEndStopped();\r
+ void StopCountDownRing();\r
+ void StartCountDownRing();\r
+ void OnInterrupt(int32_t type, int32_t hint) override;\r
+\r
+ private:\r
+ std::shared_ptr<Player> player_{nullptr};\r
+ bool isPaused_{false};\r
+ bool isDelayed_{false};\r
+ bool isResumed_{false};\r
+ bool isBeginStopped_{false};\r
+ bool isEndStopped_{false};\r
+ };\r
+\r
+ /*处理计时器铃声媒体播放事件的类*/\r
+ class CountDownRingPlayerCallbackImpl : public OHOS::Media::PlayerCallback\r
+ {\r
+ public:\r
+ CountDownRingPlayerCallbackImpl() {}\r
+ ~CountDownRingPlayerCallbackImpl() {}\r
+ /*媒体播放完毕时被调用*/\r
+ void OnPlaybackComplete();\r
+ /*当播放过程中发生错误时,此方法将被调用,提供了错误类型和错误代码以供分析和处理。*/\r
+ void OnError(int32_t errorType, int32_t errorCode);\r
+ /*在播放过程中,为处理某些信息而调用该方法,信息类型和额外数据通过参数提供。*/\r
+ void OnInfo(int type, int extra);\r
+ /*当跳转操作完成时(例如快进到某个特定位置),该方法被调用*/\r
+ void OnRewindToComplete();\r
+ };\r
+\r
class CountDownModel\r
{\r
public:\r
void CountDown_PauseTimer(void);\r
void CountDown_ResumeTimer(uint32_t interval);\r
\r
+ /*播放器相关函数*/\r
+ int CountDownRingPlayerInit(const char *RingMusicName);\r
+ int InitializeAndPlayRingtone(void);\r
+ int StartRingtonePlayback(void);\r
+ int StopRingtonePlaybackAndReleaseResources(void);\r
+ void RequestStartRingtone(void);\r
+ void RequestStopRingtone(void);\r
+ int ResetRingtonePlayback(void);\r
+\r
+ public:\r
static int g_CountDownTimes;\r
\r
private:\r
CountDownModel() {}\r
~CountDownModel() {}\r
+ CountDownModel(const CountDownModel &) = delete;\r
+ CountDownModel &operator=(const CountDownModel &) = delete;\r
+\r
+ std::string uri;\r
+ std::shared_ptr<PlayerCallback> playerCallback{nullptr};\r
+ std::shared_ptr<Player> playerCtr{nullptr};\r
+ std::map<std::string, std::string> header;\r
+ std::shared_ptr<Source> source{nullptr};\r
+ std::shared_ptr<CountDownRingPlayerListener> playerInterruptListener{nullptr};\r
+ AudioSession sessionId;\r
+ AudioInterrupt interrupt;\r
+ const char *RingMusicPath = "/user/music/alarm.mp3"; // 铃声路径\r
+\r
std::string countdownDuration{nullptr};\r
std::string RingTime{"00:00:00"}; // 响铃时间\r
std::string CountTime{"00:00:00"}; // 倒计时时间\r
* @Author: luozheng 1732036298@qq.com\r
* @Date: 2024-04-07 18:15:53\r
* @LastEditors: luozheng 1732036298@qq.com\r
- * @LastEditTime: 2024-04-08 20:43:16\r
+ * @LastEditTime: 2024-04-09 15:38:14\r
* @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/countdown/src/CountDownModel.cpp\r
*/\r
#include "countdown/include/CountDownModel.h"\r
return RingTime;\r
}\r
\r
+ /*\r
+ * @brief 初始化音乐播放器以播放一个指定的铃声文件\r
+ * @param {char*} RingMusicName 铃声文件\r
+ */\r
+ int CountDownModel::CountDownRingPlayerInit(const char *RingMusicName)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CountDownModel::CountDownRingPlayerInit");\r
+ /* ------------------------------- 1.播放文件路径设置 ------------------------------- */\r
+ uri = RingMusicName;\r
+ /* -------------------------------- 2.播放器对象创建 ------------------------------- */\r
+ if (playerCtr.get() == nullptr)\r
+ {\r
+ playerCtr = std::make_shared<Player>();\r
+ if (playerCtr.get() == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownModel] playerCtr new fail");\r
+ return OHOS_FAILURE;\r
+ }\r
+ }\r
+ /* ------------------------------- 3.播放器回调对象创建 ------------------------------ */\r
+ if (playerCallback.get() == nullptr)\r
+ {\r
+ playerCallback = std::make_shared<CountDownRingPlayerCallbackImpl>();\r
+ if (playerCallback.get() == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownModel] playerCallback new fail");\r
+ return OHOS_FAILURE;\r
+ }\r
+ }\r
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[CountDownModel] PlayerInit success!");\r
+ return OHOS_SUCCESS;\r
+ }\r
+\r
+ /*\r
+ * @brief 对铃声播放器进行设置并开始播放铃声。\r
+ */\r
+ int CountDownModel::InitializeAndPlayRingtone(void)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CountDownModel::InitializeAndPlayRingtone");\r
+ /* -------------------------------- 1.检查播放器实例 ------------------------------- */\r
+ int32_t ret;\r
+ int32_t state;\r
+ if (playerCtr.get() == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownModel] playerCtr.get() == nullptr");\r
+ return OHOS_FAILURE;\r
+ }\r
+ playerCtr->GetPlayerState(state);\r
+ /* -------------------------------- 2.设置播放器回调 ------------------------------- */\r
+ playerCtr->SetPlayerCallback(playerCallback);\r
+ /* -------------------------------- 3.创建并设置音频源 -------------------------------- */\r
+ source = std::make_shared<Source>(uri, header);\r
+ if (source.get() == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownModel] source.get() == fail");\r
+ return OHOS_FAILURE;\r
+ }\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownModel] Player url:%s", uri.c_str());\r
+ playerCtr->SetSource(*source);\r
+ /* --------------------------------- 4.配置播放器 -------------------------------- */\r
+ playerCtr->SetAudioStreamType(AUDIO_STREAM_MUSIC); // 设置播放器的音频流类型\r
+ playerCtr->Prepare(); // 准备播放器对象以播放音频。\r
+ /* -------------------------------- 5.请求音频焦点 -------------------------------- */\r
+ AudioManager &amIntance = AudioManager::GetInstance();\r
+ sessionId = amIntance.MakeSessionId();\r
+ if (sessionId == AUDIO_SESSION_ID_NONE)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownModel] sessionId invalid!!");\r
+ return OHOS_FAILURE;\r
+ }\r
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "[CountDownModel] MakeSessionId = %d", sessionId);\r
+ playerInterruptListener = std::make_shared<CountDownRingPlayerListener>(); // 创建音频中断监听器\r
+ if (playerInterruptListener.get() == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownModel] playerInterruptListener playerInterruptListener.get() == nullptr");\r
+ return OHOS_FAILURE;\r
+ }\r
+ playerInterruptListener->SetOwner(playerCtr);\r
+ interrupt = {AUDIO_STREAM_MUSIC, sessionId, playerInterruptListener};\r
+ // 激活音频中断 5s超时\r
+ if (amIntance.ActivateAudioInterrupt(interrupt) == INTERRUPT_FAILED)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ActivateAudioInterrupt faild");\r
+ return OHOS_FAILURE;\r
+ }\r
+ // playerCtr->SetVolume(50, 50); // 将左声道和右声道音量都设置为50\r
+ playerCtr->SetAudioSessionId(sessionId);\r
+ // 播放\r
+ playerCtr->Play();\r
+ return OHOS_SUCCESS;\r
+ }\r
+\r
+ /*\r
+ * @brief 开始铃声的播放\r
+ */\r
+ int CountDownModel::StartRingtonePlayback(void)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CountDownModel::StartRingtonePlayback");\r
+ if (CountDownRingPlayerInit(RingMusicPath) != OHOS_SUCCESS)\r
+ {\r
+ // 错误处理,例如记录日志或者返回错误状态码\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CountDownModel::CountDownRingPlayerInit error!!");\r
+ return OHOS_FAILURE;\r
+ }\r
+\r
+ if (InitializeAndPlayRingtone() != OHOS_SUCCESS)\r
+ {\r
+ // 错误处理,例如记录日志或者返回错误状态码\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CountDownModel::InitializeAndPlayRingtone error!!");\r
+ return OHOS_FAILURE;\r
+ }\r
+ return OHOS_SUCCESS;\r
+ }\r
+\r
+ /*\r
+ * @brief 停止播放铃声,重置并释放播放器资源,并去激活之前设置的音频中断。\r
+ */\r
+ int CountDownModel::StopRingtonePlaybackAndReleaseResources(void)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CountDownModel::StopRingtonePlaybackAndReleaseResources");\r
+ int32_t ret = 0;\r
+ int32_t state = 0;\r
+ AudioManager &amIntance = AudioManager::GetInstance();\r
+ if (playerCtr.get() == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownModel] playerCtr.get() == nullptr");\r
+ return OHOS_FAILURE;\r
+ }\r
+ playerCtr->GetPlayerState(state);\r
+ if (state == PlayerStates::PLAYER_STARTED || state == PlayerStates::PLAYER_PAUSED)\r
+ {\r
+ ret = playerCtr->Stop();\r
+ if (ret != 0)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownModel] Failed to stop the player");\r
+ return OHOS_FAILURE;\r
+ }\r
+ }\r
+ ret = playerCtr->Reset();\r
+ if (ret != 0)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownModel] Failed to reset the player");\r
+ return OHOS_FAILURE;\r
+ }\r
+ ret = playerCtr->Release();\r
+ playerCtr.reset();\r
+ if (ret != 0)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownModel] Failed to release the player");\r
+ return OHOS_FAILURE;\r
+ }\r
+ if (amIntance.DeactivateAudioInterrupt(interrupt) != 0)\r
+ {\r
+ return OHOS_FAILURE;\r
+ }\r
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Reset, ret:%d", ret);\r
+ return OHOS_SUCCESS;\r
+ }\r
+\r
+ int CountDownModel::ResetRingtonePlayback(void)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CountDownModel::ResetRingtonePlayback");\r
+ int32_t ret = 0;\r
+ int32_t state = 0;\r
+ if (playerCtr.get() == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownModel] playerCtr is null");\r
+ return OHOS_FAILURE;\r
+ }\r
+ playerCtr->GetPlayerState(state);\r
+ if (state == PlayerStates::PLAYER_STARTED || state == PlayerStates::PLAYER_PAUSED)\r
+ {\r
+ ret = playerCtr->Stop();\r
+ if (ret != 0)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownModel] Failed to stop the player");\r
+ return OHOS_FAILURE;\r
+ }\r
+ }\r
+ ret = playerCtr->Reset();\r
+ if (ret != 0)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownModel] Failed to reset the player");\r
+ return OHOS_FAILURE;\r
+ }\r
+ return OHOS_SUCCESS;\r
+ }\r
+\r
+ template <typename Func>\r
+ static void PostRingtoneEvent(Func function)\r
+ {\r
+ GraphicService::GetInstance()->PostGraphicEvent(\r
+ std::bind(function, CountDownModel::GetInstance()));\r
+ }\r
+\r
+ /*触发铃声的开始*/\r
+ void CountDownModel::RequestStartRingtone(void)\r
+ {\r
+ PostRingtoneEvent(&CountDownModel::StartRingtonePlayback);\r
+ }\r
+\r
+ /*触发铃声的停止*/\r
+ void CountDownModel::RequestStopRingtone(void)\r
+ {\r
+ PostRingtoneEvent(&CountDownModel::StopRingtonePlaybackAndReleaseResources);\r
+ }\r
+\r
/* ----------------------------------- 定时器 ---------------------------------- */\r
\r
/*\r
return;\r
}\r
\r
+ if (MainCountDownView::GetInstance()->GetStartCountDownView()->GetPlayOrPauseToggleButton() == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDown_TimerCallbackProc] GetPlayOrPauseToggleButton is NULL");\r
+ return;\r
+ }\r
+\r
if (CountDownModel::GetInstance()->DisplayCountDownDuration() == nullptr)\r
{\r
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDown_TimerCallbackProc] DisplayCountDownDuration is NULL");\r
// 检查倒计时是否结束\r
if (CountDownModel::g_CountDownTimes <= 0)\r
{\r
+ MainCountDownView::GetInstance()->GetStartCountDownView()->GetPlayOrPauseToggleButton()->SetState(false);\r
+ MainCountDownView::GetInstance()->GetStartCountDownView()->GetPlayOrPauseToggleButton()->SetTouchable(false);\r
CountDownModel::GetInstance()->CountDown_StopTimer(); // 停止定时器\r
MainCountDownView::GetInstance()->GetStartCountDownView()->GetShowCountDownTimelabel()->SetText("倒计时结束");\r
// 进行倒计时结束时的额外操作,比如播放声音、显示通知等\r
+ // CountDownModel::GetInstance()->StartRingtonePlayback();\r
+ CountDownModel::GetInstance()->RequestStartRingtone();\r
}\r
else\r
{\r
// 更新显示\r
MainCountDownView::GetInstance()->GetStartCountDownView()->GetShowCountDownTimelabel()->SetText(CountDownModel::GetInstance()->DisplayCountDownDuration());\r
}\r
+\r
+ return;\r
}\r
\r
/*\r
}\r
}\r
\r
+ /* ----------------------- CountDownRingPlayerListener ---------------------- */\r
+\r
+ void CountDownRingPlayerListener::SetOwner(std::shared_ptr<Player> player)\r
+ {\r
+ player_ = player;\r
+ }\r
+\r
+ /*重置标志位*/\r
+ void CountDownRingPlayerListener::RestFlag()\r
+ {\r
+ isPaused_ = false;\r
+ isDelayed_ = false;\r
+ isResumed_ = false;\r
+ isBeginStopped_ = false;\r
+ isEndStopped_ = false;\r
+ }\r
+\r
+ bool CountDownRingPlayerListener::IsPaused()\r
+ {\r
+ return isPaused_;\r
+ }\r
+\r
+ bool CountDownRingPlayerListener::IsDelayed()\r
+ {\r
+ return isDelayed_;\r
+ }\r
+\r
+ bool CountDownRingPlayerListener::IsResumed()\r
+ {\r
+ return isResumed_;\r
+ }\r
+\r
+ bool CountDownRingPlayerListener::IsBeginStopped()\r
+ {\r
+ return isBeginStopped_;\r
+ }\r
+\r
+ bool CountDownRingPlayerListener::IsEndStopped()\r
+ {\r
+ return isEndStopped_;\r
+ }\r
+\r
+ static void Start(void)\r
+ {\r
+ CountDownModel::GetInstance()->RequestStartRingtone();\r
+ }\r
+\r
+ static void Stop(void)\r
+ {\r
+ CountDownModel::GetInstance()->RequestStopRingtone();\r
+ }\r
+\r
+ /*开始计时器铃声播放*/\r
+ void CountDownRingPlayerListener::StartCountDownRing(void)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownRingPlayerListener::StartCountDownRing] start");\r
+ GraphicService::GetInstance()->PostGraphicEvent(Start);\r
+ }\r
+\r
+ /*停止计时器铃声播放*/\r
+ void CountDownRingPlayerListener::StopCountDownRing(void)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDownRingPlayerListener::StopCountDownRing] start");\r
+ GraphicService::GetInstance()->PostGraphicEvent(Stop);\r
+ }\r
+\r
+ /*响应外部的音频中断事件*/\r
+ void CountDownRingPlayerListener::OnInterrupt(int32_t type, int32_t hint)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OnInterrupt go in, type %d, hint %d.", type, hint);\r
+ if (type == INTERRUPT_TYPE_BEGIN && hint == INTERRUPT_HINT_PAUSE)\r
+ {\r
+ isDelayed_ = true;\r
+ }\r
+\r
+ if (type == INTERRUPT_TYPE_BEGIN && hint == INTERRUPT_HINT_STOP)\r
+ {\r
+ StopCountDownRing();\r
+ }\r
+ else if (type == INTERRUPT_TYPE_END && isDelayed_ == true)\r
+ {\r
+ // 重新开始计时器的铃声播放\r
+ StartCountDownRing();\r
+ isDelayed_ = false;\r
+ }\r
+ return;\r
+ }\r
+\r
+ /* --------------------- CountDownRingPlayerCallbackImpl -------------------- */\r
+ void CountDownRingPlayerCallbackImpl::OnPlaybackComplete(void)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OnPlaybackComplete");\r
+ CountDownModel::GetInstance()->RequestStopRingtone();\r
+ CountDownModel::GetInstance()->RequestStartRingtone();\r
+ }\r
+\r
+ void CountDownRingPlayerCallbackImpl::OnError(int32_t errorType, int32_t errorCode)\r
+ {\r
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OnError test, errorType %d, errorCode %d", errorType, errorCode);\r
+ // 此处实现代码处理错误事件\r
+ }\r
+\r
+ void CountDownRingPlayerCallbackImpl::OnInfo(int type, int extra)\r
+ {\r
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OnInfo test, type %d, extra %d.", type, extra);\r
+ // 此处实现代码处理普通事件\r
+ }\r
+\r
+ void CountDownRingPlayerCallbackImpl::OnRewindToComplete(void)\r
+ {\r
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "OnRewindToComplete test");\r
+ // 此处实现代码处理进度控制完成的事件\r
+ }\r
}\r