Skip to content

Fix media opened bug#3252

Open
ne0rrmatrix wants to merge 5 commits into
CommunityToolkit:mainfrom
ne0rrmatrix:FixMediaOpenedBug
Open

Fix media opened bug#3252
ne0rrmatrix wants to merge 5 commits into
CommunityToolkit:mainfrom
ne0rrmatrix:FixMediaOpenedBug

Conversation

@ne0rrmatrix

Copy link
Copy Markdown
Member

Description of Change

Linked Issues

PR Checklist

  • Has a linked Issue, and the Issue has been approved(bug) or Championed (feature/proposal)
  • Has tests (if omitted, state reason in description)
  • Has samples (if omitted, state reason in description)
  • Rebased on top of main at time of PR
  • Changes adhere to coding standard
  • Documentation created or updated: https://github.com/MicrosoftDocs/CommunityToolkit/pulls

Additional information

This pull request refactors the Android MediaManager implementation for the MediaElement component, focusing on improving how playback state changes are handled and when media events are triggered. The changes streamline state management, ensure accurate notification of media events, and update the interface to better align with ExoPlayer's event model.

Playback State Handling Improvements:

  • Refactored playback state management by removing the old OnPlayerStateChanged implementation and introducing a new OnPlaybackStateChanged method that uses a switch expression for clarity and correctness. This ensures that MediaOpened is triggered only once when playback starts, and MediaEnded is called when playback stops.
  • Added a new OnPlayWhenReadyChanged implementation to update the MediaElement state to Playing or Paused based on the player's readiness, ensuring state transitions are handled more accurately.

Code Cleanup and Interface Updates:

  • Removed the previous empty OnPlayWhenReadyChanged method and added an empty OnPlayerStateChanged method to maintain interface compliance with IPlayerListener.
  • Introduced new constants for player states (e.g., idleState) and a hasMediaOpened flag to track whether the media has been opened, preventing duplicate event triggers.

Notification and Event Triggering Adjustments:

  • Updated PlatformUpdateSource to only call UpdateNotifications when source is set and the Android foreground service is enabled, removing the previous unconditional triggering of MediaOpened.

Split OnPlayerStateChanged into OnPlayWhenReadyChanged and OnPlaybackStateChanged for better alignment with ExoPlayer events. Added hasMediaOpened flag to ensure MediaOpened triggers only once. Improved state mapping, event triggering, and notification updates. Cleaned up obsolete methods and followed .NET MAUI Toolkit guidelines.
Update playback state check in OnPlaybackStateChanged

Changed the condition to trigger duration and position updates from checking for Playing state to checking if playbackState equals readyState. This ensures media properties are updated at the correct playback lifecycle event.
Copilot AI review requested due to automatic review settings June 24, 2026 14:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses Android MediaElement event/state timing by moving MediaOpened to align with ExoPlayer’s STATE_READY transition and refining when playback-state-related updates occur.

Changes:

  • Trigger MediaOpened from OnPlaybackStateChanged(STATE_READY) with a guard to prevent duplicate firing.
  • Add OnPlayWhenReadyChanged handling to reflect play/pause transitions after media is opened.
  • Avoid unconditional notification updates in PlatformUpdateSource, only updating when the Android foreground service is enabled.

Comment on lines +408 to +410
if (hasSetSource && isAndroidForegroundServiceEnabled)
{
if (Player.PlayerError is null)
{
MediaElement.MediaOpened();
}

if (isAndroidForegroundServiceEnabled)
{
UpdateNotifications();
}
UpdateNotifications();
Comment on lines +140 to +157
public void OnPlayWhenReadyChanged(bool playWhenReady, int reason)
{
if(!hasMediaOpened)
{
return;
}

if (playWhenReady)
{
MediaElement.CurrentStateChanged(MediaElementState.Playing);

}

else
{
MediaElement.CurrentStateChanged(MediaElementState.Paused);
}
}
Comment on lines +169 to +174
if (MediaElement.Source is null || Player is null)
{
return;
}

MediaElementState newState = MediaElement.CurrentState;
switch (playbackState)
MediaElementState newState = playbackState switch
Improve guard conditions in OnPlayWhenReadyChanged to check for nulls and playback state. Simplify state update logic with a ternary operator. Update idleState mapping in OnPlaybackStateChanged to return Stopped instead of None when appropriate.
Set hasMediaOpened to false at the start of PlatformUpdateSource() to ensure the flag accurately reflects the state when a new media source is set. This helps prevent incorrect media state handling during source changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Android MediaElement.MediaOpened is raised from Player.Prepare() instead of ExoPlayer STATE_READY, leading to unpredictable state transitions

2 participants