From b5ffaef548e849472ea890946f507054d36a2a63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=9B=BD=E5=BB=BA?= Date: Wed, 26 Sep 2018 11:29:40 +0800 Subject: [PATCH] update the ihw player from R16 --- package/netease/ihw_player/src/ihwplayer.c | 23 +- .../netease/ihw_player/src/include/readCmd.h | 2 +- .../ihw_player/src/libplayer/audioplayer.cpp | 49 ++-- .../src/libplayer/include/musicplayer.h | 2 +- .../src/libplayer/include/playerapi.h | 3 +- .../ihw_player/src/libplayer/musicplayer.cpp | 52 ++-- .../ihw_player/src/libplayer/playerapi.cpp | 232 ++++++++++-------- 7 files changed, 214 insertions(+), 149 deletions(-) diff --git a/package/netease/ihw_player/src/ihwplayer.c b/package/netease/ihw_player/src/ihwplayer.c index d16f2c271..ffc9b9a27 100755 --- a/package/netease/ihw_player/src/ihwplayer.c +++ b/package/netease/ihw_player/src/ihwplayer.c @@ -32,6 +32,8 @@ #endif #define CUR_POS_MSG_TIME 3000 +#define POS_NO_CHANGE_TIMEOUT 6000 //6秒如果还没有更新pos就认为网络有问题,直接停止 + /* * 是否允许terminal控制播放模块,仅测试用 */ @@ -78,6 +80,8 @@ static unsigned long lastCmdTime = 0; // 毫秒 static unsigned int maxLastTime = 0, minLastTime = 0xffffffff; +static void playerCallbackHandler(uint32 playerId, PlayerStatus st, char *musicUuid, int musicUuidLen); + inline static unsigned long getTime(){ struct timeval tv; gettimeofday(&tv,NULL); @@ -524,8 +528,9 @@ static void DBusSendPlayerSt(PlayerStatusOut playerSt){ return; } memset(player_to_ctrl, 0, sizeof(PLAYER_TO_CTRL)); - if(NULL != playerSt.musicUuid){ + if(NULL != playerSt.musicUuid && (strlen(playerSt.musicUuid) < MAX_MUSIC_UUID)){ memcpy(player_to_ctrl->musicUuid, playerSt.musicUuid, strlen(playerSt.musicUuid) + 1); + *(player_to_ctrl->musicUuid + strlen(playerSt.musicUuid)) = 0; } player_to_ctrl->plySt = playerSt.playerStatus; @@ -567,6 +572,8 @@ static void DBusSendPlayerSt(PlayerStatusOut playerSt){ RETURNED VALUES: void *****************************************************************************/ static void curPosMsgCallBack(uv_timer_t *handle){ + static int timeoutForPosNotchange = 0; + static int lastPeriodTime = CUR_POS_MSG_TIME; if(MUSIC_ST_PLAYING == playerStatusOut.playerStatus){ static int pos = -1; if (AirPlayerId == playerStatusOut.playerId){ @@ -579,13 +586,23 @@ static void curPosMsgCallBack(uv_timer_t *handle){ if(pos != playerStatusOut.curPostionOfMs){ DBusSendPlayerSt(playerStatusOut); pos = playerStatusOut.curPostionOfMs; + timeoutForPosNotchange = 0; } else if(playerStatusOut.durationOfMs - playerStatusOut.curPostionOfMs < 1000){ playerStatusOut.curPostionOfMs = playerStatusOut.durationOfMs; DBusSendPlayerSt(playerStatusOut); pos = playerStatusOut.curPostionOfMs; + timeoutForPosNotchange = 0; }else{ LOG_EX(LOG_Warn, "curPos is not change, pos:%d duration:%d\n", pos, playerStatusOut.durationOfMs); + timeoutForPosNotchange += lastPeriodTime; + if(timeoutForPosNotchange >= POS_NO_CHANGE_TIMEOUT){ + timeoutForPosNotchange = 0; + PlayerCtrlParamsIn playerCtrlParamsIn = {playerStatusOut.playerId, NULL, playerStatusOut.musicUuid, -1, MUSIC_MODE_MAX, MAX_MUSIC_LIST, (char)-1}; + LOG_EX(LOG_Error, "music play timeout, cur pos:%d duration:%d\n", pos, playerStatusOut.durationOfMs); + cmdProcess(CMD_PLAY_STOP, playerCtrlParamsIn); + playerCallbackHandler(playerStatusOut.playerId, MUSIC_ST_ERR_PREPARING_TIMEOUT, playerStatusOut.musicUuid, strlen(playerStatusOut.musicUuid) + 1); + } } uv_timer_stop(&timerCurPosMsg); @@ -598,6 +615,8 @@ static void curPosMsgCallBack(uv_timer_t *handle){ { periodTime = 1000;//min(1000, playerStatusOut.durationOfMs - playerStatusOut.curPostionOfMs); } + + lastPeriodTime = periodTime; uv_timer_start(&timerCurPosMsg, curPosMsgCallBack, periodTime, 0); } } @@ -643,6 +662,7 @@ static void playerCallbackHandler(uint32 playerId, PlayerStatus st, char *musicU playerStatusTmp.musicUuid = (char *)malloc(sizeof(char) * musicUuidLen); if(NULL != playerStatusTmp.musicUuid){ memcpy(playerStatusTmp.musicUuid, musicUuid, musicUuidLen); + *(playerStatusTmp.musicUuid + musicUuidLen -1) = 0; } } @@ -737,6 +757,7 @@ int main(int argv, char** argc){ LOG_EX(LOG_Warn, "cjson.\n"); #endif + SetHBLAutoExit(TRUE); playerInit(playerCallbackHandler); SEPlayerCbRegister(sePlayerStateNotify); diff --git a/package/netease/ihw_player/src/include/readCmd.h b/package/netease/ihw_player/src/include/readCmd.h index 5abafbbd1..4493a5e1a 100755 --- a/package/netease/ihw_player/src/include/readCmd.h +++ b/package/netease/ihw_player/src/include/readCmd.h @@ -26,7 +26,7 @@ typedef struct Command static const Command commands[] = { {"help", PLAYER_CMD_HELP, "show this help message."}, - {"mode change", CMD_PLAY_MODECHANGE, "change the mode,0: list cycle, 1: signal cycle, for example: mode change: 0"}, + {"mode change", CMD_PLAY_MODECHANGE, "change the mode,0: list cycle, 1: single cycle, for example: mode change: 0"}, {"play", CMD_PLAY_PLAY, "start playback."}, {"playurl", MUSIC_CMD_PLAY_URL, "prepare url, playurl:$(url)."}, {"pause", CMD_PLAY_PAUSE, "pause the playback."}, diff --git a/package/netease/ihw_player/src/libplayer/audioplayer.cpp b/package/netease/ihw_player/src/libplayer/audioplayer.cpp index cddd76c8c..da64d5bc5 100755 --- a/package/netease/ihw_player/src/libplayer/audioplayer.cpp +++ b/package/netease/ihw_player/src/libplayer/audioplayer.cpp @@ -65,8 +65,6 @@ static bool needWaitMain = true; static pthread_mutex_t mutexStop = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t condStop = PTHREAD_COND_INITIALIZER; volatile static bool needWaitStop = true; -//播放器是否需要reset标志,tinaplay出现error的时候需要reset -volatile static bool needResetTinaplay = FALSE; #if TTS_TEXT_ROKID #define ERR_NIL_ID -1 @@ -111,6 +109,9 @@ AudioPlayer mAudioPlayer; #define PREPARING_TTS_TIMEOUT 5000 //tts缓存超时时间:5s static uv_timer_t timerPrepareTts; +static bool isTimerPrepareTts = false; +static uv_loop_t * pLoop; + /************** tts *******************/ /* @@ -492,13 +493,13 @@ nil_tts_play: RETURNED VALUES: bool *****************************************************************************/ static bool setAudioPlayerReset(){ + LOG_EX(LOG_Debug, "TinyPlayer reset start...\n"); if(mAudioPlayer.nTinaplayer->reset() != 0){ LOG_EX(LOG_Error, "TinyPlayer reset error\n"); notifyCallback(nonMusicPlayerId, AUDIO_ST_ERR); return false; } - needResetTinaplay = FALSE; LOG_EX(LOG_Debug, "TinyPlayer reset successfull\n"); return true; @@ -514,8 +515,8 @@ static bool setAudioPlayerReset(){ RETURNED VALUES: void *****************************************************************************/ static void timerCallBack(uv_timer_t *handle){ - LOG_EX(LOG_Debug, "timeout when tts preparing.\n"); - + LOG_EX(LOG_Warn, "timeout when tts preparing.\n"); + isTimerPrepareTts = true; setAudioPlayerReset(); } @@ -531,6 +532,7 @@ static void timerCallBack(uv_timer_t *handle){ RETURNED VALUES: bool *****************************************************************************/ static bool setAudioPlayerUrlSource(char* pUrl){ + LOG_EX(LOG_Debug, "setAudioPlayerUrlSource start....\n"); if(!setAudioPlayerReset()){ return false; } @@ -541,13 +543,15 @@ static bool setAudioPlayerUrlSource(char* pUrl){ return false; } + isTimerPrepareTts = false; + uv_update_time(pLoop); + uv_timer_start(&timerPrepareTts, timerCallBack, (PREPARING_TTS_TIMEOUT), 0); if(mAudioPlayer.nTinaplayer->prepareAsync() != 0){ + uv_timer_stop(&timerPrepareTts); LOG_EX(LOG_Error, "prepareAsync err, exit\n"); notifyCallback(nonMusicPlayerId, AUDIO_ST_ERR); return false; } - - uv_timer_start(&timerPrepareTts, timerCallBack, (PREPARING_TTS_TIMEOUT), 0); LOG_EX(LOG_Debug, "url:%s\n", pUrl); return true; @@ -623,6 +627,7 @@ int audio_play(char *source, char type) static void audio_stop() { + LOG_EX(LOG_Debug, "audio_stop to setAudioPlayerReset....\n"); switch (curSourceType){ case AUDIO_TYPE_URL: if(setAudioPlayerReset()){ @@ -715,11 +720,6 @@ static void audioPlayerPlayThreadFun(void){ needWaitPlay = true; pthread_mutex_unlock(&mutexPlay); - if(needResetTinaplay == true){ - setAudioPlayerReset(); - continue; - } - LOG_EX(LOG_Debug, "Begin to play audio>>>>>>>>>>>>\n"); if (AUDIO_ST_PREPARED == mAudioPlayer.nStatus){ @@ -811,23 +811,21 @@ static int callbackForTinaPlayer(void* pUserData, int msg, int param0, void* par case TPLAYER_NOTIFY_MEDIA_ERROR: { PlayerStatus audioSt; - if(param0 == NOTIFY_ERROR_TYPE_IO) + + uv_timer_stop(&timerPrepareTts); + if(param0 == NOTIFY_ERROR_TYPE_IO || isTimerPrepareTts) { + isTimerPrepareTts = false; audioSt = AUDIO_ST_ERR; LOG_EX(LOG_Error, "TINA_NOTIFY_ERROR, net is disconnect!\n"); }else{ audioSt = AUDIO_ST_INTERRUPT; LOG_EX(LOG_Error, "TINA_NOTIFY_ERROR, maybe interrupt by cc, errCode:0x%x\n", param0); } - pthread_mutex_lock(&mutexPlay); - needResetTinaplay = true; - needWaitPlay = false; - pthread_cond_signal(&condPlay); - pthread_mutex_unlock(&mutexPlay); + #if LOCK_ENABLE pthread_mutex_lock(&mAudioPlayer->nMutex); #endif - uv_timer_stop(&timerPrepareTts); mAudioPlayer->nStatus = AUDIO_ST_IDLE; #if LOCK_ENABLE pthread_mutex_unlock(&mAudioPlayer->nMutex); @@ -984,7 +982,8 @@ bool audioPlayerInit(AudioPlayerCallback callback){ } #endif - uv_timer_init(uv_default_loop(), &timerPrepareTts); + pLoop = uv_default_loop(); + uv_timer_init(pLoop, &timerPrepareTts); LOG_EX(LOG_Debug, "audioPlayerCreate successfully.\n"); return true; @@ -1013,10 +1012,6 @@ ErrRet: RETURNED VALUES: bool *****************************************************************************/ bool audioPlayerControl(uint32 playerId, uint32 cmd, char *source, int sourceLen, char audioPlayerSourceType){ - if(needResetTinaplay == true){ - setAudioPlayerReset(); - } - if(CMD_PLAY_AUDIO_PLAY == cmd){ nonMusicPlayerId = playerId; LOG_EX(LOG_Debug, "CMD_PLAY_AUDIO_PLAY, trig main thread. sourceLen:%d\n", sourceLen); @@ -1045,8 +1040,12 @@ bool audioPlayerControl(uint32 playerId, uint32 cmd, char *source, int sourceLen // 如果是停止命令,直接调用stop,不要去触发主线程 audio_stop(); + }else if(audioPlayerSourceType == AUDIO_STOP_MIX_TYPE){ + LOG_EX(LOG_Warn, "Cmd: 0x%x(700:Stop), stop tts when mix mode!\n", cmd); + setAudioPlayerReset(); }else{ - LOG_EX(LOG_Warn, "Cmd: 0x%x(700:Stop), but new tts run already, so do nothing!\n", cmd); + LOG_EX(LOG_Warn, "Cmd: 0x%x(700:Stop), new tts run already, reset old one!\n", cmd); + setAudioPlayerReset(); } return true; } diff --git a/package/netease/ihw_player/src/libplayer/include/musicplayer.h b/package/netease/ihw_player/src/libplayer/include/musicplayer.h index e784cc728..c0a80e61c 100755 --- a/package/netease/ihw_player/src/libplayer/include/musicplayer.h +++ b/package/netease/ihw_player/src/libplayer/include/musicplayer.h @@ -35,7 +35,7 @@ using namespace aw; -#define THREADHOLD_PREPARE_NEXT 5000 // 5 s +#define THREADHOLD_PREPARE_NEXT 15000 // 15 s /* prepared 后开始播放以及 completed之后播放下一首,不再在musicplayer中控制,而是通过player统一控制 */ #define CUT_MAINTHREAD diff --git a/package/netease/ihw_player/src/libplayer/include/playerapi.h b/package/netease/ihw_player/src/libplayer/include/playerapi.h index 4f19059df..18c424191 100755 --- a/package/netease/ihw_player/src/libplayer/include/playerapi.h +++ b/package/netease/ihw_player/src/libplayer/include/playerapi.h @@ -80,7 +80,7 @@ typedef enum{ typedef enum { MUSIC_LIST_CYCLE = 0x01, - MUSIC_SIGNAL_CYCLE, + MUSIC_SINGLE_CYCLE, MUSIC_MODE_MAX, }PlayMode; @@ -244,6 +244,7 @@ typedef enum { // audioplayer中,无需判断参数,直接停止 #define AUDIO_STOP_REPLAY_MUSIC 0x30 #define AUDIO_STOP_NOT_REPLAY_MUSIC 0X31 +#define AUDIO_STOP_MIX_TYPE 0X32 // 混音播放的时候,stop命令用,内部type #define AUDIO_NULL_TYPE 0XFF diff --git a/package/netease/ihw_player/src/libplayer/musicplayer.cpp b/package/netease/ihw_player/src/libplayer/musicplayer.cpp index 61615318b..98ec67cff 100755 --- a/package/netease/ihw_player/src/libplayer/musicplayer.cpp +++ b/package/netease/ihw_player/src/libplayer/musicplayer.cpp @@ -45,7 +45,6 @@ typedef struct { bool nSeekable; u8 nError; pthread_mutex_t nMutex[MUSIC_TINA_PALYER_NUM]; - bool needResetTinaplay[MUSIC_TINA_PALYER_NUM];//播放器是否需要reset标志,tinaplay出现error的时候需要reset }MusicPlayer; static bool musicPlayerLoop = false; @@ -141,6 +140,8 @@ inline static bool needPrepareNext(int curPos, int duration){ RETURNED VALUES: bool *****************************************************************************/ static bool setMusicPlayerUrlSource(char* pUrl, bool curMusic){ + LOG_EX(LOG_Warn, "setMusicPlayerUrlSource start... curMusic:%d.\n" ,curMusic); + MusicPlayerIndex musicPlayerIndex; if(curMusic){ lastHasEndWhenForNext = true; @@ -164,7 +165,6 @@ static bool setMusicPlayerUrlSource(char* pUrl, bool curMusic){ return false; } - musicplayer.needResetTinaplay[musicPlayerIndex] = false; musicplayer.nSeekable = true; notifyCallback(musicPlayerId, MUSIC_ST_PREPARING); @@ -206,6 +206,7 @@ static bool setMusicPlayerUrlSource(char* pUrl, bool curMusic){ *****************************************************************************/ static bool setMusicPlayerStart() { + LOG_EX(LOG_Warn, "setMusicPlayerStart.....PlayerIndex=%d\n", musicplayer.nPlayerIndex); if(musicplayer.nStatus[musicplayer.nPlayerIndex] != MUSIC_ST_PREPARED && musicplayer.nStatus[musicplayer.nPlayerIndex] != MUSIC_ST_SEEKING && musicplayer.nStatus[musicplayer.nPlayerIndex] != MUSIC_ST_PAUSED && @@ -354,12 +355,14 @@ static bool setMusicPlayerReset(MusicPlayerIndex num){ return false; } - musicplayer.needResetTinaplay[num] = false; + LOG_EX(LOG_Debug, "TinyPlayer Music(index=%d) reset end\n", num); + pthread_mutex_lock(&musicplayer.nMutex[num]); isMusicPlayerPlaying = false; musicplayer.nStatus[num] = MUSIC_ST_IDLE; pthread_mutex_unlock(&musicplayer.nMutex[num]); - + + LOG_EX(LOG_Debug, "TinyPlayer Music reset successfull\n"); notifyCallback(musicPlayerId, MUSIC_ST_IDLE); return true; } @@ -485,6 +488,11 @@ static void threadChangeVol(void){ struct timeval timeOut; u8 cnt = 0; do{ + if(musicplayer.nStatus[musicplayer.nPlayerIndex] != MUSIC_ST_PLAYING){ + volBegin = volOriginal; + LOG_EX(LOG_Debug, "music not playing, so vol restore to (%d)\n", volBegin); + break; + } timeOut.tv_sec = 0; timeOut.tv_usec = VOL_TIMER_PERIOD; select(0, NULL, NULL, NULL, &timeOut); @@ -583,17 +591,21 @@ static int callbackForTinaPlayer(void* pUserData, int msg, int param0, void* par //case TINA_NOTIFY_ERROR: case TPLAYER_NOTIFY_MEDIA_ERROR: { - for(int i = 0; i < MUSIC_TINA_PALYER_NUM ; i++){ - pthread_mutex_lock(&pMusicPlayer->nMutex[i]); - pMusicPlayer->nStatus[i] = MUSIC_ST_IDLE; - pMusicPlayer->nPreStatus[i] = MUSIC_ST_IDLE; - pMusicPlayer->needResetTinaplay[i] = true; - pthread_mutex_unlock(&pMusicPlayer->nMutex[i]); - } - notifyCallback(musicPlayerId, PLAYER_ERR_TINA_NOTIFY); - - LOG_EX(LOG_Error, "TINA_NOTIFY_ERROR, errCode:0x%x\n", param0); - break; + if(param0 == NOTIFY_ERROR_TYPE_IO) + { + //网络出错情况 + for(int i = 0; i < MUSIC_TINA_PALYER_NUM ; i++){ + pthread_mutex_lock(&pMusicPlayer->nMutex[i]); + pMusicPlayer->nStatus[i] = MUSIC_ST_IDLE; + pMusicPlayer->nPreStatus[i] = MUSIC_ST_IDLE; + pthread_mutex_unlock(&pMusicPlayer->nMutex[i]); + } + notifyCallback(musicPlayerId, PLAYER_ERR_TINA_NOTIFY); + LOG_EX(LOG_Error, "TINA_NOTIFY_ERROR, net is disconnect!\n"); + }else{ + LOG_EX(LOG_Error, "TINA_NOTIFY_ERROR, maybe cancel by ihwplayer perpare timeout, errCode:0x%x\n", param0); + } + break; } //case TINA_NOTIFY_PREPARED: @@ -768,8 +780,6 @@ bool musicPlayerInit(MusicPlayerCallback callback){ //musicplayer.nTinaplayer[1] = new TinaPlayer(); musicplayer.nTinaplayer[0] = new LuPlayer(); musicplayer.nTinaplayer[1] = new LuPlayer(); - musicplayer.needResetTinaplay[0] = false; - musicplayer.needResetTinaplay[1] = false; musicPlayerInited = true; @@ -848,13 +858,8 @@ bool musicPlayerControl(MusicCtrlParams params){ musicPlayerLoop = params.loop; - for(int i = 0; i < MUSIC_TINA_PALYER_NUM ; i++){ - if(musicplayer.needResetTinaplay[i]){ - setMusicPlayerReset((MusicPlayerIndex)i); - } - } - LOG_EX(LOG_Debug, "cmd:0x%x loop:%d ignorePause:%d playerId:%d\n",params.cmdCtrl, params.loop, params.ignorePause, params.playerId); + LOG_EX(LOG_Debug, "cmd:0x%x loop:%d ignorePause:%d playerId:%d, index=%d\n",params.cmdCtrl, params.loop, params.ignorePause, params.playerId,musicplayer.nPlayerIndex); bool forcePlayWhenSeek = false; switch(params.cmdCtrl){ @@ -919,6 +924,7 @@ bool musicPlayerControl(MusicCtrlParams params){ setMusicPlayerPause(); break; case CMD_PLAY_STOP: + LOG_EX(LOG_Debug, "TinyPlayer Music CMD_PLAY_STOP... playerIndex=%d\n", musicplayer.nPlayerIndex); // 目前播放器没有暂停的逻辑,直接reset掉 setMusicPlayerReset(musicplayer.nPlayerIndex); break; diff --git a/package/netease/ihw_player/src/libplayer/playerapi.cpp b/package/netease/ihw_player/src/libplayer/playerapi.cpp index 2b04318a1..3be218a96 100755 --- a/package/netease/ihw_player/src/libplayer/playerapi.cpp +++ b/package/netease/ihw_player/src/libplayer/playerapi.cpp @@ -23,8 +23,10 @@ #include "background.h" #define UV_TIMER 0 // 0:没有使用uv的定时器,因为歌曲播报时,会wait住线程,导致定时器失效 -#define PREPARING_TIMEOUT THREADHOLD_PREPARE_NEXT +#define PREPARING_TIMEOUT 5000 //5s +#define PREPARING_NEXT_TIMEOUT THREADHOLD_PREPARE_NEXT #define TIMER_UINT 1 +#define PREPARING_TIMEOUT_PLUS 2000 //2s, 如果tts播放完成后,混音音乐还没有结束,再多缓存2s #ifdef CALLBACK_MSG IhwPlayerCallback playerCallback; @@ -45,6 +47,13 @@ volatile static bool audioPlayerRunning = false; // 是否有非音乐类音频 volatile bool ignoreRAudioPlayerRunning = false; // 是否忽略修改audioPlayerRunning的状态 volatile static bool pauseWhenPreparing = false; // 在preparing时是否有过暂停动作 +typedef enum{ + NULL_WHEN_PAUSE = 0, + PREPARING_WHEN_PAUSE, //正在缓存 + PREPARED_WHEN_PAUSE, //缓存完成 +}StatusWhenPause; +volatile static StatusWhenPause musicStWhenPause = NULL_WHEN_PAUSE; // 在暂停过程music的状态 + static bool replayMusicWhenStopAudio = true; // tts结束时是否唤醒音乐播放 static bool ttsTrigByPlayerInner = false; // 判断播放的tts是否是播放器自动触发,如果是,不回调消息给控制中心 @@ -58,12 +67,6 @@ volatile static PlayMode playMode = MUSIC_LIST_CYCLE; static MusicListType curMusicListType = NORMAL_MUSIC_LIST; static uint32 musicPlayerId = 1, nonMusicPlayerId = 0, sePlayerId = 0, bgPlayerId = 0; -/* 如果先调用了music,但是此时music状态没有返回,又调用了audio播放,有混音的bug - * fix方案:如果调用了music接口,且未返回时,当再次调用audio,此时等待music接口返回在往下走 - */ -volatile static bool hasCallMusicFunc = false; -static pthread_mutex_t mutexWaitMusicFuncCb = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t condWaitMusicFuncCb = PTHREAD_COND_INITIALIZER; bool ignoreMusicPause = false; static pthread_t threadCallBack; @@ -74,6 +77,7 @@ static pthread_cond_t condTimer = PTHREAD_COND_INITIALIZER; static bool needWaitTimer = true; volatile static bool cancleTimer; volatile static int timerOut; +volatile static int prepareTimecnt = 0; static uv_timer_t timerPreparing; static bool musicPreparingTimeoutForTtsMix = false; //播放混音时当音乐缓存失败,取消tts播放 @@ -91,6 +95,12 @@ static PlayerCtrlParamsIn prepareTtsParams = { .source = NULL, }; +static PlayerCtrlParamsIn MixTtsParams = { + .playerId = 1, + .source = NULL, +}; + + /***************************************************************************** FUNCTION NAME: clearPrepareTts @@ -290,22 +300,31 @@ static void playerStatusChangedHandler(uint32 playerId, PlayerStatus status, cha RETURNED VALUES: void *****************************************************************************/ static void timerCallBack(uv_timer_t *handle){ - LOG_EX(LOG_Debug, "timeout when preparing.\n"); + MusicCtrlParams musicParams; + + LOG_EX(LOG_Warn, "timeout when music preparing.\n"); musicPreparingTimeoutForTtsMix = true; pauseWhenPreparing = true; + musicStWhenPause = NULL_WHEN_PAUSE; musicPlayerStatus = MUSIC_ST_IDLE; - - pthread_mutex_lock(&mutexWaitMusicFuncCb); - hasCallMusicFunc = false; - pthread_cond_signal(&condWaitMusicFuncCb); - pthread_mutex_unlock(&mutexWaitMusicFuncCb); + ttsTrigByPlayerInner = false; preparedNextSt = PREPARE_NEXT_INIT; + + musicParams.playerId = musicPlayerId; + backGroundPlayerControl(bgPlayerId, BG_CMD_STOP, NULL, false); + musicParams.cmdCtrl = CMD_PLAY_STOP; + musicPlayerControl(musicParams); clearPrepareTts(); - playerStatusChangedHandler(musicPlayerId, MUSIC_ST_ERR_PREPARING_TIMEOUT, NULL, NULL); + if(NULL == urlArrayInfo[0].at(urlIndex).musicUuid){ + playerStatusChangedHandler(musicPlayerId, MUSIC_ST_ERR_PREPARING_TIMEOUT, NULL, NULL); + } else { + playerStatusChangedHandler(musicPlayerId, MUSIC_ST_ERR_PREPARING_TIMEOUT, urlArrayInfo[0].at(urlIndex).musicUuid, \ + strlen(urlArrayInfo[0].at(urlIndex).musicUuid) + 1); + } } /***************************************************************************** @@ -327,13 +346,25 @@ static void threadPrepareTimerFunc(void){ needWaitTimer = true; pthread_mutex_unlock(&mutexTimer); - int cnt = 0; + prepareTimecnt = 0; do { usleep(TIMER_UINT*1000); // 1ms - if(!cancleTimer && timerOut == ++cnt){ - timerCallBack(NULL); + if(!cancleTimer && timerOut <= ++prepareTimecnt){ + if(ttsTrigByPlayerInner && audioPlayerStatus == AUDIO_ST_START){ + //混音播放的时候,tts没有播放完成,music延长缓存时间 + timerOut += PREPARING_TIMEOUT; + LOG_EX(LOG_Debug, "<<>>\n", timerOut); + } else { + cancleTimer = true; + timerCallBack(NULL); + break; + } + } + if(prepareTimecnt%1000 == 0){ + LOG_EX(LOG_Debug, "wait for prepare timer=%d\n", prepareTimecnt); } } while(!cancleTimer); + LOG_EX(LOG_Warn, "wait for prepare total timer=%d\n", prepareTimecnt); } } @@ -363,6 +394,7 @@ static void playerCallBackThread(){ while(true){ pthread_mutex_lock(&mutexMain); while(needWaitMain){ + LOG_EX(LOG_Debug, "needWaitMain: pthread_cond_wait condMain\n"); pthread_cond_wait(&condMain,&mutexMain); } needWaitMain = true; @@ -402,9 +434,13 @@ static void playerCallBackThread(){ if (!ttsTrigByPlayerInner) { playerStatusChangedHandler(nonMusicPlayerId, audioPlayerStatus, NULL, NULL); } else { - LOG_EX(LOG_Debug, "ttsTrigByPlayerInner(%d) ignore up tts status(0x%x).\n", - ttsTrigByPlayerInner, - audioPlayerStatus); + params.volRestoreTime = MixTtsParams.volRestoreTime; + params.volBegin = MixTtsParams.volBegin; + params.cmdCtrl = CMD_PLAY_VOL_SET; + musicPlayerControl(params); + + LOG_EX(LOG_Debug, "ttsTrigByPlayerInner(%d) ignore up tts status(0x%x). preparing Time: %d ms, music timeout: %d ms\n", + ttsTrigByPlayerInner, audioPlayerStatus, prepareTimecnt, timerOut); } LOG_EX(LOG_Debug, "AUDIO_ST_START(0x%x)\n", AUDIO_ST_START); @@ -424,9 +460,12 @@ static void playerCallBackThread(){ if (!ttsTrigByPlayerInner) { playerStatusChangedHandler(nonMusicPlayerId, audioPlayerStatus, NULL, NULL); } else { - LOG_EX(LOG_Debug, "ttsTrigByPlayerInner(%d) ignore up tts status(0x%x).\n", - ttsTrigByPlayerInner, - audioPlayerStatus); + if((audioPlayerStatus == AUDIO_ST_FINISH) + && ((prepareTimecnt > PREPARING_TIMEOUT) || ((timerOut - prepareTimecnt) < PREPARING_TIMEOUT_PLUS))){ + timerOut = prepareTimecnt + PREPARING_TIMEOUT_PLUS; + } + LOG_EX(LOG_Debug, "ttsTrigByPlayerInner(%d) ignore up tts status(0x%x). preparing Time: %d ms, music timeout: %d ms\n", + ttsTrigByPlayerInner, audioPlayerStatus, prepareTimecnt, timerOut); ttsTrigByPlayerInner = false; } @@ -447,8 +486,19 @@ static void playerCallBackThread(){ LOG_EX(LOG_Warn, "ignore replay music when audio stop.\n"); break; } - + + LOG_EX(LOG_Warn, "isMusicPlayerBeInterrupted:%d, musicPlayerStatus:%d.\n", isMusicPlayerBeInterrupted, musicPlayerStatus); if(isMusicPlayerBeInterrupted){ + if(PREPARED_WHEN_PAUSE == musicStWhenPause){ + LOG_EX(LOG_Debug, "MUSIC_ST_PREPARED, wait for cc music play cmd...\n"); + musicPlayerStatus = MUSIC_ST_PREPARED; + break; + } else if(PREPARING_WHEN_PAUSE == musicStWhenPause){ + LOG_EX(LOG_Debug, "MUSIC_ST_PREPARING, replay the music, reset timeout:%d ms\n", PREPARING_TIMEOUT); + musicPlayerStatus = MUSIC_ST_PREPARING; + startTimer(PREPARING_TIMEOUT); + } + switch(musicPlayerStatus){ #ifdef CUT_MAINTHREAD case MUSIC_ST_PREPARED: @@ -501,6 +551,7 @@ static void playerCallBackThread(){ default: // not audioplayer status switch(musicPlayerStatus){ case MUSIC_ST_PLAYING: + musicStWhenPause = NULL_WHEN_PAUSE; if(NULL == urlArrayInfo[0].at(urlIndex).musicUuid){ playerStatusChangedHandler(musicPlayerId, MUSIC_ST_PLAYING, NULL, NULL); } else { @@ -512,13 +563,9 @@ static void playerCallBackThread(){ if(pauseWhenPreparing){ pauseWhenPreparing = false; - musicPlayerStatus = MUSIC_ST_IDLE; - - pthread_mutex_lock(&mutexWaitMusicFuncCb); - hasCallMusicFunc = false; - pthread_cond_signal(&condWaitMusicFuncCb); - pthread_mutex_unlock(&mutexWaitMusicFuncCb); - + musicPlayerStatus = MUSIC_ST_PREPARED; + musicStWhenPause = PREPARED_WHEN_PAUSE; + LOG_EX(LOG_Debug, "clear pauseWhenPreparing and do nothing.\n"); } else { if(NULL == urlArrayInfo[0].at(urlIndex).musicUuid){ @@ -528,19 +575,20 @@ static void playerCallBackThread(){ strlen(urlArrayInfo[0].at(urlIndex).musicUuid) + 1); } #ifdef CUT_MAINTHREAD - if(!audioPlayerRunning){ + if(!audioPlayerRunning || ttsTrigByPlayerInner){ //如果tts有内容,就开始混音缓存播放 if(NULL != prepareTtsParams.source){ + LOG_EX(LOG_Debug, "mix tts play.\n"); playerControl(CMD_PLAY_AUDIO_PLAY, prepareTtsParams); clearPrepareTts(); } - + + //ttsTrigByPlayerInner为true混音播放,也同时开始播放音乐 params.cmdCtrl = CMD_PLAY_PLAY; params.loop = musicLoop; params.gain = gainArr.at(0); musicPlayerControl(params); - } - else{ + } else { isMusicPlayerBeInterrupted = true; } #endif @@ -643,11 +691,13 @@ static void musicCallback(uint32 playerId, PlayerStatus msg){ return; } - if(hasCallMusicFunc && (MUSIC_ST_PLAYING == msg || MUSIC_ST_SEEKING == msg || PLAYER_ERR_TINA_NOTIFY == msg)){ - pthread_mutex_lock(&mutexWaitMusicFuncCb); - hasCallMusicFunc = false; - pthread_cond_signal(&condWaitMusicFuncCb); - pthread_mutex_unlock(&mutexWaitMusicFuncCb); + if(PLAYER_ERR_TINA_NOTIFY == msg){ +#if UV_TIMER + uv_timer_stop(&timerPreparing); +#else + stopTimer(); +#endif + musicStWhenPause = NULL_WHEN_PAUSE; } if (MUSIC_ST_PAUSED == msg && (preparedNextSt == PREPARE_NEXT_OK || preparedNextSt == PREPARE_NEXT_BEGIN)){ @@ -664,11 +714,11 @@ static void musicCallback(uint32 playerId, PlayerStatus msg){ if(prepareNext){ prepareNext = false; #if UV_TIMER - uv_timer_start(&timerPreparing, timerCallBack, (PREPARING_TIMEOUT), 0); - LOG_EX(LOG_Debug, "set uv timer for preparing(prepareNext)...%d\n", (PREPARING_TIMEOUT)); + uv_timer_start(&timerPreparing, timerCallBack, (PREPARING_NEXT_TIMEOUT), 0); + LOG_EX(LOG_Debug, "set uv timer for preparing(prepareNext)...%d\n", (PREPARING_NEXT_TIMEOUT)); #else - startTimer(PREPARING_TIMEOUT); - LOG_EX(LOG_Debug, "set pthread timer for preparing(prepareNext)...%d\n", (PREPARING_TIMEOUT)); + startTimer(PREPARING_NEXT_TIMEOUT); + LOG_EX(LOG_Debug, "set pthread timer for preparing(prepareNext)...%d\n", (PREPARING_NEXT_TIMEOUT)); #endif } else{ #if UV_TIMER @@ -833,7 +883,7 @@ static bool playerInitInter(void){ BGPlayerStatus = BG_ST_IDLE; urlArrayInfoReset(); - if(playMode == MUSIC_SIGNAL_CYCLE){ + if(playMode == MUSIC_SINGLE_CYCLE){ musicLoop = true; } else{ @@ -940,7 +990,7 @@ bool playerControl(uint32 cmd, PlayerCtrlParamsIn params){ && pauseWhenPreparing){ pauseWhenPreparing = false; LOG_EX(LOG_Debug, "pause when preparing:%d.\n",musicPlayerStatus); - break; + //break; } else{ pauseWhenPreparing = false; } @@ -960,7 +1010,19 @@ bool playerControl(uint32 cmd, PlayerCtrlParamsIn params){ playerStatusChangedHandler(params.playerId, PLAYER_ERR_SOURCE_NULL, NULL, NULL); return false; } - LOG_EX(LOG_Debug, "control want to replay the music.\n"); + LOG_EX(LOG_Debug, "control want to replay the music, musicPlayerStatus =%d, musicStWhenPause=%d\n", musicPlayerStatus, musicStWhenPause); + if(PREPARED_WHEN_PAUSE == musicStWhenPause){ + LOG_EX(LOG_Debug, "MUSIC_ST_PREPARED, replay the music...\n"); + musicParams.cmdCtrl = CMD_PLAY_PLAY; + musicParams.loop = musicLoop; + musicParams.gain = gainArr.at(0); + musicPlayerControl(musicParams); + break; + } else if(PREPARING_WHEN_PAUSE == musicStWhenPause){ + LOG_EX(LOG_Debug, "MUSIC_ST_PREPARING, replay the music, reset timeout:%d ms\n", PREPARING_TIMEOUT_PLUS); + startTimer(PREPARING_TIMEOUT_PLUS); + break; + } } else{ preparedNextSt = PREPARE_NEXT_INIT; @@ -971,6 +1033,7 @@ bool playerControl(uint32 cmd, PlayerCtrlParamsIn params){ gainArr.at(0) = params.gain; pauseWhenPreparing = false; + musicStWhenPause = NULL_WHEN_PAUSE; /* 播放传入的url,如果当前正在播放,替换 */ ignoreMusicPause = true; // url 和 id 需要同时存在 @@ -987,9 +1050,6 @@ bool playerControl(uint32 cmd, PlayerCtrlParamsIn params){ } if(!audioPlayerRunning){ - pthread_mutex_lock(&mutexWaitMusicFuncCb); - hasCallMusicFunc = true; - pthread_mutex_unlock(&mutexWaitMusicFuncCb); prepareNext = false; musicParams.cmdCtrl = CMD_PLAY_PLAY; musicParams.url = urlArrayInfo[0].at(urlIndex).musicUrl; @@ -1063,9 +1123,16 @@ bool playerControl(uint32 cmd, PlayerCtrlParamsIn params){ LOG_EX(LOG_Debug, "clear isMusicPlayerBeInterrupted becauseof pause.\n"); break; } - if(hasCallMusicFunc || - (preparedNextSt != PREPARE_NEXT_BEGIN && preparedNextSt != PREPARE_NEXT_OK && - (MUSIC_ST_PREPARING == musicPlayerStatus || MUSIC_ST_PREPARED == musicPlayerStatus))){ + if(preparedNextSt != PREPARE_NEXT_BEGIN && preparedNextSt != PREPARE_NEXT_OK && + (MUSIC_ST_PREPARING == musicPlayerStatus || MUSIC_ST_PREPARED == musicPlayerStatus)){ + if(MUSIC_ST_PREPARING == musicPlayerStatus){ + musicStWhenPause = PREPARING_WHEN_PAUSE; +#if UV_TIMER + uv_timer_stop(&timerPreparing); +#else + stopTimer(); +#endif + } pauseWhenPreparing = true; LOG_EX(LOG_Debug, "pause when preparing:%d.\n",musicPlayerStatus); musicCallback(params.playerId, MUSIC_ST_PAUSED); @@ -1076,7 +1143,12 @@ bool playerControl(uint32 cmd, PlayerCtrlParamsIn params){ musicPlayerControl(musicParams); if (audioPlayerRunning){ - audioPlayerControl(nonMusicPlayerId, CMD_PLAY_AUDIO_STOP, NULL, NULL, NULL); + if(ttsTrigByPlayerInner){ + //混音播放需要将tts停止 + audioPlayerControl(nonMusicPlayerId, CMD_PLAY_AUDIO_STOP, NULL, NULL, AUDIO_STOP_MIX_TYPE); + }else{ + audioPlayerControl(nonMusicPlayerId, CMD_PLAY_AUDIO_STOP, NULL, NULL, NULL); + } } break; case CMD_PLAY_STOP: @@ -1113,21 +1185,6 @@ bool playerControl(uint32 cmd, PlayerCtrlParamsIn params){ params.audioSourceType = AUDIO_TYPE_URL; LOG_EX(LOG_Warn, "not need replay music when stop.\n"); } - /* 如果调用了music接口,但是没有返回,等在这里 */ - if(AUDIO_TYPE_TEXT_MIX == params.audioSourceType || AUDIO_TYPE_URL_MIX == params.audioSourceType){ - pthread_mutex_lock(&mutexWaitMusicFuncCb); - while(hasCallMusicFunc){ - LOG_EX(LOG_Debug, "mix tts wait for music play.\n"); - pthread_cond_wait(&condWaitMusicFuncCb,&mutexWaitMusicFuncCb); - } - pthread_mutex_unlock(&mutexWaitMusicFuncCb); - - if(musicPreparingTimeoutForTtsMix){ - LOG_EX(LOG_Debug, "give up tts because of timeout.\n"); - musicPreparingTimeoutForTtsMix = false; - break; - } - } LOG_EX(LOG_Debug, "audioPlayerRunning: %d ttsTrigByPlayer:%d.\n", audioPlayerRunning, ttsTrigByPlayerInner); if(!audioPlayerRunning){ @@ -1143,16 +1200,7 @@ bool playerControl(uint32 cmd, PlayerCtrlParamsIn params){ #endif isMusicPlayerBeInterrupted = true; if(MUSIC_ST_PLAYING == musicPlayerStatus || MUSIC_ST_PREPARED == musicPlayerStatus || \ - MUSIC_ST_PREPARING == musicPlayerStatus || MUSIC_ST_FOR_NEXT == musicPlayerStatus){ - /* 如果当前是prepare或者prepared状态,暂停会没法执行,因此等play状态 */ - //if (MUSIC_ST_PREPARED == musicPlayerStatus || MUSIC_ST_PREPARING == musicPlayerStatus){ - // pthread_mutex_lock(&mutexWaitMusicFuncCb); - // hasCallMusicFunc = true; - // pthread_cond_wait(&condWaitMusicFuncCb,&mutexWaitMusicFuncCb); - // pthread_mutex_unlock(&mutexWaitMusicFuncCb); - //} - - //musicPlayerControl(musicPlayerId, CMD_PLAY_PAUSE, NULL, NULL, NULL, NULL, NULL, NULL); + MUSIC_ST_PREPARING == musicPlayerStatus || MUSIC_ST_FOR_NEXT == musicPlayerStatus){ musicParams.cmdCtrl = CMD_PLAY_PAUSE; musicParams.playerId = musicPlayerId; musicPlayerControl(musicParams); @@ -1165,19 +1213,13 @@ bool playerControl(uint32 cmd, PlayerCtrlParamsIn params){ } } else if (AUDIO_TYPE_TEXT_MIX == params.audioSourceType){ params.audioSourceType = AUDIO_TYPE_TEXT; - - //musicPlayerControl(params.playerId, CMD_PLAY_VOL_SET, NULL, NULL, NULL, NULL, params.volRestoreTime, params.volBegin); - musicParams.cmdCtrl = CMD_PLAY_VOL_SET; - musicParams.playerId = musicPlayerId; - musicPlayerControl(musicParams); + MixTtsParams.volBegin = params.volBegin; + MixTtsParams.volRestoreTime = params.volRestoreTime; LOG_EX(LOG_Debug, "mix with music.\n"); } else if (AUDIO_TYPE_URL_MIX == params.audioSourceType){ params.audioSourceType = AUDIO_TYPE_URL; - - //musicPlayerControl(params.playerId, CMD_PLAY_VOL_SET, NULL, NULL, NULL, NULL, params.volRestoreTime, params.volBegin); - musicParams.cmdCtrl = CMD_PLAY_VOL_SET; - musicParams.playerId = musicPlayerId; - musicPlayerControl(musicParams); + MixTtsParams.volBegin = params.volBegin; + MixTtsParams.volRestoreTime = params.volRestoreTime; LOG_EX(LOG_Debug, "mix with music.\n"); } audioPlayerRunning = true; @@ -1195,17 +1237,13 @@ bool playerControl(uint32 cmd, PlayerCtrlParamsIn params){ if (AUDIO_TYPE_TEXT_MIX == params.audioSourceType){ params.audioSourceType = AUDIO_TYPE_TEXT; - - musicParams.cmdCtrl = CMD_PLAY_VOL_SET; - musicParams.playerId = musicPlayerId; - musicPlayerControl(musicParams); + MixTtsParams.volBegin = params.volBegin; + MixTtsParams.volRestoreTime = params.volRestoreTime; LOG_EX(LOG_Debug, "mix with music.\n"); } else if (AUDIO_TYPE_URL_MIX == params.audioSourceType){ params.audioSourceType = AUDIO_TYPE_URL; - - musicParams.cmdCtrl = CMD_PLAY_VOL_SET; - musicParams.playerId = musicPlayerId; - musicPlayerControl(musicParams); + MixTtsParams.volBegin = params.volBegin; + MixTtsParams.volRestoreTime = params.volRestoreTime; LOG_EX(LOG_Debug, "mix with music.\n"); }