Skip to content

Conversation

@sheershtehri7
Copy link

@sheershtehri7 sheershtehri7 commented Jan 27, 2026

feat: Add Automatic Adaptive Bitrate (ABR) support for HLS/DASH streaming in Android and iOS.

Introduces a built-in AdaptiveBitrateManager to the core video_player package
and implements native support for Android and iOS. This allows the player
to dynamically switch video quality based on network conditions and
buffering events.

Key changes:

  • Core: Added AdaptiveBitrateManager to monitor buffering events and
    automatically adjust bandwidth limits.
  • Core: Exposed setBandwidthLimit(int bps) in VideoPlayerController
    to allow manual or automated quality capping.
  • Android: Migrated PlatformVideoView from SurfaceView to TextureView
    to handle seamless resolution switching during adaptive transitions
    without frame misalignment or surface recreation.
  • Android: Integrated DefaultTrackSelector with setMaxVideoBitrate
    to enforce bandwidth constraints in ExoPlayer.
  • Android: Added enhanced logging in ExoPlayerEventListener to track
    and report adaptive quality changes (e.g., 360p -> 1080p).
  • iOS: Leveraged preferredPeakBitRate in AVFoundation to support
    native ABR constraints.

For Reference - https://github.com/user-attachments/assets/b271adb2-7942-4b98-8234-fbbbbae6b850
HLS used - https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_ts/master.m3u8

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.

@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests or get an explicit test exemption before merging.

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. If you believe this PR qualifies for a test exemption, contact "@test-exemption-reviewer" in the #hackers channel in Discord (don't just cc them here, they won't see it!). The test exemption team is a small volunteer group, so all reviewers should feel empowered to ask for tests, without delegating that responsibility entirely to the test exemption group.

@google-cla
Copy link

google-cla bot commented Jan 27, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces automatic adaptive bitrate (ABR) streaming support for HLS/DASH in Android and iOS video players. It includes core changes to manage bandwidth limits, platform-specific implementations for Android (ExoPlayer) and iOS (AVFoundation), and updates to the video_player plugin. The changes involve adding a new AdaptiveBitrateManager class, modifying platform-specific code to support ABR, and updating the Pigeon messaging interface. I have provided comments to address potential issues and improve the code.

MediaSource.Factory getMediaSourceFactory(
Context context, DefaultHttpDataSource.Factory initialFactory) {
unstableUpdateDataSourceFactory(initialFactory, httpHeaders, userAgent);
unstableUpdateDataSourceFactory(initialFactory, httpHeaders, userAgent, assetUrl, streamingFormat);

Choose a reason for hiding this comment

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

medium

The method unstableUpdateDataSourceFactory is called before dataSourceFactory is initialized. It's better to pass the initialized dataSourceFactory to unstableUpdateDataSourceFactory.

Comment on lines +269 to +271
* @deprecated This method DISABLES adaptive bitrate streaming. Do not use.
* ExoPlayer's adaptive streaming is now enabled by default in the player creation.
*/

Choose a reason for hiding this comment

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

medium

This deprecation message should be more descriptive, explaining why the method is deprecated and what the alternative is.

Comment on lines +53 to +56
// ExoPlayer handles HLS adaptive bitrate resolution changes automatically.
// No need to recreate the surface - doing so causes frame misalignment issues.
// The MediaCodec decoder will seamlessly adapt to the new resolution.
}

Choose a reason for hiding this comment

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

medium

It's good that you're preventing surface recreation during resolution changes, but it's important to verify that the TextureView is indeed adapting correctly to the new dimensions. Consider adding a check or a log to confirm the TextureView's dimensions are updated after an adaptive streaming quality change.

Comment on lines +79 to +81
.setAllowVideoNonSeamlessAdaptiveness(true) // Allow quality switches even with brief buffering
.setAllowVideoMixedMimeTypeAdaptiveness(false) // Keep same codec for stability
.setAllowVideoMixedDecoderSupportAdaptiveness(true) // Allow decoder adaptiveness

Choose a reason for hiding this comment

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

medium

It's recommended to keep the same codec for stability during adaptive bitrate streaming. However, it's important to test that this configuration doesn't negatively impact playback in certain scenarios. Consider adding a comment explaining the rationale behind disabling mixed MIME type adaptiveness.

Comment on lines 73 to +76

@OptIn(markerClass = androidx.media3.common.util.UnstableApi.class)
@Override
public void onVideoSizeChanged(@NonNull VideoSize videoSize) {
android.util.Log.d("TextureListener",

Choose a reason for hiding this comment

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

medium

It's good that you're preventing re-initialization during resolution changes, but it's important to verify that the TextureView is indeed adapting correctly to the new dimensions. Consider adding a check or a log to confirm the TextureView's dimensions are updated after an adaptive streaming quality change.

@stuartmorgan-g
Copy link
Collaborator

Thanks for the contribution! You’ve checked boxes in the PR checklist above that are not reflected in this PR, so I’m assuming this is a work in progress and am marking it as a Draft. Please review the checklist, updating the PR as appropriate, and when the state of the PR as posted reflects the checklist please feel free to mark it as ready for review.

@stuartmorgan-g
Copy link
Collaborator

This will also need a design document before the code is reviewed, to get a review of the high-level approach. For instance, it appears that this is implementing some heuristic logic at the Dart level that's not part of any of the underlying players, and that will need design exploration to evaluate whether the plugin is the right place for logic that none of the underlying players provide.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants