Custom Aspect Ratio for VideoView
This guide shows how to force a specific aspect ratio for VideoView widgets in your Flutter app. This works consistently on both iOS and Android.
The Problem
By default, VideoView expands to fill its parent container. If you need a specific aspect ratio (like 1:1 for square videos), you need to constrain it using Flutter's layout widgets.
Solution
Wrap VideoView in an AspectRatio widget and use ClipRRect to clip any overflow.
Self Video (1:1)
AspectRatio(
aspectRatio: 1.0, // 1:1 square
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Container(
color: Colors.black,
child: const VideoView(isSelfParticipant: true),
),
),
)
Remote Participant Video (1:1)
AspectRatio(
aspectRatio: 1.0,
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Container(
color: Colors.black,
child: VideoView(meetingParticipant: participant),
),
),
)
Grid of Participants (1:1 tiles)
Use childAspectRatio in GridView:
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
childAspectRatio: 1.0, // 1:1 aspect ratio
),
itemCount: participants.length,
itemBuilder: (context, index) {
final participant = participants[index];
return ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Container(
color: Colors.black,
child: VideoView(
key: ValueKey(participant.id),
meetingParticipant: participant,
),
),
);
},
)
Other Aspect Ratios
| Ratio | Value |
|---|---|
| 1:1 (Square) | 1.0 |
| 16:9 (Landscape) | 16 / 9 |
| 9:16 (Portrait) | 9 / 16 |
| 4:3 | 4 / 3 |
// Example: 16:9 aspect ratio
AspectRatio(
aspectRatio: 16 / 9,
child: ClipRRect(
child: VideoView(isSelfParticipant: true),
),
)
Key Points
AspectRatioconstrains the child to the specified ratioClipRRectclips overflow and optionally adds rounded cornersContainerwithcolor: Colors.blackprovides a background for letterboxingValueKeyonVideoViewensures proper widget recycling in lists
This approach works identically on iOS and Android.