feat: use FlTextureGL for Linux mpv video rendering

This commit is contained in:
edde746
2026-02-17 08:55:29 +01:00
parent 544fccf82d
commit 2bc2c0a0ec
12 changed files with 376 additions and 436 deletions
+3 -6
View File
@@ -2,11 +2,8 @@ import '../player_native.dart';
/// Linux implementation of [Player].
///
/// Uses libmpv with OpenGL rendering via GtkGLArea.
/// The mpv video is rendered to a GtkGLArea positioned behind
/// the Flutter view using a GtkOverlay, with transparent regions
/// in the Flutter UI allowing the video to show through.
/// Uses libmpv with FlTextureGL — video is rendered to an offscreen FBO
/// and composited GPU-side via Flutter's Texture widget.
class PlayerLinux extends PlayerNative {
@override
int? get textureId => null; // Uses GtkGLArea, not Flutter texture
// textureId is set during initialize() via PlayerNative
}
+16 -4
View File
@@ -6,9 +6,15 @@ import '../font_loader.dart';
import '../models.dart';
import 'player_base.dart';
/// Shared native implementation of [Player] for iOS, macOS, and Android (MPV fallback).
/// Uses MPVKit via platform channels with Metal rendering (Apple) or native window (Android).
/// Shared native implementation of [Player] for iOS, macOS, Android (MPV fallback), and Linux.
/// Uses MPVKit via platform channels with Metal rendering (Apple), native window (Android),
/// or FlTextureGL (Linux).
class PlayerNative extends PlayerBase {
int? _textureIdValue;
@override
int? get textureId => _textureIdValue;
static const _methodChannel = MethodChannel('com.plezy/mpv_player');
static const _eventChannel = EventChannel('com.plezy/mpv_player/events');
@@ -32,8 +38,14 @@ class PlayerNative extends PlayerBase {
if (initialized) return;
try {
final result = await methodChannel.invokeMethod<bool>('initialize');
initialized = result == true;
final result = await methodChannel.invokeMethod<Object>('initialize');
if (result is int) {
// Linux: initialize returns the texture ID
_textureIdValue = result;
initialized = true;
} else {
initialized = result == true;
}
if (!initialized) {
throw Exception('Failed to initialize player');
}
+8 -1
View File
@@ -74,7 +74,14 @@ class _VideoState extends State<Video> {
}
Widget _buildVideoSurface() {
// For players that support video rect positioning (Windows, Linux),
// For players that use Flutter's texture pipeline (Linux FlTextureGL),
// render directly via the Texture widget.
final textureId = widget.player.textureId;
if (textureId != null) {
return Texture(textureId: textureId);
}
// For players that support video rect positioning (Windows),
// communicate layout changes to the native side.
if (widget.player is VideoRectSupport) {
return LayoutBuilder(