Skip to content

[video_player_avplay] Add playerEngine option to select the native playback engine#1064

Open
jackie099 wants to merge 2 commits into
flutter-tizen:masterfrom
jackie099:feat/avplay-player-engine-option
Open

[video_player_avplay] Add playerEngine option to select the native playback engine#1064
jackie099 wants to merge 2 commits into
flutter-tizen:masterfrom
jackie099:feat/avplay-player-engine-option

Conversation

@jackie099

Copy link
Copy Markdown

Motivation

video_player_avplay drives 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). Today Create() picks between them with a fixed heuristic (a URI beginning with http uses 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 (OnPrepareDone returns false at kTypeFinderReady) — 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 playerEngine parameter to VideoPlayerController.network:

enum PlayerEngine { auto, adaptiveStreaming, general }
  • PlayerEngine.adaptiveStreaming — force the engine specialized for adaptive streaming / DRM
  • PlayerEngine.general — force the general-purpose media engine
  • PlayerEngine.auto (default) — the existing URI-based selection

The 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 playerOptions map (a playerEngine key, read in Create() with the same flutter_common::GetValue helper that already reads prebufferMode / startPosition) — so there is no pigeon / CreateMessage change. 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 — the playerEngine key is only added when the caller opts out of auto. No existing call site changes.

Usage

VideoPlayerController.network(
  url,
  playerEngine: PlayerEngine.general, // or PlayerEngine.adaptiveStreaming
);

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:

  • With PlayerEngine.auto, a URI beginning with http uses the adaptive-streaming engine and file / asset sources use the general-purpose engine, as before.
  • PlayerEngine.general forces the general-purpose engine for an http:// (localhost-proxy) source that otherwise fails on the adaptive-streaming engine — it then prepares and plays.

dart analyze is clean; the added C++ follows the surrounding Google C++ style.

Notes

  • playerEngine is only available on VideoPlayerController.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.
  • The typed enum mirrors first-party video_player's VideoViewType (a small, typed platform-selection enum). If you'd prefer an even smaller diff, the same selection can be exposed purely as a playerEngine string key in playerOptions with no public Dart API addition — happy to switch to whichever shape you prefer.

@gemini-code-assist gemini-code-assist Bot 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.

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.

Comment on lines +464 to +470
/// 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;

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.

medium

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

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

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.

jackie099 added a commit to jackie099/PiliPlus-Tizen that referenced this pull request Jul 14, 2026
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.
@JSUYA JSUYA requested review from gin7773 and xiaowei-guan July 15, 2026 00:32
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.

1 participant