Skip to content

[video_player] : Add video track selection support for Android and iOS#10688

Open
nateshmbhat wants to merge 132 commits intoflutter:mainfrom
nateshmbhat:feature/video-track-selection-v2
Open

[video_player] : Add video track selection support for Android and iOS#10688
nateshmbhat wants to merge 132 commits intoflutter:mainfrom
nateshmbhat:feature/video-track-selection-v2

Conversation

@nateshmbhat
Copy link
Contributor

@nateshmbhat nateshmbhat commented Dec 27, 2025

This PR adds video track selection (quality switching) support to the video_player plugin for Android and iOS platforms. This allows users to programmatically get available video quality variants and select a specific quality track, similar to the existing audio track selection feature.

Addresses issue : flutter/flutter#58854

Pre-Review Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] page, which explains my responsibilities.
  • I read and followed the [relevant style guides] and ran [the auto-formatter].
  • I signed the [CLA].
  • The title of the PR starts with the name of the package surrounded by square brackets, e.g. [shared_preferences]
  • I [linked to at least one issue that this PR fixes] in the description above.
  • I updated pubspec.yaml with an appropriate new version according to the [pub versioning philosophy], or I have commented below to indicate which [version change exemption] this PR falls under[^1].
  • I updated CHANGELOG.md to add a description of the change, [following repository CHANGELOG style], or I have commented below to indicate which [CHANGELOG exemption] this PR falls under[^1].
  • I updated/added any relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or I have commented below to indicate which [test exemption] this PR falls under[^1].
  • All existing and new tests are passing.

feat(video_player): add platform check for audio track selection support
Copy link
Contributor

@camsim99 camsim99 left a comment

Choose a reason for hiding this comment

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

Android overall LGTM just have one question about how we force a video player re-render after selecting a new track.

// position (e.g., top-left corner) or the old surface remains partially visible.
// By disabling the video track type, we force ExoPlayer to completely release the
// current renderer and decoder, ensuring a clean slate for the new resolution.
if (dimensionsChanged) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This disabling/re-enabling hack make sense thanks to your explanation. However, I just want to make sure there's no more direct way to force a re-render. Is there some documentation that we can point to as to why we are handling it this way?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated with relevant details

Copy link
Contributor

Choose a reason for hiding this comment

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

Those links don't clearly state why we need this approach. I did a little digging and found this Exoplayer issue that does seem relevant though: androidx/media#1631. My read on those issues is that the seamless changing of tracks with different formats is currently not supported and their suggested workaround is to disallow that, but please correct me if I'm wrong.

Unless we can find evidence for this solution of disabling/re-enabling the video track type with a delay being reliable, I would suggest that we move in that direction versus implementing a hack. For now, then, we could file an issue for supporting this in the future and follow up in the Exoplayer bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The thing is, during my testing I was actually facing the visual glitches and that's why I had implement this approach after digging around for solutions.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think instead of landing this initially with a hack to support this on Android, we should not allow the switching of media formats for now and file an issue to follow up on that. Then a fix for the issue could potentially land as a follow up PR. I'm open to pushback, but I think we should invest in finding a reliable solution for this issue if possible. We can follow up in the ExoPlayer bug I linked, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor

Choose a reason for hiding this comment

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

@nateshmbhat Thanks for the explanation! Ultimately, your logic as to keeping the workaround in makes sense to me and I'm okay moving forward.

If you don't mind, can you file an issue for the todo and link it here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done , added here flutter/flutter#183824

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you! And sorry for being unclear but can you link it in the todo?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done :) ✨

nateshmbhat and others added 5 commits February 16, 2026 07:53
…or handling

- Added a new method `enableAutoVideoQuality` to replace the previous method of selecting video tracks with -1 indices for auto quality.
- Updated the Android implementation to utilize this new method, enhancing clarity and maintainability.
- Introduced helper methods in `VideoPlayer.java` to streamline the extraction of format values, improving code readability.
- Adjusted test cases to reflect the new method naming and functionality.
- Cleaned up imports and formatting across various files for consistency.
@nateshmbhat nateshmbhat requested a review from camsim99 February 18, 2026 10:21
@stuartmorgan-g
Copy link
Collaborator

@tarrinneal I believe this still needs your review for the cross-platform parts.

Copy link
Contributor

@tarrinneal tarrinneal left a comment

Choose a reason for hiding this comment

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

Seems like the non-platform code is pretty solid. I didn't review the platform code in depth, but I didn't see anything glaringly wrong there either.

// position (e.g., top-left corner) or the old surface remains partially visible.
// By disabling the video track type, we force ExoPlayer to completely release the
// current renderer and decoder, ensuring a clean slate for the new resolution.
if (dimensionsChanged) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should leave a TODO: for these at least. Hopefully this workaround won't be necessary forever.

Comment on lines +998 to +999
/// For non-adaptive videos (MP4, MOV, etc.), this returns an empty list
/// as they have a single fixed quality that cannot be switched.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this always true? Could a non-adaptive video send a single track? I think it's possible in the platform implementations

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch. I double-checked this and the previous wording was too narrow, so I updated it.

My read from the platform docs is that for non-adaptive video we can’t safely assume only “a single track or an empty list”:

On Android/Media3, a TrackGroup represents tracks with the same content in different formats, and the track selection docs/API also allow for multiple video groups such as alternate video feeds/camera angles:
Track selection guide
TrackGroup API
On Apple’s AVFoundation side, their docs note that a simple asset may have one video track, but more complex assets/compositions can have multiple video tracks:
Time and Media Representations
About AVFoundation
So I changed the doc to say that for non-adaptive videos, platform implementations may return one or more tracks, or an empty list, depending on the media and the metadata available.

@nateshmbhat nateshmbhat requested a review from tarrinneal March 11, 2026 15:24
…workaround (#3)

flutter/flutter#183824

Co-authored-by: Claude <noreply@anthropic.com>
Copy link
Contributor

@camsim99 camsim99 left a comment

Choose a reason for hiding this comment

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

Android LGTM!

@nateshmbhat
Copy link
Contributor Author

nateshmbhat commented Mar 19, 2026

@stuartmorgan-g are we good to create breakout PRs ?

@priyankj-simform
Copy link

Hi, any update on when these changes will be merged?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

federated: all_changes PR that contains changes for all packages for a federated plugin change p: video_player platform-android platform-ios platform-macos platform-web triage-android Should be looked at in Android triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants