fix(ios): player rotation

This commit is contained in:
edde746
2025-12-03 11:14:59 +01:00
parent dff51ca888
commit 09860f81c8
5 changed files with 46 additions and 8 deletions
@@ -76,6 +76,9 @@ class MpvPlayerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, MpvPlayerD
case "isInitialized":
result(playerCore?.isInitialized ?? false)
case "updateFrame":
handleUpdateFrame(result: result)
default:
result(FlutterMethodNotImplemented)
}
@@ -198,6 +201,13 @@ class MpvPlayerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, MpvPlayerD
}
}
private func handleUpdateFrame(result: @escaping FlutterResult) {
DispatchQueue.main.async { [weak self] in
self?.playerCore?.updateFrame()
result(nil)
}
}
// MARK: - MpvPlayerDelegate
func onPropertyChange(name: String, value: Any?) {
+7
View File
@@ -178,6 +178,13 @@ abstract class Player {
/// controls are hidden. On other platforms, this is a no-op.
Future<void> setControlsVisible(bool visible);
/// Update the video frame/surface dimensions.
///
/// On iOS/macOS, this updates the Metal layer's frame to match the current
/// window size. Call this when the layout changes (e.g., device rotation).
/// On other platforms, this is a no-op.
Future<void> updateFrame();
// ============================================
// Lifecycle
// ============================================
+11
View File
@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:io' show Platform;
import 'package:flutter/services.dart';
@@ -491,6 +492,16 @@ class PlayerNative implements Player {
// No-op on most platforms. Override on Linux for transparency workaround.
}
@override
Future<void> updateFrame() async {
_checkDisposed();
if (!_initialized) return;
// Only iOS and macOS use Metal layer that needs frame updates
if (Platform.isIOS || Platform.isMacOS) {
await _methodChannel.invokeMethod('updateFrame');
}
}
// ============================================
// Lifecycle
// ============================================
+8 -8
View File
@@ -1184,14 +1184,14 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen>
constraints.maxHeight,
);
// Update player size in video filter manager
if (_videoFilterManager != null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
_videoFilterManager!.updatePlayerSize(newSize);
}
});
}
// Update player size in video filter manager and native layer
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted && player != null) {
_videoFilterManager?.updatePlayerSize(newSize);
// Update Metal layer frame on iOS/macOS for rotation
player!.updateFrame();
}
});
return Video(
player: player!,
@@ -76,6 +76,9 @@ class MpvPlayerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, MpvPlayerD
case "isInitialized":
result(playerCore?.isInitialized ?? false)
case "updateFrame":
handleUpdateFrame(result: result)
default:
result(FlutterMethodNotImplemented)
}
@@ -198,6 +201,13 @@ class MpvPlayerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, MpvPlayerD
}
}
private func handleUpdateFrame(result: @escaping FlutterResult) {
DispatchQueue.main.async { [weak self] in
self?.playerCore?.updateFrame()
result(nil)
}
}
// MARK: - MpvPlayerDelegate
func onPropertyChange(name: String, value: Any?) {