Skip to content

Commit 4e7328d

Browse files
authored
Support macOS video platform views (#1116)
## Summary - enable `VideoRenderMode.platformView` on macOS in `VideoTrackRenderer` - avoid texture-only resize assumptions by reading width/height from the shared video renderer interface - add a patch changeset for macOS platform video rendering support ## Validation - `flutter analyze --no-pub`
1 parent c3b2d91 commit 4e7328d

2 files changed

Lines changed: 21 additions & 9 deletions

File tree

.changes/macos-video-platform-view

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
patch type="fixed" "Support platform video rendering on macOS"

lib/src/widgets/video_track_renderer.dart

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import 'dart:async';
1616
import 'dart:math';
1717

18-
import 'package:flutter/foundation.dart' show kIsWeb;
18+
import 'package:flutter/foundation.dart' show ValueListenable, kIsWeb;
1919
import 'package:flutter/material.dart';
2020

2121
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
@@ -78,7 +78,7 @@ class VideoTrackRenderer extends StatefulWidget {
7878

7979
/// Placeholder builder to display while the track is loading.
8080
///
81-
/// On iOS, this has no effect when [renderMode] is [VideoRenderMode.platformView].
81+
/// On iOS and macOS, this has no effect when [renderMode] is [VideoRenderMode.platformView].
8282
final WidgetBuilder? placeholderBuilder;
8383

8484
const VideoTrackRenderer(
@@ -107,9 +107,21 @@ class _VideoTrackRendererState extends State<VideoTrackRenderer> {
107107
// Used to compute visibility information
108108
late VideoTrackViewRegistration _viewRegistration;
109109

110-
Future<rtc.VideoRenderer> _initializeRenderer() async {
111-
if (lkPlatformIs(PlatformType.iOS) && widget.renderMode == VideoRenderMode.platformView) {
112-
return Null as Future<rtc.VideoRenderer>;
110+
bool get _shouldUsePlatformView =>
111+
widget.renderMode == VideoRenderMode.platformView &&
112+
[PlatformType.iOS, PlatformType.macOS].contains(lkPlatform());
113+
114+
double? get _rendererAspectRatio {
115+
final renderer = _renderer;
116+
if (renderer != null && renderer is ValueListenable<rtc.RTCVideoValue>) {
117+
return (renderer as ValueListenable<rtc.RTCVideoValue>).value.aspectRatio;
118+
}
119+
return null;
120+
}
121+
122+
Future<rtc.VideoRenderer?> _initializeRenderer() async {
123+
if (_shouldUsePlatformView) {
124+
return null;
113125
}
114126
if (_renderer == null) {
115127
_renderer = rtc.RTCVideoRenderer();
@@ -192,7 +204,7 @@ class _VideoTrackRendererState extends State<VideoTrackRenderer> {
192204
_renderer?.onResize = () {
193205
if (mounted) {
194206
setState(() {
195-
_aspectRatio = (_renderer as rtc.RTCVideoRenderer?)?.videoValue.aspectRatio;
207+
_aspectRatio = _rendererAspectRatio;
196208
});
197209
}
198210
};
@@ -236,7 +248,7 @@ class _VideoTrackRendererState extends State<VideoTrackRenderer> {
236248
);
237249

238250
Widget _videoRendererView() {
239-
if (lkPlatformIs(PlatformType.iOS) && widget.renderMode == VideoRenderMode.platformView) {
251+
if (_shouldUsePlatformView) {
240252
return rtc.RTCVideoPlatFormView(
241253
mirror: _shouldMirror(),
242254
objectFit: widget.fit.toRTCType(),
@@ -259,8 +271,7 @@ class _VideoTrackRendererState extends State<VideoTrackRenderer> {
259271
Widget _videoViewForNative() => FutureBuilder(
260272
future: _initializeRenderer(),
261273
builder: (context, snapshot) {
262-
if ((snapshot.hasData && _renderer != null) ||
263-
(lkPlatformIs(PlatformType.iOS) && widget.renderMode == VideoRenderMode.platformView)) {
274+
if ((snapshot.hasData && _renderer != null) || _shouldUsePlatformView) {
264275
return Builder(
265276
key: _viewRegistration.key,
266277
builder: (ctx) {

0 commit comments

Comments
 (0)