[video_player_android] Add adaptive bitrate streaming support#11323
[video_player_android] Add adaptive bitrate streaming support#11323sheershtehri7 wants to merge 1 commit intoflutter:mainfrom
Conversation
There was a problem hiding this comment.
Code Review
This pull request adds support for adaptive bitrate streaming on Android. The changes include implementing setBandwidthLimit, configuring ExoPlayer with AdaptiveTrackSelection.Factory and DefaultBandwidthMeter, and switching to TextureView for platform views to allow seamless resolution changes. The implementation is solid, but there is an opportunity to reduce code duplication in the ExoPlayer creation logic, which I've pointed out in a specific comment.
| () -> { | ||
| androidx.media3.exoplayer.trackselection.DefaultTrackSelector trackSelector = | ||
| new androidx.media3.exoplayer.trackselection.DefaultTrackSelector(context); | ||
| DefaultBandwidthMeter bandwidthMeter = | ||
| new DefaultBandwidthMeter.Builder(context) | ||
| .setInitialBitrateEstimate(1_000_000) | ||
| .build(); | ||
|
|
||
| // AdaptiveTrackSelection.Factory enables ABR: ExoPlayer selects | ||
| // video tracks based on measured network bandwidth. | ||
| DefaultTrackSelector trackSelector = | ||
| new DefaultTrackSelector( | ||
| context, new AdaptiveTrackSelection.Factory()); | ||
|
|
||
| trackSelector.setParameters( | ||
| trackSelector | ||
| .buildUponParameters() | ||
| .setAllowVideoNonSeamlessAdaptiveness(true) | ||
| .setAllowVideoMixedDecoderSupportAdaptiveness(true) | ||
| .setForceLowestBitrate(false) | ||
| .setForceHighestSupportedBitrate(false) | ||
| .build()); | ||
|
|
||
| ExoPlayer.Builder builder = | ||
| new ExoPlayer.Builder(context) | ||
| .setTrackSelector(trackSelector) | ||
| .setBandwidthMeter(bandwidthMeter) | ||
| .setMediaSourceFactory(asset.getMediaSourceFactory(context)); | ||
|
|
||
| return builder.build(); | ||
| }); |
There was a problem hiding this comment.
The ExoPlayer creation logic within this lambda is nearly identical to the logic in TextureVideoPlayer.create(). To avoid code duplication and improve maintainability, consider extracting this logic into a shared helper method.
For example, you could create a private static method, perhaps in the VideoPlayer base class, that builds and returns a configured ExoPlayer instance:
@UnstableApi
private static ExoPlayer createExoPlayerWithAbr(Context context, VideoAsset asset) {
// ... (setup for DefaultBandwidthMeter and DefaultTrackSelector)
ExoPlayer.Builder builder =
new ExoPlayer.Builder(context)
.setTrackSelector(trackSelector)
.setBandwidthMeter(bandwidthMeter)
.setMediaSourceFactory(asset.getMediaSourceFactory(context));
return builder.build();
}Then, both create methods could use this helper in their ExoPlayerProvider lambda: () -> createExoPlayerWithAbr(context, asset).
Implements setBandwidthLimit via ExoPlayer's DefaultTrackSelector.setMaxVideoBitrate(). Key changes: - Configures AdaptiveTrackSelection.Factory and DefaultBandwidthMeter for ABR - Switches PlatformVideoView from SurfaceView to TextureView for seamless resolution changes during quality transitions - Adds onVideoSizeChanged no-op to prevent re-initialization during ABR switches - Adds null-safety check for video format in PlatformViewExoPlayerEventListener Requires video_player_platform_interface ^6.7.0. Part of flutter/flutter#183941
00395a6 to
02fb3c0
Compare
|
Closing per #11322 (comment) |
Implements adaptive bitrate streaming support for the Android video player.
Changes
setBandwidthLimit— Implements the platform interface method via ExoPlayer'sDefaultTrackSelector.setMaxVideoBitrate(). Values <= 0 remove the cap (Integer.MAX_VALUE).AdaptiveTrackSelection.FactoryandDefaultBandwidthMeter(initial estimate 1 Mbps) for both texture and platform view modes, enabling ExoPlayer's built-in bandwidth-adaptive track selection.PlatformVideoView— Switches fromSurfaceViewtoTextureViewto support seamless resolution changes during quality transitions.SurfaceViewoperates on a separate window layer which can cause visual artifacts when the video resolution changes mid-playback during ABR.onVideoSizeChangedno-op — Added to bothTextureExoPlayerEventListenerandPlatformViewExoPlayerEventListenerto prevent re-initialization events during ABR quality switches.videoFormatinPlatformViewExoPlayerEventListener.sendInitialized()to handle cases where format is not yet available.Versioned as 2.10.0 — minor version bump. Requires
video_player_platform_interface ^6.7.0.Depends on PR #11322 (platform interface
setBandwidthLimit).Part of flutter/flutter#183941
AI Disclosure: This PR was developed with assistance from AI tools (GitHub Copilot / Claude). All code has been reviewed, tested, and validated by the author.
Pre-Review Checklist
[shared_preferences]///).Footnotes
Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩ ↩2