@@ -48,12 +48,14 @@ class VideoTrackRenderer extends StatefulWidget {
4848 final rtc.RTCVideoViewObjectFit fit;
4949 final VideoViewMirrorMode mirrorMode;
5050 final VideoRenderMode renderMode;
51+ final bool preferFixHeight;
5152
5253 const VideoTrackRenderer (
5354 this .track, {
5455 this .fit = rtc.RTCVideoViewObjectFit .RTCVideoViewObjectFitContain ,
5556 this .mirrorMode = VideoViewMirrorMode .auto,
5657 this .renderMode = VideoRenderMode .texture,
58+ this .preferFixHeight = true ,
5759 Key ? key,
5860 }) : super (key: key);
5961
@@ -65,6 +67,7 @@ class _VideoTrackRendererState extends State<VideoTrackRenderer> {
6567 rtc.VideoRenderer ? _renderer;
6668 // for flutter web only.
6769 bool _rendererReadyForWeb = false ;
70+ double ? _aspectRatio;
6871 EventsListener <TrackEvent >? _listener;
6972 // Used to compute visibility information
7073 late GlobalKey _internalKey;
@@ -100,6 +103,7 @@ class _VideoTrackRendererState extends State<VideoTrackRenderer> {
100103
101104 void disposeRenderer () {
102105 try {
106+ _renderer? .onResize = null ;
103107 _renderer? .srcObject = null ;
104108 _renderer? .dispose ();
105109 _renderer = null ;
@@ -141,6 +145,13 @@ class _VideoTrackRendererState extends State<VideoTrackRenderer> {
141145 // force recompute of mirror mode
142146 setState (() {});
143147 });
148+ _renderer? .onResize = () {
149+ if (mounted) {
150+ setState (() {
151+ _aspectRatio = _renderer? .videoValue.aspectRatio;
152+ });
153+ }
154+ };
144155 }
145156
146157 @override
@@ -216,22 +227,43 @@ class _VideoTrackRendererState extends State<VideoTrackRenderer> {
216227 widget.track.onVideoViewBuild? .call (_internalKey);
217228 });
218229
219- if (! lkPlatformIsMobile () || widget.track is ! LocalVideoTrack ) {
220- return _videoRendererView ();
221- }
222230 return LayoutBuilder (
223231 builder: (BuildContext context, BoxConstraints constraints) {
224- return GestureDetector (
225- onScaleStart: (details) {},
226- onScaleUpdate: (details) {
227- if (details.scale != 1.0 ) {
228- setZoom (details.scale);
229- }
230- },
231- onTapDown: (TapDownDetails details) =>
232- onViewFinderTap (details, constraints),
233- child: _videoRendererView (),
234- );
232+ final bool fixHeight = (widget.preferFixHeight &&
233+ constraints.hasBoundedHeight) ||
234+ ! constraints.hasBoundedWidth;
235+ final Widget child;
236+ if (! lkPlatformIsMobile () ||
237+ widget.track is ! LocalVideoTrack ) {
238+ child = _videoRendererView ();
239+ } else {
240+ child = GestureDetector (
241+ onScaleStart: (details) {},
242+ onScaleUpdate: (details) {
243+ if (details.scale != 1.0 ) {
244+ setZoom (details.scale);
245+ }
246+ },
247+ onTapDown: (TapDownDetails details) =>
248+ onViewFinderTap (details, constraints),
249+ child: _videoRendererView (),
250+ );
251+ }
252+ final double ? aspectRatio = _aspectRatio;
253+ final double width;
254+ final double height;
255+ if (aspectRatio != null ) {
256+ if (fixHeight) {
257+ height = constraints.maxHeight;
258+ width = height * aspectRatio;
259+ } else {
260+ width = constraints.maxWidth;
261+ height = width / aspectRatio;
262+ }
263+ return SizedBox (width: width, height: height, child: child);
264+ } else {
265+ return child;
266+ }
235267 },
236268 );
237269 },
0 commit comments