diff --git a/component_ext/movingphoto/movingphoto_controller.h b/component_ext/movingphoto/movingphoto_controller.h index 3c606b71bbd0502c2406ff55f026b23c91d62dd0..30011d5ea72a392e06c51269e6a8477f56e3d598 100644 --- a/component_ext/movingphoto/movingphoto_controller.h +++ b/component_ext/movingphoto/movingphoto_controller.h @@ -32,6 +32,12 @@ public: using StartPlaybackImpl = std::function; using StopPlaybackImpl = std::function; using RefreshMovingPhotoImpl = std::function; + using PauseImpl = std::function; + using ResetImpl = std::function; + using RestartImpl = std::function; + using EnableTransitionImpl = std::function; + using SetPlaybackPeriodFucImpl = std::function; + using EnableAutoPlayImpl = std::function; void SetStartPlaybackImpl(StartPlaybackImpl&& startPlaybackImpl) { @@ -69,10 +75,88 @@ public: } } + void SetPauseImpl(PauseImpl&& pauseImpl) + { + pauseImpl_ = std::move(pauseImpl); + } + + void Pause() + { + if (pauseImpl_) { + pauseImpl_(); + } + } + + void SetResetImpl(ResetImpl&& resetImpl) + { + resetImpl_ = std::move(resetImpl); + } + + void Reset() + { + if (resetImpl_) { + resetImpl_(); + } + } + + void SetRestartImpl(RestartImpl&& restartImpl) + { + restartImpl_ = std::move(restartImpl); + } + + void Restart() + { + if (restartImpl_) { + restartImpl_(); + } + } + + void SetPlaybackPeriodImpl(SetPlaybackPeriodFucImpl&& setPlaybackPeriodImpl) + { + setPlaybackPeriodFucImpl_ = std::move(setPlaybackPeriodImpl); + } + + void SetPlaybackPeriod(int64_t startTime, int64_t endTime) + { + if (setPlaybackPeriodFucImpl_) { + setPlaybackPeriodFucImpl_(startTime, endTime); + } + } + + void SetEnableTransitionImpl(EnableTransitionImpl&& enableTransitionImpl) + { + enableTransitionImpl_ = std::move(enableTransitionImpl); + } + + void EnableTransition(bool enabled) + { + if (enableTransitionImpl_) { + enableTransitionImpl_(enabled); + } + } + + void SetEnableAutoPlayImpl(EnableAutoPlayImpl&& enableAutoPlayImpl) + { + enableAutoPlayImpl_ = std::move(enableAutoPlayImpl); + } + + void EnableAutoPlay(bool enabled) + { + if (enableAutoPlayImpl_) { + enableAutoPlayImpl_(enabled); + } + } + private: StartPlaybackImpl startPlaybackImpl_; StopPlaybackImpl stopPlaybackImpl_; RefreshMovingPhotoImpl refreshMovingPhotoImpl_; + PauseImpl pauseImpl_; + ResetImpl resetImpl_; + RestartImpl restartImpl_; + EnableTransitionImpl enableTransitionImpl_; + SetPlaybackPeriodFucImpl setPlaybackPeriodFucImpl_; + EnableAutoPlayImpl enableAutoPlayImpl_; }; } // namespace OHOS::Ace::NG diff --git a/component_ext/movingphoto/movingphoto_event_hub.h b/component_ext/movingphoto/movingphoto_event_hub.h index af59cd1793300f2e99cea8f448b2e9cc2a1212ae..fa1253339e64b68e4860193a9a1f0b852d22f830 100644 --- a/component_ext/movingphoto/movingphoto_event_hub.h +++ b/component_ext/movingphoto/movingphoto_event_hub.h @@ -135,6 +135,24 @@ public: } } + void SetOnPrepared(MovingPhotoEventFunc&& onPrepared) + { + onPrepared_ = std ::move(onPrepared); + } + + MovingPhotoEventFunc GetOnPrepared() + { + return onPrepared_; + } + + void FirePreparedEvent() + { + if (onPrepared_) { + auto onPrepared = onPrepared_; + onPrepared(); + } + } + private: MovingPhotoEventFunc onComplete_; MovingPhotoEventFunc onStart_; @@ -142,6 +160,7 @@ private: MovingPhotoEventFunc onPause_; MovingPhotoEventFunc onFinish_; MovingPhotoEventFunc onError_; + MovingPhotoEventFunc onPrepared_; }; } // namespace OHOS::Ace::NG diff --git a/component_ext/movingphoto/movingphoto_model_ng.cpp b/component_ext/movingphoto/movingphoto_model_ng.cpp index 7cb79472e0999258bbea22bd8498597fe30b8acf..e3a59442c5993a28fb9ef98d4deae587c0f00b99 100644 --- a/component_ext/movingphoto/movingphoto_model_ng.cpp +++ b/component_ext/movingphoto/movingphoto_model_ng.cpp @@ -172,6 +172,15 @@ void MovingPhotoModelNG::SetOnError(MovingPhotoEventFunc&& onError) eventHub->SetOnError(std::move(onError)); } +void MovingPhotoModelNG::SetOnPrepared(MovingPhotoEventFunc&& onPrepared) +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto eventHub = frameNode->GetOrCreateEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnPrepared(std::move(onPrepared)); +} + void MovingPhotoModelNG::AutoPlayPeriod(int64_t startTime, int64_t endTime) { auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); diff --git a/component_ext/movingphoto/movingphoto_model_ng.h b/component_ext/movingphoto/movingphoto_model_ng.h index 816ebb2199528486ab9b475f66c9ed2567496a68..50b710c5dcda4bf27658b995df3d306b7cc6191e 100644 --- a/component_ext/movingphoto/movingphoto_model_ng.h +++ b/component_ext/movingphoto/movingphoto_model_ng.h @@ -39,6 +39,7 @@ public: void SetOnPause(MovingPhotoEventFunc&& onPause); void SetOnFinish(MovingPhotoEventFunc&& onFinish); void SetOnError(MovingPhotoEventFunc&& onError); + void SetOnPrepared(MovingPhotoEventFunc&& onPrepared); void AutoPlayPeriod(int64_t startTime, int64_t endTime); void AutoPlay(bool isAutoPlay); void RepeatPlay(bool isRepeatPlay); diff --git a/component_ext/movingphoto/movingphoto_napi.cpp b/component_ext/movingphoto/movingphoto_napi.cpp index fc574c16ad07ae8c4e707d7b7af43d6a94a344d7..3d128bad242f76628f7fb86c841fce9b1a150803 100644 --- a/component_ext/movingphoto/movingphoto_napi.cpp +++ b/component_ext/movingphoto/movingphoto_napi.cpp @@ -276,6 +276,24 @@ napi_value JsOnError(napi_env env, napi_callback_info info) return ExtNapiUtils::CreateNull(env); } +napi_value JsOnPrepared(napi_env env, napi_callback_info info) +{ + size_t argc = MAX_ARG_NUM; + napi_value thisVal = nullptr; + napi_value argv[MAX_ARG_NUM] = { nullptr }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr)); + NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments"); + if (!ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_function)) { + return ExtNapiUtils::CreateNull(env); + } + auto asyncEvent = std::make_shared(env, argv[0]); + auto onPrepared = [asyncEvent]() { + asyncEvent->Call(0, nullptr); + }; + NG::MovingPhotoModelNG::GetInstance()->SetOnPrepared(std::move(onPrepared)); + return ExtNapiUtils::CreateNull(env); +} + napi_value InitView(napi_env env, napi_value exports) { static napi_property_descriptor desc[] = { @@ -288,6 +306,7 @@ napi_value InitView(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("onPause", JsOnPause), DECLARE_NAPI_FUNCTION("onFinish", JsOnFinish), DECLARE_NAPI_FUNCTION("onError", JsOnError), + DECLARE_NAPI_FUNCTION("onPrepared", JsOnPrepared), DECLARE_NAPI_FUNCTION("autoPlayPeriod", JsAutoPlayPeriod), DECLARE_NAPI_FUNCTION("autoPlay", JsAutoPlay), DECLARE_NAPI_FUNCTION("repeatPlay", JsRepeatPlay), @@ -337,6 +356,110 @@ napi_value RefreshMovingPhoto(napi_env env, napi_callback_info info) return ExtNapiUtils::CreateNull(env); } +napi_value Pause(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, NULL)); + NG::MovingPhotoController* controller = nullptr; + napi_unwrap(env, thisVar, (void**)&controller); + if (controller == nullptr) { + return ExtNapiUtils::CreateNull(env); + } + controller->Pause(); + return ExtNapiUtils::CreateNull(env); +} + +napi_value Reset(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, NULL)); + NG::MovingPhotoController* controller = nullptr; + napi_unwrap(env, thisVar, (void**)&controller); + if (controller == nullptr) { + return ExtNapiUtils::CreateNull(env); + } + controller->Reset(); + return ExtNapiUtils::CreateNull(env); +} + +napi_value Restart(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, NULL)); + NG::MovingPhotoController* controller = nullptr; + napi_unwrap(env, thisVar, (void**)&controller); + if (controller == nullptr) { + return ExtNapiUtils::CreateNull(env); + } + controller->Restart(); + return ExtNapiUtils::CreateNull(env); +} + +napi_value EnableTransition(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + size_t argc = MAX_ARG_NUM; + napi_value argv[MAX_ARG_NUM] = { nullptr }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + NAPI_ASSERT(env, argc >= ARG_NUM_TWO, "Wrong number of arguments"); + bool enabled = true; + if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[PARAM_INDEX_ZERO], napi_number)) { + enabled = ExtNapiUtils::GetBool(env, argv[PARAM_INDEX_ZERO]); + } + NG::MovingPhotoController* controller = nullptr; + napi_unwrap(env, thisVar, (void**)&controller); + if (controller == nullptr) { + return ExtNapiUtils::CreateNull(env); + } + controller->EnableTransition(enabled); + return ExtNapiUtils::CreateNull(env); +} + +napi_value SetPlaybackPeriod(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + size_t argc = MAX_ARG_NUM; + napi_value argv[MAX_ARG_NUM] = { nullptr }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + NAPI_ASSERT(env, argc >= ARG_NUM_TWO, "Wrong number of arguments"); + int64_t startTime = 0; + if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[PARAM_INDEX_ZERO], napi_number)) { + startTime = static_cast(ExtNapiUtils::GetDouble(env, argv[PARAM_INDEX_ZERO]) * US_CONVERT); + } + int64_t endTime = 0; + if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[PARAM_INDEX_ONE], napi_number)) { + endTime = static_cast(ExtNapiUtils::GetDouble(env, argv[PARAM_INDEX_ONE]) * US_CONVERT); + } + NG::MovingPhotoController* controller = nullptr; + napi_unwrap(env, thisVar, (void**)&controller); + if (controller == nullptr) { + return ExtNapiUtils::CreateNull(env); + } + controller->SetPlaybackPeriod(startTime, endTime); + return ExtNapiUtils::CreateNull(env); +} + +napi_value EnableAutoPlay(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + size_t argc = MAX_ARG_NUM; + napi_value argv[MAX_ARG_NUM] = { nullptr }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + NAPI_ASSERT(env, argc >= ARG_NUM_TWO, "Wrong number of arguments"); + bool enabled = true; + if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[PARAM_INDEX_ZERO], napi_number)) { + enabled = ExtNapiUtils::GetBool(env, argv[PARAM_INDEX_ZERO]); + } + NG::MovingPhotoController* controller = nullptr; + napi_unwrap(env, thisVar, (void**)&controller); + if (controller == nullptr) { + return ExtNapiUtils::CreateNull(env); + } + controller->EnableAutoPlay(enabled); + return ExtNapiUtils::CreateNull(env); +} + + napi_value MovingPhotoControllerConstructor(napi_env env, napi_callback_info info) { napi_value thisVar = nullptr; @@ -363,6 +486,12 @@ napi_value InitController(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("startPlayback", StartPlayback), DECLARE_NAPI_FUNCTION("stopPlayback", StopPlayback), DECLARE_NAPI_FUNCTION("refreshMovingPhoto", RefreshMovingPhoto), + DECLARE_NAPI_FUNCTION("pause", Pause), + DECLARE_NAPI_FUNCTION("reset", Reset), + DECLARE_NAPI_FUNCTION("restart", Restart), + DECLARE_NAPI_FUNCTION("enableTransition", EnableTransition), + DECLARE_NAPI_FUNCTION("setPlaybackPeriod", SetPlaybackPeriod), + DECLARE_NAPI_FUNCTION("enableAutoPlay", EnableAutoPlay), }; NAPI_CALL(env, napi_define_class(env, "MovingPhotoViewController", NAPI_AUTO_LENGTH, MovingPhotoControllerConstructor, nullptr, sizeof(properties) / sizeof(*properties), properties, diff --git a/component_ext/movingphoto/movingphoto_napi.h b/component_ext/movingphoto/movingphoto_napi.h index d887ec5181266315cfc2abd2476043f4f5b82213..85c132601774511be2777cb5f64c536833d29e4a 100644 --- a/component_ext/movingphoto/movingphoto_napi.h +++ b/component_ext/movingphoto/movingphoto_napi.h @@ -33,8 +33,15 @@ napi_value JsOnStop(napi_env env, napi_callback_info info); napi_value JsOnPause(napi_env env, napi_callback_info info); napi_value JsOnFinish(napi_env env, napi_callback_info info); napi_value JsOnError(napi_env env, napi_callback_info info); +napi_value JsOnPrepared(napi_env env, napi_callback_info info); napi_value StartPlayback(napi_env env, napi_callback_info info); napi_value StopPlayback(napi_env env, napi_callback_info info); +napi_value Pause(napi_env env, napi_callback_info info); +napi_value Reset(napi_env env, napi_callback_info info); +napi_value Restart(napi_env env, napi_callback_info info); +napi_value EnableTransition(napi_env env, napi_callback_info info); +napi_value SetPlaybackPeriod(napi_env env, napi_callback_info info); +napi_value EnableAutoPlay(napi_env env, napi_callback_info info); napi_value JsAutoPlayPeriod(napi_env env, napi_callback_info info); napi_value JsAutoPlay(napi_env env, napi_callback_info info); napi_value JsRepeatPlay(napi_env env, napi_callback_info info); diff --git a/component_ext/movingphoto/movingphoto_pattern.cpp b/component_ext/movingphoto/movingphoto_pattern.cpp index 0a711d88e938acec056191d11d5e457835df5350..19317114e62fe7c3177ac475f53bc7675e03313b 100644 --- a/component_ext/movingphoto/movingphoto_pattern.cpp +++ b/component_ext/movingphoto/movingphoto_pattern.cpp @@ -100,6 +100,20 @@ void MovingPhotoPattern::OnAttachToFrameNode() auto context = PipelineContext::GetCurrentContext(); CHECK_NULL_VOID(context); auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI); + SetStartPlaybackImpl(uiTaskExecutor); + SetStopPlaybackImpl(uiTaskExecutor); + SetRefreshMovingPhotoImpl(uiTaskExecutor); + SetPauseImpl(uiTaskExecutor); + SetResetImpl(uiTaskExecutor); + SetRestartImpl(uiTaskExecutor); + SetEnableTransitionImpl(uiTaskExecutor); + SetPlaybackPeriodImpl(uiTaskExecutor); + SetEnableAutoPlayImpl(uiTaskExecutor); + RegisterVisibleAreaChange(); +} + +void MovingPhotoPattern::SetStartPlaybackImpl(const SingleTaskExecutor& uiTaskExecutor) +{ controller_->SetStartPlaybackImpl([weak = WeakClaim(this), uiTaskExecutor]() { uiTaskExecutor.PostTask( [weak]() { @@ -109,7 +123,10 @@ void MovingPhotoPattern::OnAttachToFrameNode() pattern->StartPlayback(); }, "ArkUIMovingPhotoStart"); }); +} +void MovingPhotoPattern::SetStopPlaybackImpl(const SingleTaskExecutor& uiTaskExecutor) +{ controller_->SetStopPlaybackImpl([weak = WeakClaim(this), uiTaskExecutor]() { uiTaskExecutor.PostTask( [weak]() { @@ -119,7 +136,10 @@ void MovingPhotoPattern::OnAttachToFrameNode() pattern->StopPlayback(); }, "ArkUIMovingPhotoStop"); }); +} +void MovingPhotoPattern::SetRefreshMovingPhotoImpl(const SingleTaskExecutor& uiTaskExecutor) +{ controller_->SetRefreshMovingPhotoImpl([weak = WeakClaim(this), uiTaskExecutor]() { uiTaskExecutor.PostTask( [weak]() { @@ -127,10 +147,86 @@ void MovingPhotoPattern::OnAttachToFrameNode() CHECK_NULL_VOID(pattern); ContainerScope scope(pattern->instanceId_); pattern->RefreshMovingPhoto(); - }, "RefreshMovingPhoto"); + }, "ArkUIRefreshMovingPhoto"); }); +} - RegisterVisibleAreaChange(); +void MovingPhotoPattern::SetPauseImpl(const SingleTaskExecutor& uiTaskExecutor) +{ + controller_->SetPauseImpl([weak = WeakClaim(this), uiTaskExecutor]() { + uiTaskExecutor.PostTask( + [weak]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + ContainerScope scope(pattern->instanceId_); + pattern->PauseVideo(); + }, "ArkUIPauseVideo"); + }); +} + +void MovingPhotoPattern::SetResetImpl(const SingleTaskExecutor& uiTaskExecutor) +{ + controller_->SetResetImpl([weak = WeakClaim(this), uiTaskExecutor]() { + uiTaskExecutor.PostTask( + [weak]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + ContainerScope scope(pattern->instanceId_); + pattern->ResetVideo(); + }, "ArkUIResetVideo"); + }); +} + +void MovingPhotoPattern::SetRestartImpl(const SingleTaskExecutor& uiTaskExecutor) +{ + controller_->SetRestartImpl([weak = WeakClaim(this), uiTaskExecutor]() { + uiTaskExecutor.PostTask( + [weak]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + ContainerScope scope(pattern->instanceId_); + pattern->RestartVideo(); + }, "ArkUIRestartVideo"); + }); +} + +void MovingPhotoPattern::SetEnableTransitionImpl(const SingleTaskExecutor& uiTaskExecutor) +{ + controller_->SetEnableTransitionImpl([weak = WeakClaim(this), uiTaskExecutor](bool enabled) { + uiTaskExecutor.PostTask( + [weak, enabled]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + ContainerScope scope(pattern->instanceId_); + pattern->SetEnableTransition(enabled); + }, "ArkUISetEnableTransition"); + }); +} + +void MovingPhotoPattern::SetPlaybackPeriodImpl(const SingleTaskExecutor& uiTaskExecutor) +{ + controller_->SetPlaybackPeriodImpl([weak = WeakClaim(this), uiTaskExecutor](int64_t startTime, int64_t endTime) { + uiTaskExecutor.PostTask( + [weak, startTime, endTime]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + ContainerScope scope(pattern->instanceId_); + pattern->SetPlaybackPeriod(startTime, endTime); + }, "ArkUISetPlaybackPeriod"); + }); +} + +void MovingPhotoPattern::SetEnableAutoPlayImpl(const SingleTaskExecutor& uiTaskExecutor) +{ + controller_->SetEnableAutoPlayImpl([weak = WeakClaim(this), uiTaskExecutor](bool enabled) { + uiTaskExecutor.PostTask( + [weak, enabled]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + ContainerScope scope(pattern->instanceId_); + pattern->EnableAutoPlay(enabled); + }, "ArkUIEnableAutoPlay"); + }); } void MovingPhotoPattern::OnDetachFromFrameNode(FrameNode* frameNode) @@ -261,8 +357,7 @@ void MovingPhotoPattern::HandleLongPress(GestureEvent& info) if (currentPlayStatus_ == PlaybackStatus::STOPPED) { mediaPlayer_->PrepareAsync(); } - if (isSetAutoPlayPeriod_ && (currentPlayStatus_ == PlaybackStatus::PLAYBACK_COMPLETE || - currentPlayStatus_ == PlaybackStatus::PAUSED)) { + if (currentPlayStatus_ == PlaybackStatus::PLAYBACK_COMPLETE || currentPlayStatus_ == PlaybackStatus::PAUSED) { int32_t duration = DURATION_FLAG; mediaPlayer_->GetDuration(duration); SetAutoPlayPeriod(PERIOD_START, duration * US_CONVERT); @@ -498,6 +593,11 @@ void MovingPhotoPattern::ResetMediaPlayer() { CHECK_NULL_VOID(mediaPlayer_); isPrepared_ = false; + isStopAnimation_ = false; + int32_t duration = DURATION_FLAG; + mediaPlayer_->GetDuration(duration); + autoPlayPeriodStartTime_ = PERIOD_START; + autoPlayPeriodEndTime_ = duration; ContainerScope scope(instanceId_); auto context = PipelineContext::GetCurrentContext(); CHECK_NULL_VOID(context); @@ -699,6 +799,13 @@ void MovingPhotoPattern::FireMediaPlayerError() eventHub->FireErrorEvent(); } +void MovingPhotoPattern::FireMediaPlayerPrepared() +{ + auto eventHub = GetOrCreateEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->FirePreparedEvent(); +} + void MovingPhotoPattern::OnResolutionChange() { if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) { @@ -730,6 +837,11 @@ void MovingPhotoPattern::OnStartedStatusCallback() CHECK_NULL_VOID(movingPhoto); auto image = AceType::DynamicCast(movingPhoto->GetImage()); CHECK_NULL_VOID(image); + if (isStopAnimation_) { + TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer OnStartedStatusCallback stop startAnimation."); + isStopAnimation_ = false; + return; + } StartAnimation(); } @@ -1343,6 +1455,7 @@ void MovingPhotoPattern::OnMediaPlayerPrepared() UpdateMediaPlayerSpeed(); UpdateMediaPlayerMuted(); VisiblePlayback(); + FireMediaPlayerPrepared(); } void MovingPhotoPattern::OnMediaPlayerStoped() @@ -1359,7 +1472,7 @@ void MovingPhotoPattern::OnMediaPlayerCompletion() StopAnimation(); } } - + isStopAnimation_ = false; FireMediaPlayerFinish(); } @@ -1483,10 +1596,7 @@ void MovingPhotoPattern::StartAnimation() void MovingPhotoPattern::RsContextUpdateTransformScale(const RefPtr& imageRsContext, const RefPtr& videoRsContext, PlaybackMode playbackMode) { - if (playbackMode == PlaybackMode::REPEAT) { - videoRsContext->UpdateTransformScale({NORMAL_SCALE, NORMAL_SCALE}); - imageRsContext->UpdateTransformScale({NORMAL_SCALE, NORMAL_SCALE}); - } else if (playbackMode == PlaybackMode::AUTO) { + if (playbackMode == PlaybackMode::REPEAT || playbackMode == PlaybackMode::AUTO || !isEnableTransition_) { videoRsContext->UpdateTransformScale({NORMAL_SCALE, NORMAL_SCALE}); imageRsContext->UpdateTransformScale({NORMAL_SCALE, NORMAL_SCALE}); } else { @@ -1528,6 +1638,124 @@ void MovingPhotoPattern::PausePlayback() StopAnimation(); } +void MovingPhotoPattern::PauseVideo() +{ + isFastKeyUp_ = false; + if (currentPlayStatus_ != PlaybackStatus::STARTED || !isPrepared_) { + TAG_LOGE(AceLogTag::ACE_MOVING_PHOTO, "movingphoto Pause return."); + return; + } + if (isRefreshMovingPhotoPlaying_ && autoAndRepeatLevel_ == PlaybackMode::REPEAT) { + TAG_LOGE(AceLogTag::ACE_MOVING_PHOTO, "HandleTouchEvent IsRefreshMovingPhotoReturn."); + return; + } + TAG_LOGE(AceLogTag::ACE_MOVING_PHOTO, "movingphoto Pause video."); + isStopAnimation_ = true; + Pause(); +} + +void MovingPhotoPattern::ResetVideo() +{ + isFastKeyUp_ = false; + if (currentPlayStatus_ == PlaybackStatus::ERROR) { + ResetMediaPlayer(); + } + if (currentPlayStatus_ == PlaybackStatus::STOPPED) { + mediaPlayer_->PrepareAsync(); + } + if (currentPlayStatus_ == PlaybackStatus::STARTED) { + Pause(); + } + TAG_LOGE(AceLogTag::ACE_MOVING_PHOTO, "movingphoto reset video."); + int32_t duration = DURATION_FLAG; + mediaPlayer_->GetDuration(duration); + SetAutoPlayPeriod(PERIOD_START, duration); + Seek(0); + historyAutoAndRepeatLevel_ = PlaybackMode::NONE; + autoAndRepeatLevel_ = PlaybackMode::NONE; + isSetAutoPlayPeriod_ = false; + StopAnimation(); +} + +void MovingPhotoPattern::RestartVideo() +{ + if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) { + TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is null or invalid."); + return; + } + if (currentPlayStatus_ == PlaybackStatus::STOPPED) { + mediaPlayer_->PrepareAsync(); + } + TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto restart video."); + isPlayByController_ = true; + ContainerScope scope(instanceId_); + auto context = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID(context); + auto platformTask = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::BACKGROUND); + platformTask.PostTask( + [weak = WeakClaim(RawPtr(mediaPlayer_))] { + auto mediaPlayer = weak.Upgrade(); + CHECK_NULL_VOID(mediaPlayer); + mediaPlayer->Play(); + }, + "ArkUIMovingPhotoUpdateMuted"); +} + +void MovingPhotoPattern::SetEnableTransition(bool enabled) +{ + TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto SetEnableTransition %{public}d.", enabled); + isEnableTransition_ = enabled; +} + +bool MovingPhotoPattern::GetEnableTransition() +{ + TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto SetEnableTransition %{public}d.", isEnableTransition_); + return isEnableTransition_; +} + +void MovingPhotoPattern::SetPlaybackPeriod(int64_t startTime, int64_t endTime) +{ + TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto setPlaybackPeriod."); + if (startTime < VIDEO_PLAYTIME_START_POSITION || startTime >= endTime) { + TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MeidaPlayer SetAutoPlayPeriod error."); + return; + } + if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) { + TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is null or invalid."); + return; + } + TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto SetPlaybackPeriod."); + autoPlayPeriodStartTime_ = startTime; + autoPlayPeriodEndTime_ = endTime; + mediaPlayer_->SetPlayRangeUsWithMode(startTime, endTime, SeekMode::SEEK_CLOSEST); +} + +void MovingPhotoPattern::EnableAutoPlay(bool enabled) +{ + TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto enable AutoPlay : %{public}d.", enabled); + if (!enabled || autoAndRepeatLevel_ == PlaybackMode::REPEAT || !mediaPlayer_ || + !mediaPlayer_->IsMediaPlayerValid()) { + return; + } + if (currentPlayStatus_ == PlaybackStatus::PLAYBACK_COMPLETE || currentPlayStatus_ == PlaybackStatus::PAUSED) { + SetAutoPlayPeriod(autoPlayPeriodStartTime_, autoPlayPeriodEndTime_); + } + if (currentPlayStatus_ == PlaybackStatus::STARTED || !isPrepared_) { + TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto play status is STARTED or isPrepared is :%{public}d", + isPrepared_); + return; + } + historyAutoAndRepeatLevel_ = PlaybackMode::AUTO; + autoAndRepeatLevel_ = PlaybackMode::AUTO; + if (currentPlayStatus_ == PlaybackStatus::STOPPED) { + mediaPlayer_->PrepareAsync(); + } + TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto autoplay set success."); + isPlayByController_ = true; + isFastKeyUp_ = false; + Start(); +} + void MovingPhotoPattern::RefreshMovingPhoto() { TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto RefreshMovingPhoto start."); @@ -1593,6 +1821,7 @@ void MovingPhotoPattern::RefreshMovingPhotoSceneManager() void MovingPhotoPattern::StopAnimation() { + isStopAnimation_ = false; startAnimationFlag_ = false; if (historyAutoAndRepeatLevel_ == PlaybackMode::REPEAT) { StopAnimationCallback(); @@ -1638,7 +1867,7 @@ void MovingPhotoPattern::StopAnimation() void MovingPhotoPattern::StopAnimationCallback() { - if (historyAutoAndRepeatLevel_ == PlaybackMode::AUTO && autoPlayPeriodStartTime_ >= 0) { + if (autoPlayPeriodStartTime_ >= 0) { Seek(static_cast(autoPlayPeriodStartTime_ / US_CONVERT)); } else { Seek(0); @@ -2302,7 +2531,7 @@ bool MovingPhotoPattern::IsRefreshMovingPhotoReturn(bool status) return true; } } else { - if (autoAndRepeatLevel_ != PlaybackMode::NONE) { + if (autoAndRepeatLevel_ != PlaybackMode::NONE && !isStopAnimation_) { TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "IsRefreshMovingPhotoReturn not:%{public}d.", status); return true; } diff --git a/component_ext/movingphoto/movingphoto_pattern.h b/component_ext/movingphoto/movingphoto_pattern.h index 2efdf95c652e237a50f6ac5ab3eefb513e8118bd..592ae6f4a16a763d252c4ea0ebc9b52cdef3b43c 100644 --- a/component_ext/movingphoto/movingphoto_pattern.h +++ b/component_ext/movingphoto/movingphoto_pattern.h @@ -233,6 +233,7 @@ private: void FireMediaPlayerPause(); void FireMediaPlayerFinish(); void FireMediaPlayerError(); + void FireMediaPlayerPrepared(); void OnResolutionChange(); void OnStartRenderFrame(); void OnStartedStatusCallback(); @@ -252,6 +253,22 @@ private: void PausePlayback(); void RefreshMovingPhoto(); void RefreshMovingPhotoSceneManager(); + void PauseVideo(); + void ResetVideo(); + void RestartVideo(); + void SetEnableTransition(bool enabled); + bool GetEnableTransition(); + void SetPlaybackPeriod(int64_t startTime, int64_t endTime); + void EnableAutoPlay(bool enabled); + void SetStartPlaybackImpl(const SingleTaskExecutor& uiTaskExecutor); + void SetStopPlaybackImpl(const SingleTaskExecutor& uiTaskExecutor); + void SetRefreshMovingPhotoImpl(const SingleTaskExecutor& uiTaskExecutor); + void SetPauseImpl(const SingleTaskExecutor& uiTaskExecutor); + void SetResetImpl(const SingleTaskExecutor& uiTaskExecutor); + void SetRestartImpl(const SingleTaskExecutor& uiTaskExecutor); + void SetEnableTransitionImpl(const SingleTaskExecutor& uiTaskExecutor); + void SetPlaybackPeriodImpl(const SingleTaskExecutor& uiTaskExecutor); + void SetEnableAutoPlayImpl(const SingleTaskExecutor& uiTaskExecutor); void StopAnimation(); void StopAnimationCallback(); void StartAutoPlay(); @@ -304,6 +321,8 @@ private: bool isAutoChangePlayMode_ = false; bool needUpdateImageNode_ = false; bool isPlayWithMask_ = false; + bool isEnableTransition_ = true; + bool isStopAnimation_ = false; PlaybackStatus currentPlayStatus_ = PlaybackStatus::NONE; PlaybackMode autoAndRepeatLevel_ = PlaybackMode::NONE; PlaybackMode historyAutoAndRepeatLevel_ = PlaybackMode::NONE; diff --git a/component_ext/movingphoto/multimedia_movingphotoview.js b/component_ext/movingphoto/multimedia_movingphotoview.js index bc2e523f972f3adbdad16b210dd666d0fb42630e..b319cfe0f9b23a85a5774e6d7a3023e4af71e10c 100644 --- a/component_ext/movingphoto/multimedia_movingphotoview.js +++ b/component_ext/movingphoto/multimedia_movingphotoview.js @@ -70,6 +70,10 @@ class MovingPhotoView extends JSViewAbstract { static onError(value) { __MovingPhotoView__.onError(value); } + + static onPrepared(value) { + __MovingPhotoView__.onPrepared(value); + } static onClick(value) { __Common__.onClick(value); diff --git a/test/unittest/core/pattern/movingphoto/movingphoto_test_ng.cpp b/test/unittest/core/pattern/movingphoto/movingphoto_test_ng.cpp index 2a73354d830eddee155d42fa109d83c4ff36a181..e65d92f039d492c26da8fcfcfea05df6cb734732 100644 --- a/test/unittest/core/pattern/movingphoto/movingphoto_test_ng.cpp +++ b/test/unittest/core/pattern/movingphoto/movingphoto_test_ng.cpp @@ -172,7 +172,6 @@ HWTEST_F(MovingphotoTestNg, MovingPhotoPropertyTest002, TestSize.Level1) MovingPhotoModelNG movingphoto; auto movingPhotoController = AceType::MakeRefPtr(); movingphoto.Create(movingPhotoController); - auto frameNodeTemp = ViewStackProcessor::GetInstance()->GetMainFrameNode(); CHECK_NULL_VOID(frameNodeTemp); auto movingPhotoPatternTemp = AceType::DynamicCast(frameNodeTemp->GetPattern());