bool PcmAudioPlayer::prepare(const std::string &url, const PcmData &decResult) { _url = url; _decResult = decResult; _track = new (std::nothrow) Track(_decResult); _track->onStateChanged = [this](Track::State state) { if (state == Track::State::OVER) { if (_playEventCallback != nullptr) { _playEventCallback(State::OVER); } } else if (state == Track::State::STOPPED) { if (_playEventCallback != nullptr) { _playEventCallback(State::STOPPED); } } else if (state == Track::State::DESTROYED) { delete this; } }; setVolume(1.0f); return true; }
bool PcmAudioPlayer::prepare(const std::string &url, const PcmData &decResult) { _url = url; _decResult = decResult; _track = new (std::nothrow) Track(_decResult); std::thread::id callerThreadId = _callerThreadUtils->getCallerThreadId(); _track->onStateChanged = [this, callerThreadId](Track::State state) { // It maybe in sub thread auto func = [this, state](){ // It's in caller's thread if (state == Track::State::OVER) { if (_playEventCallback != nullptr) { _playEventCallback(State::OVER); } } else if (state == Track::State::STOPPED) { if (_playEventCallback != nullptr) { _playEventCallback(State::STOPPED); } } else if (state == Track::State::DESTROYED) { delete this; } }; if (callerThreadId == std::this_thread::get_id()) { func(); } else { _callerThreadUtils->performFunctionInCallerThread(func); } }; setVolume(1.0f); return true; }
void UrlAudioPlayer::playEventCallback(SLPlayItf caller, SLuint32 playEvent) { // Note that it's on sub thread, please don't invoke OpenSLES API on sub thread if (playEvent == SL_PLAYEVENT_HEADATEND) { std::shared_ptr<bool> isDestroyed = _isDestroyed; auto func = [this, isDestroyed](){ // If it was destroyed, just return. if (*isDestroyed) { ALOGV("The UrlAudioPlayer (%p) was destroyed!", this); return; } //Note that It's in the caller's thread (Cocos Thread) // If state is already stopped, ignore the play over event. if (_state == State::STOPPED) { return; } //fix issue#8965:AudioEngine can't looping audio on Android 2.3.x if (isLoop()) { play(); } else { setState(State::OVER); if (_playEventCallback != nullptr) { _playEventCallback(State::OVER); } ALOGV("UrlAudioPlayer (%p) played over, destroy self ...", this); destroy(); delete this; } }; if (_callerThreadId == std::this_thread::get_id()) { func(); } else { _callerThreadUtils->performFunctionInCallerThread(func); } } }
void UrlAudioPlayer::stop() { ALOGV("UrlAudioPlayer::stop (%p, %d)", this, getId()); SLresult r = (*_playItf)->SetPlayState(_playItf, SL_PLAYSTATE_STOPPED); SL_RETURN_IF_FAILED(r, "UrlAudioPlayer::stop failed"); if (_state == State::PLAYING || _state == State::PAUSED) { setLoop(false); setState(State::STOPPED); if (_playEventCallback != nullptr) { _playEventCallback(State::STOPPED); } destroy(); delete this; } else { ALOGW("UrlAudioPlayer (%p, state:%d) isn't playing or paused, could not invoke stop!", this, static_cast<int>(_state)); } }