Pause MediaPlayerElement when leaving the live tree - #11670
Pause MediaPlayerElement when leaving the live tree#11670Hemant Kumar (Hemantxk) wants to merge 5 commits into
Conversation
Pause a playing MediaPlayer when its element leaves the live tree and resume only when that element initiated the pause. Cover remove/re-entry and retained Window-close lifecycles. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a3043399-4002-4d60-b928-b71920a36bf0
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Pause only when the element leaves because its ContentRoot is shutting down. Remove resume state and retain focused Window-close coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a3043399-4002-4d60-b928-b71920a36bf0
Keep a source token after the final event macro expansion without retaining the temporary undef directives. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a3043399-4002-4d60-b928-b71920a36bf0
Pause playing media on live-tree leave and resume when the same element re-enters after initiating that pause. Restore both focused lifecycle tests. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a3043399-4002-4d60-b928-b71920a36bf0
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
/azp run |
|
Azure Pipelines: 1 pipeline(s) were filtered out due to trigger conditions. |
Preserve the original trailing blank line after the final event macro expansion. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: a3043399-4002-4d60-b928-b71920a36bf0
|
/azp run |
|
Azure Pipelines: 1 pipeline(s) were filtered out due to trigger conditions. |
| IFC_RETURN(m_spTimedTextSource->SetMediaPlayer(nullptr)); | ||
| } | ||
|
|
||
| bool shouldPauseMediaPlayer = bLive && !bVisualTreeBeingReset; |
There was a problem hiding this comment.
shouldPauseMediaPlayer = bLive && !bVisualTreeBeingReset means we pause on every ordinary removal from the live tree, not just on a window close - Frame navigation, ListView/ItemsRepeater container recycling, TabView content swap, re-parenting and Popup close all take this path. The linked bug is scoped to a terminal close, so we may have to consult IsShuttingDown() on both branches rather than treating !bVisualTreeBeingReset as sufficient. Please check whether the non-reset path should be pausing at all.
|
|
||
| IFC_RETURN(__super::LeaveImpl(bLive, bSkipNameRegistration, bCoercedIsEnabled, bVisualTreeBeingReset)); | ||
|
|
||
| if (shouldPauseMediaPlayer && m_spMediaPlayer && !m_resumeMediaPlayerOnEnter) |
There was a problem hiding this comment.
Since e88e20cc removed m_bOwnsMediaPlayer there is no ownership signal left on the class, so this also pauses app-supplied players and players shared with a second MediaPlayerElement that is still live and on screen. SharedMediaPlayerSurvivesElementDestruction only pins the destruction path, so a shared player being paused by whichever element leaves first would not be caught. Please check whether we need a framework-created-player signal before mutating transport state here.
| { | ||
| IFC_RETURN(UpdateAutoPlay()); | ||
|
|
||
| if (m_resumeMediaPlayerOnEnter && m_spMediaPlayer) |
There was a problem hiding this comment.
m_resumeMediaPlayerOnEnter is only cleared at line 267 for the MediaPlayer property and here at 706, so a Source change while the element is detached leaves it set and we force a Play() on the newly bound content on re-entry - that is the recycled container case for ListView and ItemsRepeater. It also bypasses AutoPlay="False", since UpdateAutoPlay() runs just before this, and it reverses a Pause() the app or user performed while we were out of the tree. Please check whether we should clear the flag in the Source case too, and re-read PlaybackState before resuming.
| bool shouldPauseMediaPlayer = bLive && !bVisualTreeBeingReset; | ||
| if (bLive && bVisualTreeBeingReset) | ||
| { | ||
| if (CContentRoot* contentRoot = VisualTree::GetContentRootForElement(GetHandle())) |
There was a problem hiding this comment.
If GetContentRootForElement returns null here we fall through with shouldPauseMediaPlayer still false from line 731, so the one branch that actually implements the fix quietly does nothing and the bug reproduces with no assert or trace to explain why. Please check whether treating an unresolved content root as shutting down would be the safer default on a path we already know is a tree reset.
Fixes
Related work item: ADO Bug 40049143
PR Type
Description
Current Behavior
When a
Windowcontaining a playingMediaPlayerElementis closed, its visual tree is torn down. If the app still retains the closedWindoworMediaPlayerElement, the underlyingMediaPlayeralso remains alive and keeps playing. The video surface disappears with the Window, but its audio continues in the background.New Behavior
When
MediaPlayerElementleaves the live visual tree:MediaPlayeris paused.ContentRootis shutting down.MediaPlayerclears the pending resume state.LOG_IF_FAILEDwithout failing tree entry.Customer Impact
Closing or removing playback UI no longer leaves invisible media continuing in the background. If the same element is temporarily removed and later reattached, its previous playback continues automatically only when the element caused the pause.
There is no public API change.
Regression Potential
The change is limited to live-tree leave/re-entry handling. It pauses only a player that is currently playing or buffering, skips transient tree resets, and resumes only after a successful framework-initiated pause.
How Has This Been Tested?
Focused WPF TAEF tests:
PausesAndResumesMediaPlayerWhenRemovedFromTree— passedPausesMediaPlayerWhenWindowCloses— passedResult: 2 passed, 0 failed, 0 blocked.
Manual retained-Window validation confirmed that closing the playback Window stops its audio while the Window remains retained. Collapsing only the element's visibility continues playback, as expected, because it remains in the live tree.
This commit restores the behavior covered by those passing tests. The latest
amd64freMicrosoft.ui.xaml.vcxprojbuild completed with 0 warnings and 0 errors. Per request, the tests were not rerun.Screenshots (if appropriate)
N/A — this is a playback lifecycle behavior change with no visual UI change.