Skip to content

fix: tighten VideoTrackRenderer Widget #695

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
f3dcc44
fix: tighten VideoTrackRenderer Widget
holzgeist Jan 22, 2025
b4bde00
fix: get rid of manual selection which side to fix
holzgeist Jan 29, 2025
38a5078
chore: revert formatting change
holzgeist Jan 29, 2025
32b8b0a
fix: don't wrap video in cover mode
holzgeist Feb 10, 2025
476fec9
chore: upgrade lock file to make tests pass
holzgeist Feb 10, 2025
bc5cc16
Merge remote-tracking branch 'upstream/main' into video-size-constraint
holzgeist Mar 5, 2025
170783a
Merge tag 'v2.4.1' into video-size-constraint
holzgeist Apr 1, 2025
9c6c0fa
Merge branch 'livekit:main' into video-size-constraint
holzgeist Apr 3, 2025
4e80653
Merge branch 'livekit:main' into video-size-constraint
holzgeist Apr 7, 2025
b97f139
Merge branch 'livekit:main' into video-size-constraint
holzgeist Apr 10, 2025
8042559
Merge branch 'livekit:main' into video-size-constraint
holzgeist Apr 14, 2025
446cac5
Merge branch 'livekit:main' into video-size-constraint
holzgeist Apr 16, 2025
8daa6b0
Merge branch 'livekit:main' into video-size-constraint
holzgeist Apr 22, 2025
c3c7f4d
chore: adjust to new interface
holzgeist May 8, 2025
4b9167e
Merge remote-tracking branch 'origin/main' into video-size-constraint
holzgeist May 8, 2025
2654492
Merge remote-tracking branch 'origin/main' into video-size-constraint
holzgeist Jul 1, 2025
57520f0
fix: add autoCenter parameter for backward compatibility
holzgeist Jul 1, 2025
2dace6b
Merge remote-tracking branch 'upstream/main' into video-size-constraint
holzgeist Jul 2, 2025
47bb716
chore: fix flutter analyze, improve doc comment
holzgeist Jul 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 60 additions & 2 deletions lib/src/widgets/video_track_renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,17 @@ class VideoTrackRenderer extends StatefulWidget {
final rtc.RTCVideoRenderer? cachedRenderer;
final bool autoDisposeRenderer;

/// wrap the video view in a Center widget (if [fit] is [VideoViewFit.contain])
final bool autoCenter;

const VideoTrackRenderer(
this.track, {
this.fit = VideoViewFit.contain,
this.mirrorMode = VideoViewMirrorMode.auto,
this.renderMode = VideoRenderMode.texture,
this.autoDisposeRenderer = true,
this.cachedRenderer,
this.autoCenter = true,
Key? key,
}) : super(key: key);

Expand All @@ -83,6 +87,7 @@ class _VideoTrackRendererState extends State<VideoTrackRenderer> {
rtc.VideoRenderer? _renderer;
// for flutter web only.
bool _rendererReadyForWeb = false;
double? _aspectRatio;
EventsListener<TrackEvent>? _listener;
// Used to compute visibility information
late GlobalKey _internalKey;
Expand Down Expand Up @@ -121,6 +126,7 @@ class _VideoTrackRendererState extends State<VideoTrackRenderer> {

void disposeRenderer() {
try {
_renderer?.onResize = null;
_renderer?.srcObject = null;
_renderer?.dispose();
_renderer = null;
Expand Down Expand Up @@ -167,6 +173,14 @@ class _VideoTrackRendererState extends State<VideoTrackRenderer> {
// force recompute of mirror mode
setState(() {});
});
_renderer?.onResize = () {
if (mounted) {
setState(() {
_aspectRatio =
(_renderer as rtc.RTCVideoRenderer?)?.videoValue.aspectRatio;
});
}
};
}

@override
Expand Down Expand Up @@ -268,8 +282,52 @@ class _VideoTrackRendererState extends State<VideoTrackRenderer> {
// FutureBuilder will cause flickering for flutter web. so using
// different rendering methods for web and native.
@override
Widget build(BuildContext context) =>
kIsWeb ? _videoViewForWeb() : _videoViewForNative();
Widget build(BuildContext context) {
final child = kIsWeb ? _videoViewForWeb() : _videoViewForNative();

if (widget.fit == VideoViewFit.cover) {
return child;
}

final videoView = LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
if (!constraints.hasBoundedWidth && !constraints.hasBoundedHeight) {
return child;
}
if (_aspectRatio == null) {
return child;
}

bool fixHeight;
if (!constraints.hasBoundedWidth) {
fixHeight = true;
} else if (!constraints.hasBoundedHeight) {
fixHeight = false;
} else {
// both width and height are bound, figure out which to fix based on aspect ratios
final constraintsAspectRatio =
constraints.maxWidth / constraints.maxHeight;
fixHeight = constraintsAspectRatio > _aspectRatio!;
}
final double width;
final double height;
if (fixHeight) {
height = constraints.maxHeight;
width = height * _aspectRatio!;
} else {
width = constraints.maxWidth;
height = width / _aspectRatio!;
}
return SizedBox(width: width, height: height, child: child);
},
);

if (widget.autoCenter) {
return Center(child: videoView);
} else {
return videoView;
}
}

bool _shouldMirror() {
// off for screen share
Expand Down
Loading