diff --git a/dxaml/test/native/external/foundation/graphics/MediaPlayerElement/MediaPlayerElementTests.cpp b/dxaml/test/native/external/foundation/graphics/MediaPlayerElement/MediaPlayerElementTests.cpp index 6cda73737f..99d0117f7a 100644 --- a/dxaml/test/native/external/foundation/graphics/MediaPlayerElement/MediaPlayerElementTests.cpp +++ b/dxaml/test/native/external/foundation/graphics/MediaPlayerElement/MediaPlayerElementTests.cpp @@ -479,5 +479,156 @@ void MediaPlayerElementTests::ConfigureThenRemoveDefaultMediaPlayer() }); } +void MediaPlayerElementTests::PausesAndResumesMediaPlayerWhenRemovedFromTree() +{ + TestCleanupWrapper cleanup; + + auto playingEvent = std::make_shared(); + auto pausedEvent = std::make_shared(); + auto playbackStateChangedRegistration = CreateSafeEventRegistration(MediaPlaybackSession, PlaybackStateChanged); + xaml_controls::Grid^ root = nullptr; + xaml_controls::MediaPlayerElement^ mpe = nullptr; + MediaPlayer^ player = nullptr; + + RunOnUIThread([&]() + { + root = ref new xaml_controls::Grid(); + mpe = ref new xaml_controls::MediaPlayerElement(); + mpe->AutoPlay = true; + root->Children->Append(mpe); + TestServices::WindowHelper->WindowContent = root; + }); + TestServices::WindowHelper->WaitForIdle(); + + RunOnUIThread([&]() + { + player = mpe->MediaPlayer; + VERIFY_IS_NOT_NULL(player); + + playbackStateChangedRegistration.Attach( + player->PlaybackSession, + ref new wf::TypedEventHandler( + [&](MediaPlaybackSession^ session, Platform::Object^) + { + if (session->PlaybackState == MediaPlaybackState::Playing) + { + playingEvent->Set(); + } + else if (session->PlaybackState == MediaPlaybackState::Paused) + { + pausedEvent->Set(); + } + })); + + mpe->Source = ::Windows::Media::Core::MediaSource::CreateFromUri( + ref new Uri(GetResourcesPath() + L"testfile.wmv")); + }); + + playingEvent->WaitForDefault(); + + RunOnUIThread([&]() + { + VERIFY_ARE_EQUAL(MediaPlaybackState::Playing, player->PlaybackSession->PlaybackState); + root->Children->RemoveAt(0); + }); + + pausedEvent->WaitForDefault(); + + RunOnUIThread([&]() + { + VERIFY_ARE_EQUAL(MediaPlaybackState::Paused, player->PlaybackSession->PlaybackState); + VERIFY_ARE_EQUAL(player, mpe->MediaPlayer); + + playingEvent->Reset(); + root->Children->Append(mpe); + }); + + playingEvent->WaitForDefault(); + + RunOnUIThread([&]() + { + VERIFY_ARE_EQUAL(MediaPlaybackState::Playing, player->PlaybackSession->PlaybackState); + VERIFY_ARE_EQUAL(player, mpe->MediaPlayer); + }); +} + +void MediaPlayerElementTests::PausesMediaPlayerWhenWindowCloses() +{ + auto playingEvent = std::make_shared(); + auto pausedEvent = std::make_shared(); + auto playbackStateChangedRegistration = CreateSafeEventRegistration(MediaPlaybackSession, PlaybackStateChanged); + Window^ window = nullptr; + xaml_controls::MediaPlayerElement^ mpe = nullptr; + MediaPlayer^ player = nullptr; + bool windowIsOpen = false; + + TestCleanupWrapper cleanup([&]() + { + if (windowIsOpen) + { + RunOnUIThread([&]() + { + window->Close(); + windowIsOpen = false; + window = nullptr; + mpe = nullptr; + player = nullptr; + }); + } + }); + + RunOnUIThread([&]() + { + window = ref new Window(); + mpe = ref new xaml_controls::MediaPlayerElement(); + mpe->AutoPlay = true; + window->Content = mpe; + window->Activate(); + windowIsOpen = true; + }); + TestServices::WindowHelper->WaitForIdle(); + + RunOnUIThread([&]() + { + player = mpe->MediaPlayer; + VERIFY_IS_NOT_NULL(player); + + playbackStateChangedRegistration.Attach( + player->PlaybackSession, + ref new wf::TypedEventHandler( + [&](MediaPlaybackSession^ session, Platform::Object^) + { + if (session->PlaybackState == MediaPlaybackState::Playing) + { + playingEvent->Set(); + } + else if (session->PlaybackState == MediaPlaybackState::Paused) + { + pausedEvent->Set(); + } + })); + + mpe->Source = ::Windows::Media::Core::MediaSource::CreateFromUri( + ref new Uri(GetResourcesPath() + L"testfile.wmv")); + }); + + playingEvent->WaitForDefault(); + + RunOnUIThread([&]() + { + VERIFY_ARE_EQUAL(MediaPlaybackState::Playing, player->PlaybackSession->PlaybackState); + window->Close(); + windowIsOpen = false; + }); + + pausedEvent->WaitForDefault(); + + RunOnUIThread([&]() + { + VERIFY_ARE_EQUAL(MediaPlaybackState::Paused, player->PlaybackSession->PlaybackState); + VERIFY_ARE_EQUAL(player, mpe->MediaPlayer); + }); +} + } } } } } } } diff --git a/dxaml/test/native/external/foundation/graphics/MediaPlayerElement/MediaPlayerElementTests.h b/dxaml/test/native/external/foundation/graphics/MediaPlayerElement/MediaPlayerElementTests.h index 290563ed1d..3d42827ee5 100644 --- a/dxaml/test/native/external/foundation/graphics/MediaPlayerElement/MediaPlayerElementTests.h +++ b/dxaml/test/native/external/foundation/graphics/MediaPlayerElement/MediaPlayerElementTests.h @@ -40,6 +40,12 @@ namespace Microsoft { namespace UI { namespace Xaml { namespace Tests { BEGIN_TEST_METHOD(ConfigureThenRemoveDefaultMediaPlayer) END_TEST_METHOD() + BEGIN_TEST_METHOD(PausesAndResumesMediaPlayerWhenRemovedFromTree) + END_TEST_METHOD() + + BEGIN_TEST_METHOD(PausesMediaPlayerWhenWindowCloses) + END_TEST_METHOD() + BEGIN_TEST_METHOD(ParseSourceUri) TEST_METHOD_PROPERTY(L"Hosting:Mode", L"WPF") END_TEST_METHOD() @@ -66,4 +72,3 @@ namespace Microsoft { namespace UI { namespace Xaml { namespace Tests { } } } } } } } - diff --git a/dxaml/xcp/dxaml/lib/MediaPlayerElement_partial.cpp b/dxaml/xcp/dxaml/lib/MediaPlayerElement_partial.cpp index d8b6f06797..33a20bbef3 100644 --- a/dxaml/xcp/dxaml/lib/MediaPlayerElement_partial.cpp +++ b/dxaml/xcp/dxaml/lib/MediaPlayerElement_partial.cpp @@ -264,6 +264,7 @@ MediaPlayerElement::OnPropertyChanged2(_In_ const PropertyChangedParams& args) if (args.m_pDP->GetIndex() == KnownPropertyIndex::MediaPlayerElement_MediaPlayer) { IFC_RETURN(get_MediaPlayer(&m_spMediaPlayer)); + m_resumeMediaPlayerOnEnter = false; IFC_RETURN(UpdateTransportControlsState()); IFC_RETURN(UpdateAutoPlay()); IFC_RETURN(UpdateSource()); @@ -700,6 +701,12 @@ MediaPlayerElement::EnterImpl( { IFC_RETURN(UpdateAutoPlay()); + if (m_resumeMediaPlayerOnEnter && m_spMediaPlayer) + { + m_resumeMediaPlayerOnEnter = false; + LOG_IF_FAILED(m_spMediaPlayer->Play()); + } + IFC_RETURN(UpdateTimedTextSource()); } @@ -721,8 +728,49 @@ MediaPlayerElement::LeaveImpl( IFC_RETURN(m_spTimedTextSource->SetMediaPlayer(nullptr)); } + bool shouldPauseMediaPlayer = bLive && !bVisualTreeBeingReset; + if (bLive && bVisualTreeBeingReset) + { + if (CContentRoot* contentRoot = VisualTree::GetContentRootForElement(GetHandle())) + { + shouldPauseMediaPlayer = contentRoot->IsShuttingDown(); + } + } + IFC_RETURN(__super::LeaveImpl(bLive, bSkipNameRegistration, bCoercedIsEnabled, bVisualTreeBeingReset)); + if (shouldPauseMediaPlayer && m_spMediaPlayer && !m_resumeMediaPlayerOnEnter) + { + ctl::ComPtr spMediaPlayer3; + ctl::ComPtr spPlaybackSession; + wmp::MediaPlaybackState playbackState{}; + + HRESULT stateResult = m_spMediaPlayer.As(&spMediaPlayer3); + if (SUCCEEDED(stateResult)) + { + stateResult = spMediaPlayer3->get_PlaybackSession(&spPlaybackSession); + } + if (SUCCEEDED(stateResult) && spPlaybackSession) + { + stateResult = spPlaybackSession->get_PlaybackState(&playbackState); + } + else if (SUCCEEDED(stateResult)) + { + stateResult = E_UNEXPECTED; + } + + if (SUCCEEDED(stateResult) && + (playbackState == wmp::MediaPlaybackState_Playing || + playbackState == wmp::MediaPlaybackState_Buffering)) + { + const HRESULT pauseResult = m_spMediaPlayer->Pause(); + if (SUCCEEDED(pauseResult)) + { + m_resumeMediaPlayerOnEnter = true; + } + } + } + return S_OK; } diff --git a/dxaml/xcp/dxaml/lib/MediaPlayerElement_partial.h b/dxaml/xcp/dxaml/lib/MediaPlayerElement_partial.h index b20e11feda..da73177ca9 100644 --- a/dxaml/xcp/dxaml/lib/MediaPlayerElement_partial.h +++ b/dxaml/xcp/dxaml/lib/MediaPlayerElement_partial.h @@ -121,5 +121,6 @@ namespace DirectUI ctl::ComPtr m_spMediaPlayer; ctl::ComPtr m_spTimedTextSource; bool m_bInit; + bool m_resumeMediaPlayerOnEnter{ false }; }; }