[video_player_avplay] Add playerEngine option to select the native playback engine#1064
[video_player_avplay] Add playerEngine option to select the native playback engine#1064jackie099 wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a playerEngine option to VideoPlayerController.network to allow manual selection of the native playback engine (PlayerEngine.adaptiveStreaming or PlayerEngine.general), defaulting to PlayerEngine.auto for backward compatibility. The reviewer suggests exporting the PlayerEngine enum from video_player.dart so that users do not need to explicitly import the platform interface package.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| /// Selects which native playback engine drives the source. | ||
| /// | ||
| /// [PlayerEngine.auto] (the default) keeps the historical URI-based selection. | ||
| /// Use [PlayerEngine.adaptiveStreaming] or [PlayerEngine.general] to force an | ||
| /// engine when a source fails on the auto-selected one. Only for | ||
| /// [VideoPlayerController.network]. | ||
| final PlayerEngine playerEngine; |
There was a problem hiding this comment.
To make the new PlayerEngine enum easily accessible to users of the plugin, it should be exported from video_player.dart. Currently, video_player.dart does not export video_player_platform_interface.dart or its members, meaning users would have to explicitly import video_player_platform_interface.dart to use PlayerEngine.general or PlayerEngine.adaptiveStreaming.\n\nPlease add the following export at the top of packages/video_player_avplay/lib/video_player.dart:\ndart\nexport 'video_player_platform_interface.dart' show PlayerEngine;\n
There was a problem hiding this comment.
Thanks! I left PlayerEngine in the platform interface to match the package's existing convention — the sibling enums used in the same VideoPlayerController.network call (e.g. VideoFormat, the formatHint type) live in video_player_platform_interface.dart too and aren't re-exported, and the plugin's own example/lib/main.dart imports both libraries:
import 'package:video_player_avplay/video_player.dart';
import 'package:video_player_avplay/video_player_platform_interface.dart';Exporting only PlayerEngine would make it the one exception. If you'd prefer better ergonomics here, the consistent move would be to export 'video_player_platform_interface.dart'; so VideoFormat, DataSourceType, PlayerEngine, … are all reachable from video_player.dart — happy to add that to this PR or keep the current convention, whichever you'd prefer.
Replace the ad-hoc playerOptions {'playerType': 'mediaplayer'} map key with
the typed PlayerEngine.general option now exposed by the video_player_avplay
fork (proposed upstream in flutter-tizen/plugins#1064). Repin the git dep from
the old snapshot repo to jackie099/plugins@7ffc99f. Behavior is unchanged: our
localhost-proxy sources are still routed to the general-purpose (CAPI
MediaPlayer) engine, which prepares them where the adaptive-streaming engine
fails.
Motivation
video_player_avplaydrives playback with one of two native engines that have different capabilities — one specialized for adaptive streaming (DASH/HLS/Smooth Streaming) and DRM (PlusPlayer), and a general-purpose media engine (the CAPI MediaPlayer). TodayCreate()picks between them with a fixed heuristic (a URI beginning withhttpuses the adaptive-streaming engine, otherwise the general-purpose one), and an app has no way to override it.The two engines have real capability differences, and some sources the heuristic routes to the adaptive-streaming engine fail there while playing correctly on the general-purpose engine. A concrete, reproducible example: media served over a localhost reverse-proxy (a common technique to inject request headers the player would otherwise drop) is an
http://URI, so it is routed to the adaptive-streaming engine — which fails to prepare it (OnPrepareDonereturnsfalseatkTypeFinderReady) — whereas the exact same source prepares and plays fine on the general-purpose engine. There is currently no public escape hatch.Change
Adds an opt-in, typed
playerEngineparameter toVideoPlayerController.network:PlayerEngine.adaptiveStreaming— force the engine specialized for adaptive streaming / DRMPlayerEngine.general— force the general-purpose media enginePlayerEngine.auto(default) — the existing URI-based selectionThe choice names the capability the app needs, not an internal engine class, so it stays meaningful if the backing implementations ever change. It is carried to the native side through the existing
playerOptionsmap (aplayerEnginekey, read inCreate()with the sameflutter_common::GetValuehelper that already readsprebufferMode/startPosition) — so there is no pigeon /CreateMessagechange. Unknown values are logged (LOG_ERROR) and fall back to the default selection.Backward compatibility
Fully backward compatible. With
PlayerEngine.auto(the default), selection is byte-for-byte the current behavior (uri.substr(0, 4) == "http"→ adaptive-streaming engine, else general-purpose), and the wire format is unchanged — theplayerEnginekey is only added when the caller opts out ofauto. No existing call site changes.Usage
This selects the engine, not the content format: the general-purpose engine can still play adaptive content such as a DASH manifest.
Testing
Verified on a Samsung Tizen 9.0 TV:
PlayerEngine.auto, a URI beginning withhttpuses the adaptive-streaming engine andfile/ asset sources use the general-purpose engine, as before.PlayerEngine.generalforces the general-purpose engine for anhttp://(localhost-proxy) source that otherwise fails on the adaptive-streaming engine — it then prepares and plays.dart analyzeis clean; the added C++ follows the surrounding Google C++ style.Notes
playerEngineis only available onVideoPlayerController.network; other source types always use the general-purpose engine. The engine is fixed when the player is created and is not re-evaluated on restore.video_player'sVideoViewType(a small, typed platform-selection enum). If you'd prefer an even smaller diff, the same selection can be exposed purely as aplayerEnginestring key inplayerOptionswith no public Dart API addition — happy to switch to whichever shape you prefer.