diff --git a/frameworks/js/avplayer/avplayer_callback.cpp b/frameworks/js/avplayer/avplayer_callback.cpp index 45440b3005e273ac6de1dcf8fcc283786c432902..ce086a36cc81613e6636ca3af474f8803f9e5f4b 100644 --- a/frameworks/js/avplayer/avplayer_callback.cpp +++ b/frameworks/js/avplayer/avplayer_callback.cpp @@ -726,6 +726,8 @@ void AVPlayerCallback::InitInfoFuncsPart2() { onInfoFuncs_[INFO_TYPE_SUPER_RESOLUTION_CHANGED] = [this](const int32_t extra, const Format &infoBody) { OnSuperResolutionChangedCb(extra, infoBody); }; + onInfoFuncs_[INFO_TYPE_RATEDONE] = + [this](const int32_t extra, const Format &infoBody) { OnPlaybackRateDoneCb(extra, infoBody); }; } void AVPlayerCallback::OnAudioDeviceChangeCb(const int32_t extra, const Format &infoBody) @@ -952,6 +954,27 @@ void AVPlayerCallback::OnSpeedDoneCb(const int32_t extra, const Format &infoBody NapiCallback::CompleteCallback(env_, cb); } +void AVPlayerCallback::OnPlaybackRateDoneCb(const int32_t extra, const Format &infoBody) +{ + (void)infoBody; + CHECK_AND_RETURN_LOG(isloaded_.load(), "current source is unready"); + float speedRate = 0.0f; + (void)infoBody.GetFloatValue(PlayerKeys::PLAYER_PLAYBACK_RATE, speedRate); + MEDIA_LOGI("OnPlaybackRateDoneCb is called, speedRate: %{public}f", speedRate); + if (refMap_.find(AVPlayerEvent::EVENT_RATE_DONE) == refMap_.end()) { + MEDIA_LOGW("can not find ratedone callback!"); + return; + } + + NapiCallback::Double *cb = new(std::nothrow) NapiCallback::Double(); + CHECK_AND_RETURN_LOG(cb != nullptr, "failed to new float"); + + cb->callback = refMap_.at(AVPlayerEvent::EVENT_RATE_DONE); + cb->callbackName = AVPlayerEvent::EVENT_RATE_DONE; + cb->value = static_cast(speedRate); + NapiCallback::CompleteCallback(env_, cb); +} + void AVPlayerCallback::OnBitRateDoneCb(const int32_t extra, const Format &infoBody) { (void)infoBody; diff --git a/frameworks/js/avplayer/avplayer_callback.h b/frameworks/js/avplayer/avplayer_callback.h index 5bedb4795f3672a903dfd1dbd568b1315d24211b..3c49fdf2dac03f5cf709a960322c48e6ac7f35d7 100644 --- a/frameworks/js/avplayer/avplayer_callback.h +++ b/frameworks/js/avplayer/avplayer_callback.h @@ -62,6 +62,7 @@ private: void OnVolumeChangeCb(const int32_t extra, const Format &infoBody); void OnSeekDoneCb(const int32_t extra, const Format &infoBody); void OnSpeedDoneCb(const int32_t extra, const Format &infoBody); + void OnPlaybackRateDoneCb(const int32_t extra, const Format &infoBody); void OnBitRateDoneCb(const int32_t extra, const Format &infoBody); void OnPositionUpdateCb(const int32_t extra, const Format &infoBody); void OnDurationUpdateCb(const int32_t extra, const Format &infoBody); diff --git a/frameworks/js/avplayer/avplayer_napi.cpp b/frameworks/js/avplayer/avplayer_napi.cpp index 20bfe3bb50b9ef4e75bc305f733f10a6e9ce4fb7..f7f83166cc30bf8667409b3cc7752b6ee5b34c08 100644 --- a/frameworks/js/avplayer/avplayer_napi.cpp +++ b/frameworks/js/avplayer/avplayer_napi.cpp @@ -98,6 +98,7 @@ napi_value AVPlayerNapi::Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("off", JsClearOnCallback), DECLARE_NAPI_FUNCTION("setVolume", JsSetVolume), DECLARE_NAPI_FUNCTION("setSpeed", JsSetSpeed), + DECLARE_NAPI_FUNCTION("setPlaybackRate", JsSetPlaybackRate), DECLARE_NAPI_FUNCTION("setMediaSource", JsSetMediaSource), DECLARE_NAPI_FUNCTION("setBitrate", JsSelectBitrate), DECLARE_NAPI_FUNCTION("getTrackDescription", JsGetTrackDescription), @@ -957,6 +958,58 @@ napi_value AVPlayerNapi::JsSetSpeed(napi_env env, napi_callback_info info) return result; } +napi_value AVPlayerNapi::JsSetPlaybackRate(napi_env env, napi_callback_info info) +{ + MediaTrace trace("AVPlayerNapi::setRate"); + napi_value result = nullptr; + napi_get_undefined(env, &result); + MEDIA_LOGI("JsSetRate In"); + + napi_value args[1] = { nullptr }; + size_t argCount = 1; + AVPlayerNapi *jsPlayer = AVPlayerNapi::GetJsInstanceWithParameter(env, info, argCount, args); + CHECK_AND_RETURN_RET_LOG(jsPlayer != nullptr, result, "failed to GetJsInstanceWithParameter"); + + if (jsPlayer->IsLiveSource()) { + jsPlayer->OnErrorCb(MSERR_EXT_API9_OPERATE_NOT_PERMIT, "The stream is live stream, not support speed"); + return result; + } + + napi_valuetype valueType = napi_undefined; + if (argCount < 1 || napi_typeof(env, args[0], &valueType) != napi_ok || valueType != napi_number) { + jsPlayer->OnErrorCb(MSERR_EXT_API20_PARAM_ERROR_OUT_OF_RANGE, "speed rate is not number"); + return result; + } + + double rate = 1.0f; + const double minRate = 0.125f; + const double maxRate = 4.0f; + napi_status status = napi_get_value_double(env, args[0], &rate); + if (status != napi_ok || rate < minRate || rate > maxRate) { + jsPlayer->OnErrorCb(MSERR_EXT_API20_PARAM_ERROR_OUT_OF_RANGE, + "invalid parameters, please check the speed rate"); + return result; + } + + if (!jsPlayer->IsControllable()) { + jsPlayer->OnErrorCb(MSERR_EXT_API9_OPERATE_NOT_PERMIT, + "current state is not prepared/playing/paused/completed, unsupport speed operation"); + return result; + } + + auto task = std::make_shared>([jsPlayer, rate]() { + MEDIA_LOGI("0x%{public}06" PRIXPTR " Speed Task In", FAKE_POINTER(jsPlayer)); + if (jsPlayer->player_ != nullptr) { + (void)jsPlayer->player_->SetPlaybackRate(static_cast(rate)); + } + MEDIA_LOGI("0x%{public}06" PRIXPTR " Speed Task Out", FAKE_POINTER(jsPlayer)); + }); + MEDIA_LOGI("0x%{public}06" PRIXPTR " JsSetSpeed EnqueueTask In", FAKE_POINTER(jsPlayer)); + (void)jsPlayer->taskQue_->EnqueueTask(task); + MEDIA_LOGI("0x%{public}06" PRIXPTR " JsSetSpeed Out", FAKE_POINTER(jsPlayer)); + return result; +} + napi_value AVPlayerNapi::JsSetVolume(napi_env env, napi_callback_info info) { MediaTrace trace("AVPlayerNapi::setVolume"); diff --git a/frameworks/js/avplayer/avplayer_napi.h b/frameworks/js/avplayer/avplayer_napi.h index 6c9a42aa8f1b4bde5637c8f85f41bc793933b444..67c13f9e6d6e2ee5fb545f27d5021f2726b6ee71 100644 --- a/frameworks/js/avplayer/avplayer_napi.h +++ b/frameworks/js/avplayer/avplayer_napi.h @@ -48,6 +48,7 @@ const std::string EVENT_VOLUME_CHANGE = "volumeChange"; const std::string EVENT_END_OF_STREAM = "endOfStream"; const std::string EVENT_SEEK_DONE = "seekDone"; const std::string EVENT_SPEED_DONE = "speedDone"; +const std::string EVENT_RATE_DONE = "playbackRateDone"; const std::string EVENT_BITRATE_DONE = "bitrateDone"; const std::string EVENT_TIME_UPDATE = "timeUpdate"; const std::string EVENT_DURATION_UPDATE = "durationUpdate"; @@ -125,6 +126,10 @@ private: * setSpeed(speed: number): void */ static napi_value JsSetSpeed(napi_env env, napi_callback_info info); + /** + * setPlaybackRate(rate: float): void + */ + static napi_value JsSetPlaybackRate(napi_env env, napi_callback_info info); /** * setVolume(vol: number): void */ diff --git a/frameworks/native/capi/player/native_avplayer.cpp b/frameworks/native/capi/player/native_avplayer.cpp index 6efd9bcfb9301a1897528f6af22f6d837fe91b48..c306eced3cded99668c8e442bc3bb862fbe12221 100644 --- a/frameworks/native/capi/player/native_avplayer.cpp +++ b/frameworks/native/capi/player/native_avplayer.cpp @@ -30,6 +30,7 @@ namespace { constexpr uint32_t STATE_MAP_LENGTH = 9; constexpr uint32_t INFO_TYPE_LENGTH = 19; constexpr int32_t UNSUPPORT_FORMAT_ERROR_CODE = 331350544; + constexpr int32_t RATE_UNSUPPORT_STATE_ERROR_CODE = 331350048; constexpr int32_t AVPLAYER_ERR_UNSUPPORT = 9; } @@ -41,6 +42,7 @@ const char* OH_PLAYER_MESSAGE_TYPE = PlayerKeys::PLAYER_MESSAGE_TYPE.data(); const char* OH_PLAYER_IS_LIVE_STREAM = PlayerKeys::PLAYER_IS_LIVE_STREAM.data(); const char* OH_PLAYER_SEEK_POSITION = PlayerKeys::PLAYER_SEEK_POSITION.data(); const char* OH_PLAYER_PLAYBACK_SPEED = PlayerKeys::PLAYER_PLAYBACK_SPEED.data(); +const char* OH_PLAYER_PLAYBACK_RATE = PlayerKeys::PLAYER_PLAYBACK_RATE.data(); const char* OH_PLAYER_BITRATE = PlayerKeys::PLAYER_BITRATE_DONE.data(); const char* OH_PLAYER_CURRENT_POSITION = PlayerKeys::PLAYER_CURRENT_POSITION.data(); const char* OH_PLAYER_DURATION = PlayerKeys::PLAYER_DURATION.data(); @@ -118,6 +120,7 @@ static const StateConvert STATE_MAP[STATE_MAP_LENGTH] = { static const PlayerOnInfoTypeConvert ON_INFO_TYPE[INFO_TYPE_LENGTH] = { { INFO_TYPE_SEEKDONE, AV_INFO_TYPE_SEEKDONE }, { INFO_TYPE_SPEEDDONE, AV_INFO_TYPE_SPEEDDONE }, + { INFO_TYPE_RATEDONE, AV_INFO_TYPE_PLAYBACK_RATE_DONE }, { INFO_TYPE_BITRATEDONE, AV_INFO_TYPE_BITRATEDONE }, { INFO_TYPE_EOS, AV_INFO_TYPE_EOS }, { INFO_TYPE_STATE_CHANGE, AV_INFO_TYPE_STATE_CHANGE }, @@ -235,6 +238,7 @@ public: private: void OnSeekDoneCb(const int32_t extra, const Format &infoBody); void OnSpeedDoneCb(const int32_t extra, const Format &infoBody); + void OnPlaybackRateDoneCb(const int32_t extra, const Format &infoBody); void OnBitRateDoneCb(const int32_t extra, const Format &infoBody); void OnEosCb(const int32_t extra, const Format &infoBody); void OnStateChangeCb(const int32_t extra, const Format &infoBody); @@ -288,6 +292,8 @@ NativeAVPlayerCallback::NativeAVPlayerCallback(OH_AVPlayer *player, AVPlayerCall [this](const int32_t extra, const Format &infoBody) { OnSeekDoneCb(extra, infoBody); } }, { INFO_TYPE_SPEEDDONE, [this](const int32_t extra, const Format &infoBody) { OnSpeedDoneCb(extra, infoBody); } }, + { INFO_TYPE_RATEDONE, + [this](const int32_t extra, const Format &infoBody) { OnPlaybackRateDoneCb(extra, infoBody); } }, { INFO_TYPE_BITRATEDONE, [this](const int32_t extra, const Format &infoBody) { OnBitRateDoneCb(extra, infoBody); } }, { INFO_TYPE_EOS, @@ -525,6 +531,21 @@ void NativeAVPlayerCallback::OnSpeedDoneCb(const int32_t extra, const Format &in infoCallback_->OnInfo(player_, AV_INFO_TYPE_SPEEDDONE, reinterpret_cast(avFormat.GetRefPtr())); } +void NativeAVPlayerCallback::OnPlaybackRateDoneCb(const int32_t extra, const Format &infoBody) +{ + (void)infoBody; + CHECK_AND_RETURN_LOG(isSourceLoaded_.load(), "OnPlaybackRateDoneCb current source is unready"); + float rate = 0.0f; + (void)infoBody.GetFloatValue(PlayerKeys::PLAYER_PLAYBACK_RATE, rate); + MEDIA_LOGI("RateDone %{public}f", rate); + + OHOS::sptr avFormat = new (std::nothrow) OH_AVFormat(); + CHECK_AND_RETURN_LOG(avFormat != nullptr, "OnPlaybackRateDoneCb OH_AVFormat create failed"); + avFormat->format_.PutFloatValue(OH_PLAYER_PLAYBACK_RATE, rate); + infoCallback_->OnInfo(player_, AV_INFO_TYPE_PLAYBACK_RATE_DONE, + reinterpret_cast(avFormat.GetRefPtr())); +} + void NativeAVPlayerCallback::OnBitRateDoneCb(const int32_t extra, const Format &infoBody) { (void)infoBody; @@ -1041,6 +1062,24 @@ OH_AVErrCode OH_AVPlayer_SetPlaybackSpeed(OH_AVPlayer *player, AVPlaybackSpeed s return AV_ERR_OK; } +OH_AVErrCode OH_AVPlayer_SetPlaybackRate(OH_AVPlayer *player, float rate) +{ + CHECK_AND_RETURN_RET_LOG(player != nullptr, AV_ERR_INVALID_VAL, "input player is nullptr!"); + struct PlayerObject *playerObj = reinterpret_cast(player); + CHECK_AND_RETURN_RET_LOG(playerObj->player_ != nullptr, AV_ERR_INVALID_VAL, "player_ is null"); + const double minRate = 0.125f; + const double maxRate = 4.0f; + CHECK_AND_RETURN_RET_LOG(rate < minRate || rate > maxRate, AV_ERR_INVALID_VAL, + "invalid parameters, please check the speed rate"); + int32_t ret = playerObj->player_->SetPlaybackRate(rate); + if (ret == MSERR_INVALID_VAL) { + return AV_ERR_INVALID_VAL; + } else if (ret == RATE_UNSUPPORT_STATE_ERROR_CODE) { + return AV_ERR_OPERATE_NOT_PERMIT; + } + return AV_ERR_OK; +} + OH_AVErrCode OH_AVPlayer_GetPlaybackSpeed(OH_AVPlayer *player, AVPlaybackSpeed *speed) { CHECK_AND_RETURN_RET_LOG(player != nullptr, AV_ERR_INVALID_VAL, "input player is nullptr!"); diff --git a/frameworks/native/player/player_impl.cpp b/frameworks/native/player/player_impl.cpp index f64d81df45984184077dca3538560a0de56bd3e0..ab10b766a344161275328c6bfa198e0edfbfadf5 100644 --- a/frameworks/native/player/player_impl.cpp +++ b/frameworks/native/player/player_impl.cpp @@ -365,6 +365,18 @@ int32_t PlayerImpl::SetPlaybackSpeed(PlaybackRateMode mode) return playerService_->SetPlaybackSpeed(mode); } +int32_t PlayerImpl::SetPlaybackRate(float rate) +{ + MEDIA_LOGD("PlayerImpl:0x%{public}06" PRIXPTR " SetPlaybackRate in, mode is %{public}f", FAKE_POINTER(this), rate); + CHECK_AND_RETURN_RET_LOG(playerService_ != nullptr, MSERR_SERVICE_DIED, "player service does not exist.."); + double minRate = 0.125f; + double maxRate = 4.0f; + if (rate < minRate || rate > maxRate) { + return MSERR_INVALID_VAL; + } + return playerService_->SetPlaybackRate(rate); +} + int32_t PlayerImpl::SetMediaSource(const std::shared_ptr &mediaSource, AVPlayStrategy strategy) { MEDIA_LOGD("PlayerImpl:0x%{public}06" PRIXPTR " SetMediaSource in(dataSrc)", FAKE_POINTER(this)); diff --git a/frameworks/native/player/player_impl.h b/frameworks/native/player/player_impl.h index 4ac477fbe4377c447a4e5b0f5af621122a4cb3e1..58fe4eb84b43567f72dbbf2bcf861f7776d1c35b 100644 --- a/frameworks/native/player/player_impl.h +++ b/frameworks/native/player/player_impl.h @@ -58,6 +58,7 @@ public: int32_t GetSubtitleTrackInfo(std::vector &subtitleTrack) override; int32_t GetVideoHeight() override; int32_t SetPlaybackSpeed(PlaybackRateMode mode) override; + int32_t SetPlaybackRate(float rate) override; int32_t GetDuration(int32_t &duration) override; int32_t GetApiVersion(int32_t &apiVersion) override; int32_t GetPlaybackSpeed(PlaybackRateMode &mode) override; diff --git a/interfaces/inner_api/native/player.h b/interfaces/inner_api/native/player.h index 9ba4c351cf6ad4951aa41eebdf4fc445462f626f..09fc7d935ce81c2c70d81bf9bc3ab2f15abee0a7 100644 --- a/interfaces/inner_api/native/player.h +++ b/interfaces/inner_api/native/player.h @@ -117,6 +117,7 @@ public: static constexpr std::string_view PLAYER_IS_LIVE_STREAM = "is_live_stream"; static constexpr std::string_view PLAYER_SEEK_POSITION = "seek_done"; static constexpr std::string_view PLAYER_PLAYBACK_SPEED = "speed_done"; + static constexpr std::string_view PLAYER_PLAYBACK_RATE = "rate_done"; static constexpr std::string_view PLAYER_BITRATE_DONE = "bitrate_done"; static constexpr std::string_view PLAYER_CURRENT_POSITION = "current_position"; static constexpr std::string_view PLAYER_DURATION = "duration"; @@ -217,6 +218,8 @@ enum PlayerOnInfoType : int32_t { INFO_TYPE_SEEKDONE = 1, /* return the message when speeding done. */ INFO_TYPE_SPEEDDONE, + /* return the message when speeding done. */ + INFO_TYPE_RATEDONE, /* return the message when select bitrate done */ INFO_TYPE_BITRATEDONE, /* return the message when playback is end of steam. */ @@ -620,6 +623,17 @@ public: */ virtual int32_t SetPlaybackSpeed(PlaybackRateMode mode) = 0; + /** + * @brief set the player playback rate + * + * @param rate the rate {@link PlaybackRateMode} which can set. + * @return Returns {@link MSERR_OK} if the playback rate is set successful; returns an error code defined + * in {@link media_errors.h} otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual int32_t SetPlaybackRate(float rate) = 0; + /** * @brief get the current player playback rate * diff --git a/interfaces/kits/c/avplayer.h b/interfaces/kits/c/avplayer.h index 78fdea8259d9ca6f6232f55b182bac9b06fec78e..121c27559a472320124030a55987f11297cc085a 100644 --- a/interfaces/kits/c/avplayer.h +++ b/interfaces/kits/c/avplayer.h @@ -271,6 +271,20 @@ OH_AVErrCode OH_AVPlayer_GetVideoHeight(OH_AVPlayer *player, int32_t *videoHeigh */ OH_AVErrCode OH_AVPlayer_SetPlaybackSpeed(OH_AVPlayer *player, AVPlaybackSpeed speed); +/** + * @brief Sets playback parameters. + * Supported states: prepared/playing/paused/completed. + * @syscap SystemCapability.Multimedia.Media.AVPlayer + * @param player Pointer to OH_AVPlayer instance + * @param rate Playback rate + * @return OH_AVErrCode Operation result code + * {@link AV_ERR_OK} if the execution is successful. + * {@link AV_ERR_OPERATE_NOT_PERMIT} if called in unsupported state or during live streaming. + * {@link AV_ERR_INVALID_VAL} if input player or params is nullptr, or parameter is out of range. + * @since 20 + */ +OH_AVErrCode OH_AVPlayer_SetPlaybackRate(OH_AVPlayer *player, float rate); + /** * @brief get the current player playback rate * @syscap SystemCapability.Multimedia.Media.AVPlayer diff --git a/interfaces/kits/c/avplayer_base.h b/interfaces/kits/c/avplayer_base.h index 2c64e3be730f14898a66c4244fc024b66bee0a96..c57791e44c8b051ea1c31a815f8135f50773111e 100644 --- a/interfaces/kits/c/avplayer_base.h +++ b/interfaces/kits/c/avplayer_base.h @@ -209,6 +209,8 @@ typedef enum AVPlayerOnInfoType { * {@link OH_AVPlayerOnInfo} is the same as {@OH_AudioStream_DeviceChangeReason} in audio framework. */ AV_INFO_TYPE_AUDIO_OUTPUT_DEVICE_CHANGE = 17, + /* Event type indicating playback rate configuration completed. */ + AV_INFO_TYPE_PLAYBACK_RATE_DONE = 18, } AVPlayerOnInfoType; /** diff --git a/services/engine/histreamer/player/hiplayer_impl.cpp b/services/engine/histreamer/player/hiplayer_impl.cpp index fd6e48129aadc7659c02b46cfe6e954c0d6ef165..6c835c18483b9c3c2b9a82d3773adec9382cd9f8 100644 --- a/services/engine/histreamer/player/hiplayer_impl.cpp +++ b/services/engine/histreamer/player/hiplayer_impl.cpp @@ -1754,6 +1754,39 @@ int32_t HiPlayerImpl::SetPlaybackSpeed(PlaybackRateMode mode) return MSERR_OK; } +int32_t HiPlayerImpl::SetPlaybackRate(float rate) +{ + MEDIA_LOG_I("SetPlaybackRate %{public}f", rate); + Status res = Status::OK; + if (audioSink_ != nullptr) { + res = audioSink_->SetSpeed(rate); + } + if (subtitleSink_ != nullptr) { + res = subtitleSink_->SetSpeed(rate); + } + if (res != Status::OK) { + MEDIA_LOG_E("SetPlaybackRate audioSink set speed error"); + return MSERR_UNKNOWN; + } + if (syncManager_ != nullptr) { + res = syncManager_->SetPlaybackRate(rate); + } + if (res != Status::OK) { + MEDIA_LOG_E("SetPlaybackRate syncManager set audio speed error"); + return MSERR_UNKNOWN; + } + if (demuxer_ != nullptr) { + demuxer_->SetSpeed(rate); + } + int32_t extra = 0; + playbackRate_ = rate; + Format format; + (void)format.PutFloatValue(PlayerKeys::PLAYER_PLAYBACK_RATE, rate); + callbackLooper_.OnInfo(INFO_TYPE_RATEDONE, extra, format); + MEDIA_LOG_I("SetPlaybackRate end"); + return MSERR_OK; +} + int32_t HiPlayerImpl::GetPlaybackSpeed(PlaybackRateMode& mode) { MEDIA_LOG_I("GetPlaybackSpeed in"); diff --git a/services/engine/histreamer/player/hiplayer_impl.h b/services/engine/histreamer/player/hiplayer_impl.h index 874a11fddd9cbce8d8e29a8a54966099c4d2b41c..8d3ad6e950301f8d941f66642bf214a9bc5f2474 100755 --- a/services/engine/histreamer/player/hiplayer_impl.h +++ b/services/engine/histreamer/player/hiplayer_impl.h @@ -128,6 +128,7 @@ public: int32_t GetPlaybackPosition(int32_t& playbackPositionMs) override; int32_t GetDuration(int32_t& durationMs) override; int32_t SetPlaybackSpeed(PlaybackRateMode mode) override; + int32_t SetPlaybackRate(float rate) override; int32_t SetMediaSource(const std::shared_ptr &mediaSource, AVPlayStrategy strategy) override; int32_t GetPlaybackSpeed(PlaybackRateMode& mode) override; int32_t SelectBitRate(uint32_t bitRate, bool isAutoSelect) override; @@ -312,6 +313,7 @@ private: std::atomic isSeek_ {false}; std::atomic isSeekClosest_ {false}; std::atomic playbackRateMode_ {PlaybackRateMode::SPEED_FORWARD_1_00_X}; + std::atomic playbackRate_ {1.0f}; std::shared_ptr playerEventReceiver_; std::shared_ptr playerFilterCallback_; diff --git a/services/include/i_player_service.h b/services/include/i_player_service.h index a8eb55a1692ce97452af3ce023ec51fa9ecdc60d..8b51c50c070e8c55c7ccfc6027b2d69226c45f40 100644 --- a/services/include/i_player_service.h +++ b/services/include/i_player_service.h @@ -352,6 +352,17 @@ public: */ virtual int32_t SetPlaybackSpeed(PlaybackRateMode mode) = 0; + /** + * @brief set the player playback rate + * + * @param rate the rate {@link PlaybackRateMode} which can set. + * @return Returns {@link MSERR_OK} if the playback rate is set successfully; returns an error code defined + * in {@link media_errors.h} otherwise. + * @since 1.0 + * @version 1.0 + */ + virtual int32_t SetPlaybackRate(float rate) = 0; + virtual int32_t SetMediaSource(const std::shared_ptr &mediaSource, AVPlayStrategy strategy) = 0; /** * @brief set the bit rate use for hls player diff --git a/services/services/engine_intf/i_player_engine.h b/services/services/engine_intf/i_player_engine.h index b8a066c73a2433c8f6306087b1edc9caceb83da0..9d9dbe91e505902f80d5e03fcbd76321c6e559cb 100644 --- a/services/services/engine_intf/i_player_engine.h +++ b/services/services/engine_intf/i_player_engine.h @@ -110,6 +110,7 @@ public: virtual int32_t GetVideoHeight() = 0; virtual int32_t GetDuration(int32_t &duration) = 0; virtual int32_t SetPlaybackSpeed(PlaybackRateMode mode) = 0; + virtual int32_t SetPlaybackRate(float rate) = 0; virtual int32_t GetPlaybackSpeed(PlaybackRateMode &mode) = 0; virtual int32_t SetMediaSource(const std::shared_ptr &mediaSource, AVPlayStrategy strategy) = 0; virtual int32_t SetVideoSurface(sptr surface) = 0; diff --git a/services/services/player/client/player_client.cpp b/services/services/player/client/player_client.cpp index 7ad648db2105c279e2b86bdd51245ddfc161bae5..f7d75bb1e5ec07b9cdadf5afb49177e2fba1c0ec 100644 --- a/services/services/player/client/player_client.cpp +++ b/services/services/player/client/player_client.cpp @@ -316,6 +316,13 @@ int32_t PlayerClient::SetPlaybackSpeed(PlaybackRateMode mode) return playerProxy_->SetPlaybackSpeed(mode); } +int32_t PlayerClient::SetPlaybackRate(float rate) +{ + std::lock_guard lock(mutex_); + CHECK_AND_RETURN_RET_LOG(playerProxy_ != nullptr, MSERR_SERVICE_DIED, "player service does not exist.."); + return playerProxy_->SetPlaybackRate(rate); +} + int32_t PlayerClient::SetMediaSource(const std::shared_ptr &mediaSource, AVPlayStrategy strategy) { MEDIA_LOGD("PlayerClient:0x%{public}06" PRIXPTR " SetMediaSource in", FAKE_POINTER(this)); diff --git a/services/services/player/client/player_client.h b/services/services/player/client/player_client.h index 985ff2797e5fbb3e92d8e5c04c3a1b2a764085c1..a0f12e0ff4f63715e4495d98cd0007bb6e0e628c 100644 --- a/services/services/player/client/player_client.h +++ b/services/services/player/client/player_client.h @@ -58,6 +58,7 @@ public: int32_t GetAudioTrackInfo(std::vector &audioTrack) override; int32_t GetVideoHeight() override; int32_t SetPlaybackSpeed(PlaybackRateMode mode) override; + int32_t SetPlaybackRate(float rate) override; int32_t SetMediaSource(const std::shared_ptr &mediaSource, AVPlayStrategy strategy) override; int32_t GetDuration(int32_t &duration) override; int32_t GetApiVersion(int32_t &apiVersion) override; diff --git a/services/services/player/ipc/i_standard_player_service.h b/services/services/player/ipc/i_standard_player_service.h index c96729c19f606daf0ac37ccd401bea440603bd9e..a5a8c7ec84159ef4c0c60a33da0a081c71134f0f 100644 --- a/services/services/player/ipc/i_standard_player_service.h +++ b/services/services/player/ipc/i_standard_player_service.h @@ -85,6 +85,7 @@ public: virtual int32_t GetVideoHeight() = 0; virtual int32_t GetDuration(int32_t &duration) = 0; virtual int32_t SetPlaybackSpeed(PlaybackRateMode mode) = 0; + virtual int32_t SetPlaybackRate(float rate) = 0; virtual int32_t GetPlaybackSpeed(PlaybackRateMode &mode) = 0; virtual int32_t SetSourceLoader(const sptr &object) = 0; virtual int32_t SetMediaSource(const std::shared_ptr &mediaSource, AVPlayStrategy strategy) = 0; @@ -186,6 +187,7 @@ public: GET_PLAY_BACK_POSITION, GET_DURATION, SET_PLAYERBACK_SPEED, + SET_PLAYERBACK_RATE, GET_PLAYERBACK_SPEED, SET_MEDIA_SOURCE, SET_VIDEO_SURFACE, diff --git a/services/services/player/ipc/player_service_proxy.cpp b/services/services/player/ipc/player_service_proxy.cpp index e5b33b5b9481c6317c054c5ae8313b64331a179f..f65097f137667f024a579caf6a8fa17484bba46d 100644 --- a/services/services/player/ipc/player_service_proxy.cpp +++ b/services/services/player/ipc/player_service_proxy.cpp @@ -75,6 +75,7 @@ void PlayerServiceProxy::InitPlayerFuncsPart1() playerFuncs_[GET_DURATION] = "Player::GetDuration"; playerFuncs_[GET_API_VERSION] = "Player::GetApiVersion"; playerFuncs_[SET_PLAYERBACK_SPEED] = "Player::SetPlaybackSpeed"; + playerFuncs_[SET_PLAYERBACK_RATE] = "Player::SetPlaybackRate"; playerFuncs_[GET_PLAYERBACK_SPEED] = "Player::GetPlaybackSpeed"; #ifdef SUPPORT_VIDEO playerFuncs_[SET_VIDEO_SURFACE] = "Player::SetVideoSurface"; @@ -700,6 +701,23 @@ int32_t PlayerServiceProxy::SetPlaybackSpeed(PlaybackRateMode mode) return reply.ReadInt32(); } +int32_t PlayerServiceProxy::SetPlaybackRate(float rate) +{ + MediaTrace trace("PlayerServiceProxy::SetPlaybackRate"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + + bool token = data.WriteInterfaceToken(PlayerServiceProxy::GetDescriptor()); + CHECK_AND_RETURN_RET_LOG(token, MSERR_INVALID_OPERATION, "Failed to write descriptor!"); + + data.WriteFloat(rate); + int32_t error = SendRequest(SET_PLAYERBACK_RATE, data, reply, option); + CHECK_AND_RETURN_RET_LOG(error == MSERR_OK, MSERR_INVALID_OPERATION, + "SetPlaybackRate failed, error: %{public}d", error); + return reply.ReadFloat(); +} + int32_t PlayerServiceProxy::SetSourceLoader(const sptr &object) { MediaTrace trace("PlayerServiceProxy::SetSourceLoader"); diff --git a/services/services/player/ipc/player_service_proxy.h b/services/services/player/ipc/player_service_proxy.h index b591a0f8996fe52131a694ce88f27e47da28b2b9..3513c29bd33be7f503c7959a475bf3a9d64a8f75 100644 --- a/services/services/player/ipc/player_service_proxy.h +++ b/services/services/player/ipc/player_service_proxy.h @@ -40,6 +40,7 @@ public: int32_t GetAudioTrackInfo(std::vector &audioTrack) override; int32_t AddSubSource(const std::string &url) override; int32_t SetPlaybackSpeed(PlaybackRateMode mode) override; + int32_t SetPlaybackRate(float rate) override; int32_t SetSourceLoader(const sptr &object) override; int32_t SetMediaSource(const std::shared_ptr &mediaSource, AVPlayStrategy strategy) override; int32_t AddSubSource(int32_t fd, int64_t offset, int64_t size) override; diff --git a/services/services/player/ipc/player_service_stub.cpp b/services/services/player/ipc/player_service_stub.cpp index da57a76873747ae7f683a710f931a11a56360fac..955b36138ba71fbb24624767406bf2c670b2ee8c 100644 --- a/services/services/player/ipc/player_service_stub.cpp +++ b/services/services/player/ipc/player_service_stub.cpp @@ -201,6 +201,8 @@ void PlayerServiceStub::FillPlayerFuncPart3() [this](MessageParcel &data, MessageParcel &reply) { return SetVideoWindowSize(data, reply); } }; playerFuncs_[SET_VOLUME_MODE] = { "Player::SetVolumeMode", [this](MessageParcel &data, MessageParcel &reply) { return SetVolumeMode(data, reply); } }; + playerFuncs_[SET_PLAYERBACK_RATE] = { "Player::SetPlaybackRate", + [this](MessageParcel &data, MessageParcel &reply) { return SetPlaybackRate(data, reply); } }; } int32_t PlayerServiceStub::Init() @@ -511,6 +513,13 @@ int32_t PlayerServiceStub::SetPlaybackSpeed(PlaybackRateMode mode) return playerServer_->SetPlaybackSpeed(mode); } +int32_t PlayerServiceStub::SetPlaybackRate(float rate) +{ + MediaTrace trace("PlayerServiceStub::SetPlaybackRate"); + CHECK_AND_RETURN_RET_LOG(playerServer_ != nullptr, MSERR_NO_MEMORY, "player server is nullptr"); + return playerServer_->SetPlaybackRate(rate); +} + int32_t PlayerServiceStub::SetMediaSource(const std::shared_ptr &mediaSource, AVPlayStrategy strategy) { CHECK_AND_RETURN_RET_LOG(mediaSource != nullptr, MSERR_INVALID_VAL, "mediaSource is nullptr"); @@ -946,6 +955,13 @@ int32_t PlayerServiceStub::SetPlaybackSpeed(MessageParcel &data, MessageParcel & return MSERR_OK; } +int32_t PlayerServiceStub::SetPlaybackRate(MessageParcel &data, MessageParcel &reply) +{ + float rate = data.ReadFloat(); + reply.WriteFloat(SetPlaybackRate(rate)); + return MSERR_OK; +} + int32_t PlayerServiceStub::SetMediaSource(MessageParcel &data, MessageParcel &reply) { std::string url = data.ReadString(); diff --git a/services/services/player/ipc/player_service_stub.h b/services/services/player/ipc/player_service_stub.h index f64dafb46fdba6ba68865d7f3e6f77dd8f21b42f..e78fb6cf6ee4a4248a268e23c446719a47afd2a4 100644 --- a/services/services/player/ipc/player_service_stub.h +++ b/services/services/player/ipc/player_service_stub.h @@ -57,6 +57,7 @@ public: int32_t SetVolume(float leftVolume, float rightVolume) override; int32_t SetVolumeMode(int32_t mode) override; int32_t SetPlaybackSpeed(PlaybackRateMode mode) override; + int32_t SetPlaybackRate(float rate) override; int32_t GetVideoWidth() override; int32_t GetAudioTrackInfo(std::vector &audioTrack) override; int32_t GetCurrentTime(int32_t ¤tTime) override; @@ -143,6 +144,7 @@ private: int32_t GetDuration(MessageParcel &data, MessageParcel &reply); int32_t GetApiVersion(MessageParcel &data, MessageParcel &reply); int32_t SetPlaybackSpeed(MessageParcel &data, MessageParcel &reply); + int32_t SetPlaybackRate(MessageParcel &data, MessageParcel &reply); int32_t GetPlaybackSpeed(MessageParcel &data, MessageParcel &reply); #ifdef SUPPORT_VIDEO int32_t SetVideoSurface(MessageParcel &data, MessageParcel &reply); diff --git a/services/services/player/server/player_server.cpp b/services/services/player/server/player_server.cpp index 1bb7a9b43c7fbd24473f5ad585c13d4a654876a4..d51d06fcc14a3cef2b7d54404354e71ce44bcaaa 100644 --- a/services/services/player/server/player_server.cpp +++ b/services/services/player/server/player_server.cpp @@ -1098,6 +1098,42 @@ int32_t PlayerServer::SetPlaybackSpeed(PlaybackRateMode mode) return MSERR_OK; } +int32_t PlayerServer::SetPlaybackRate(float rate) +{ + std::lock_guard lock(mutex_); + + if ((lastOpStatus_ != PLAYER_STARTED) && (lastOpStatus_ != PLAYER_PREPARED) && + (lastOpStatus_ != PLAYER_PAUSED) && (lastOpStatus_ != PLAYER_PLAYBACK_COMPLETE)) { + MEDIA_LOGE("Can not SetPlaybackRate, currentState is %{public}s", + GetStatusDescription(lastOpStatus_).c_str()); + return MSERR_INVALID_OPERATION; + } + MEDIA_LOGD("PlayerServer SetPlaybackRate in, rate %{public}f", rate); + if (isLiveStream_) { + MEDIA_LOGE("Can not SetPlaybackRate, it is live-stream"); + OnErrorMessage(MSERR_EXT_API9_UNSUPPORT_CAPABILITY, "Can not SetPlaybackRate, it is live-stream"); + return MSERR_INVALID_OPERATION; + } + + auto rateTask = std::make_shared>([this, rate]() { + MediaTrace::TraceBegin("PlayerServer::SetPlaybackRate", FAKE_POINTER(this)); + auto currState = std::static_pointer_cast(GetCurrState()); + (void)currState->SetPlaybackRate(rate); + }); + + auto cancelTask = std::make_shared>([this, rate]() { + MEDIA_LOGI("Interrupted rate action"); + Format format; + OnInfoNoChangeStatus(INFO_TYPE_RATEDONE, rate, format); + taskMgr_.MarkTaskDone("interrupted rate done"); + }); + + int ret = taskMgr_.SpeedTask(rateTask, cancelTask, "rate", config_.speedRate); + CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "SetPlaybackRate failed"); + + return MSERR_OK; +} + int32_t PlayerServer::HandleSetPlaybackSpeed(PlaybackRateMode mode) { if (config_.speedMode == mode) { @@ -1117,6 +1153,26 @@ int32_t PlayerServer::HandleSetPlaybackSpeed(PlaybackRateMode mode) return MSERR_OK; } +int32_t PlayerServer::HandleSetPlaybackRate(float rate) +{ + if (config_.speedRate == rate) { + MEDIA_LOGD("The speed rate is same, rate = %{public}f", rate); + Format format; + (void)format.PutFloatValue(PlayerKeys::PLAYER_PLAYBACK_RATE, rate); + OnInfoNoChangeStatus(INFO_TYPE_RATEDONE, rate, format); + taskMgr_.MarkTaskDone("set speed rate is same"); + MediaTrace::TraceEnd("PlayerServer::SetPlaybackRate", FAKE_POINTER(this)); + return MSERR_OK; + } + + if (playerEngine_ != nullptr) { + int ret = playerEngine_->SetPlaybackRate(rate); + CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "Engine SetPlaybackRate Failed!"); + } + config_.speedRate = rate; + return MSERR_OK; +} + int32_t PlayerServer::SetMediaSource(const std::shared_ptr &mediaSource, AVPlayStrategy strategy) { std::lock_guard lock(mutex_); diff --git a/services/services/player/server/player_server.h b/services/services/player/server/player_server.h index 5118527940e480f4c0b6bc1dab0b2a2f40c3c7a4..50ac13261d942bb61445d6dd6be30accedd60e77 100644 --- a/services/services/player/server/player_server.h +++ b/services/services/player/server/player_server.h @@ -101,6 +101,7 @@ public: int32_t GetDuration(int32_t &duration) override; int32_t GetApiVersion(int32_t &apiVersion) override; int32_t SetPlaybackSpeed(PlaybackRateMode mode) override; + int32_t SetPlaybackRate(float rate) override; int32_t SetSource(const std::string &url) override; int32_t SetSource(const std::shared_ptr &dataSrc) override; int32_t SetSource(int32_t fd, int64_t offset, int64_t size) override; @@ -194,6 +195,7 @@ protected: float leftVolume = INVALID_VALUE; float rightVolume = INVALID_VALUE; PlaybackRateMode speedMode = SPEED_FORWARD_1_00_X; + float speedRate = 1.0f; std::string url; int32_t effectMode = OHOS::AudioStandard::AudioEffectMode::EFFECT_DEFAULT; std::map header; @@ -219,6 +221,7 @@ private: int32_t HandleEosPlay(); int32_t HandleSetPlayRange(int64_t start, int64_t end, PlayerSeekMode mode); int32_t HandleSetPlaybackSpeed(PlaybackRateMode mode); + int32_t HandleSetPlaybackRate(float rate); int32_t SetAudioEffectMode(const int32_t effectMode); void HandleEos(); diff --git a/services/services/player/server/player_server_state.cpp b/services/services/player/server/player_server_state.cpp index 25cc85db937ae2537b503f0feeb191c2d4ce3cac..56320c27ba0af4c03f1fea853bf1e00462fc2f8a 100644 --- a/services/services/player/server/player_server_state.cpp +++ b/services/services/player/server/player_server_state.cpp @@ -88,6 +88,14 @@ int32_t PlayerServer::BaseState::SetPlaybackSpeed(PlaybackRateMode mode) return MSERR_INVALID_STATE; } +int32_t PlayerServer::BaseState::SetPlaybackRate(float rate) +{ + (void)rate; + + ReportInvalidOperation(); + return MSERR_INVALID_STATE; +} + int32_t PlayerServer::BaseState::SeekContinous(int32_t mSeconds, int64_t batchNo) { (void)mSeconds; @@ -142,6 +150,13 @@ int32_t PlayerServer::BaseState::MessageSpeedDone() return MSERR_OK; } +int32_t PlayerServer::BaseState::MessageRateDone() +{ + (void)server_.taskMgr_.MarkTaskDone("rate done"); + MediaTrace::TraceEnd("PlayerServer::SetPlaybackRate", FAKE_POINTER(&server_)); + return MSERR_OK; +} + int32_t PlayerServer::BaseState::MessageStateChange(int32_t extra) { if (extra == PLAYER_PLAYBACK_COMPLETE) { @@ -175,6 +190,10 @@ int32_t PlayerServer::BaseState::OnMessageReceived(PlayerOnInfoType type, int32_ ret = MessageSpeedDone(); break; + case INFO_TYPE_RATEDONE: + ret = MessageRateDone(); + break; + case INFO_TYPE_EOS: HandleEos(); break; @@ -278,6 +297,11 @@ int32_t PlayerServer::PreparedState::SetPlaybackSpeed(PlaybackRateMode mode) return server_.HandleSetPlaybackSpeed(mode); } +int32_t PlayerServer::PreparedState::SetPlaybackRate(float rate) +{ + return server_.HandleSetPlaybackRate(rate); +} + int32_t PlayerServer::PreparedState::SeekContinous(int32_t mSeconds, int64_t batchNo) { return server_.HandleSeekContinous(mSeconds, batchNo); @@ -346,6 +370,11 @@ int32_t PlayerServer::PlayingState::SetPlaybackSpeed(PlaybackRateMode mode) return server_.HandleSetPlaybackSpeed(mode); } +int32_t PlayerServer::PlayingState::SetPlaybackRate(float rate) +{ + return server_.HandleSetPlaybackRate(rate); +} + int32_t PlayerServer::PlayingState::SeekContinous(int32_t mSeconds, int64_t batchNo) { return server_.HandleSeekContinous(mSeconds, batchNo); @@ -442,6 +471,11 @@ int32_t PlayerServer::PausedState::SetPlaybackSpeed(PlaybackRateMode mode) return server_.HandleSetPlaybackSpeed(mode); } +int32_t PlayerServer::PausedState::SetPlaybackRate(float rate) +{ + return server_.HandleSetPlaybackRate(rate); +} + int32_t PlayerServer::PausedState::SeekContinous(int32_t mSeconds, int64_t batchNo) { return server_.HandleSeekContinous(mSeconds, batchNo); @@ -552,5 +586,10 @@ int32_t PlayerServer::PlaybackCompletedState::SetPlaybackSpeed(PlaybackRateMode { return server_.HandleSetPlaybackSpeed(mode); } + +int32_t PlayerServer::PlaybackCompletedState::SetPlaybackRate(float rate) +{ + return server_.HandleSetPlaybackRate(rate); +} } } diff --git a/services/services/player/server/player_server_state.h b/services/services/player/server/player_server_state.h index 9c17e75554baaed2f99ac419868fcbd216633686..f766cf6c9463bc5fc7341059cba2fa6e42d4593a 100644 --- a/services/services/player/server/player_server_state.h +++ b/services/services/player/server/player_server_state.h @@ -30,6 +30,7 @@ public: virtual int32_t Pause(bool isSystemOperation); virtual int32_t Seek(int32_t mSeconds, PlayerSeekMode mode); virtual int32_t SetPlaybackSpeed(PlaybackRateMode mode); + virtual int32_t SetPlaybackRate(float rate); virtual int32_t Stop(); virtual int32_t SeekContinous(int32_t mSeconds, int64_t batchNo); virtual int32_t PauseDemuxer(); @@ -59,6 +60,7 @@ protected: int32_t MessageTrackDone(int32_t extra); int32_t MessageTrackInfoUpdate(); int32_t MessageSpeedDone(); + int32_t MessageRateDone(); int32_t MessageStateChange(int32_t extra); PlayerServer &server_; @@ -104,6 +106,7 @@ public: int32_t Seek(int32_t mSeconds, PlayerSeekMode mode) override; int32_t Stop() override; int32_t SetPlaybackSpeed(PlaybackRateMode mode) override; + int32_t SetPlaybackRate(float rate) override; int32_t SeekContinous(int32_t mSeconds, int64_t batchNo) override; int32_t SetPlayRangeWithMode(int64_t start, int64_t end, PlayerSeekMode mode) override; @@ -122,6 +125,7 @@ public: int32_t Seek(int32_t mSeconds, PlayerSeekMode mode) override; int32_t Stop() override; int32_t SetPlaybackSpeed(PlaybackRateMode mode) override; + int32_t SetPlaybackRate(float rate) override; int32_t SeekContinous(int32_t mSeconds, int64_t batchNo) override; int32_t PauseDemuxer() override; int32_t ResumeDemuxer() override; @@ -146,6 +150,7 @@ public: int32_t Seek(int32_t mSeconds, PlayerSeekMode mode) override; int32_t Stop() override; int32_t SetPlaybackSpeed(PlaybackRateMode mode) override; + int32_t SetPlaybackRate(float rate) override; int32_t SeekContinous(int32_t mSeconds, int64_t batchNo) override; int32_t SetPlayRangeWithMode(int64_t start, int64_t end, PlayerSeekMode mode) override; @@ -174,6 +179,7 @@ public: int32_t Seek(int32_t mSeconds, PlayerSeekMode mode) override; int32_t Stop() override; int32_t SetPlaybackSpeed(PlaybackRateMode mode) override; + int32_t SetPlaybackRate(float rate) override; int32_t SeekContinous(int32_t mSeconds, int64_t batchNo) override; int32_t SetPlayRangeWithMode(int64_t start, int64_t end, PlayerSeekMode mode) override; void StateEnter() override; diff --git a/test/fuzztest/player_fuzztest/playerstub_fuzzer/player_service_proxy_fuzzer.h b/test/fuzztest/player_fuzztest/playerstub_fuzzer/player_service_proxy_fuzzer.h index a661d212ba1c59033689a18106cc027e318cf667..e837fdf1f24af03026673137c044dac57a506fe9 100644 --- a/test/fuzztest/player_fuzztest/playerstub_fuzzer/player_service_proxy_fuzzer.h +++ b/test/fuzztest/player_fuzztest/playerstub_fuzzer/player_service_proxy_fuzzer.h @@ -139,6 +139,10 @@ public: { return 0; } + int32_t SetPlaybackRate(float rate) override + { + return 0; + } int32_t GetPlaybackSpeed(PlaybackRateMode &mode) override { return 0; diff --git a/test/unittest/hiplayer_impl_test/mock/mock_iplayer_engine.h b/test/unittest/hiplayer_impl_test/mock/mock_iplayer_engine.h index 24097e02af16225aba2c8c9e363259ea66b053ac..327667480a625d74b3ce98670cc07c635ba01472 100644 --- a/test/unittest/hiplayer_impl_test/mock/mock_iplayer_engine.h +++ b/test/unittest/hiplayer_impl_test/mock/mock_iplayer_engine.h @@ -66,6 +66,7 @@ public: MOCK_METHOD(int32_t, GetVideoHeight, (), ()); MOCK_METHOD(int32_t, GetDuration, (int32_t &duration), ()); MOCK_METHOD(int32_t, SetPlaybackSpeed, (PlaybackRateMode mode), ()); + MOCK_METHOD(int32_t, SetPlaybackRate, (float rate), ()); MOCK_METHOD(int32_t, GetPlaybackSpeed, (PlaybackRateMode &mode), ()); MOCK_METHOD(int32_t, SetMediaSource, (const std::shared_ptr &mediaSource, AVPlayStrategy strategy), ());