From 7f4e0d2b139d7411755c71588ab5ada4b1c38474 Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Sat, 20 Jun 2026 02:57:15 +0800 Subject: [PATCH] Support macOS video platform views --- .changes/macos-video-platform-view | 1 + lib/src/widgets/video_track_renderer.dart | 27 ++++++++++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) create mode 100644 .changes/macos-video-platform-view diff --git a/.changes/macos-video-platform-view b/.changes/macos-video-platform-view new file mode 100644 index 000000000..090f6c705 --- /dev/null +++ b/.changes/macos-video-platform-view @@ -0,0 +1 @@ +patch type="fixed" "Support platform video rendering on macOS" diff --git a/lib/src/widgets/video_track_renderer.dart b/lib/src/widgets/video_track_renderer.dart index 2457129e4..da8626feb 100644 --- a/lib/src/widgets/video_track_renderer.dart +++ b/lib/src/widgets/video_track_renderer.dart @@ -15,7 +15,7 @@ import 'dart:async'; import 'dart:math'; -import 'package:flutter/foundation.dart' show kIsWeb; +import 'package:flutter/foundation.dart' show ValueListenable, kIsWeb; import 'package:flutter/material.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc; @@ -101,9 +101,21 @@ class _VideoTrackRendererState extends State { // Used to compute visibility information late VideoTrackViewRegistration _viewRegistration; - Future _initializeRenderer() async { - if (lkPlatformIs(PlatformType.iOS) && widget.renderMode == VideoRenderMode.platformView) { - return Null as Future; + bool get _shouldUsePlatformView => + widget.renderMode == VideoRenderMode.platformView && + [PlatformType.iOS, PlatformType.macOS].contains(lkPlatform()); + + double? get _rendererAspectRatio { + final renderer = _renderer; + if (renderer != null && renderer is ValueListenable) { + return (renderer as ValueListenable).value.aspectRatio; + } + return null; + } + + Future _initializeRenderer() async { + if (_shouldUsePlatformView) { + return null; } if (_renderer == null) { _renderer = rtc.RTCVideoRenderer(); @@ -186,7 +198,7 @@ class _VideoTrackRendererState extends State { _renderer?.onResize = () { if (mounted) { setState(() { - _aspectRatio = (_renderer as rtc.RTCVideoRenderer?)?.videoValue.aspectRatio; + _aspectRatio = _rendererAspectRatio; }); } }; @@ -229,7 +241,7 @@ class _VideoTrackRendererState extends State { ); Widget _videoRendererView() { - if (lkPlatformIs(PlatformType.iOS) && widget.renderMode == VideoRenderMode.platformView) { + if (_shouldUsePlatformView) { return rtc.RTCVideoPlatFormView( mirror: _shouldMirror(), objectFit: widget.fit.toRTCType(), @@ -251,8 +263,7 @@ class _VideoTrackRendererState extends State { Widget _videoViewForNative() => FutureBuilder( future: _initializeRenderer(), builder: (context, snapshot) { - if ((snapshot.hasData && _renderer != null) || - (lkPlatformIs(PlatformType.iOS) && widget.renderMode == VideoRenderMode.platformView)) { + if ((snapshot.hasData && _renderer != null) || _shouldUsePlatformView) { return Builder( key: _viewRegistration.key, builder: (ctx) {