【Flutter】 视频视频源横向、竖向问题
源代码
Container(
alignment: Alignment.center,
width: double.infinity,
height: 212.h,
child: Stack(
children: [
Container(
color: Color(0x0F000000),
constraints: const BoxConstraints.expand(),
child: Obx(() => controller.callStatusMap[cameraId].value ==
VideoCallStatus.SPEAKING
? Obx(() => Transform(
alignment: Alignment.center,
transform: controller.cameraList[index].rxFlip.value
? Matrix4.diagonal3Values(-1, 1, 1)
: Matrix4.identity(),
child: Transform.rotate(
angle: controller
.cameraList[index].rxAngle.value >
0.0
? (180 *
pi /
(controller.cameraList[index].angle ?? 1))
: 0,
child: RTCVideoView(
controller.getRender(cameraId),
objectFit: RTCVideoViewObjectFit
.RTCVideoViewObjectFitCover,
mirror: true,
placeholderBuilder: ((ctx) => Container(
color: Colors.black))),
)))
: readerToStart(cameraId, index)),
),
Obx(() => Visibility(
visible: controller.recordingStatusMap[cameraId]?.value ??
false,
child: Positioned(
top: 8.h,
left: 0,
right: 0,
child: buildRecordTimer(index),
))),
],
),
),
现象
垂直会超出父控件。
原因分析
Transform.rotate变化时不会通知父组件,导致RTCVideoView直接超出了父组件的布局范围。
修复
关键:
1、RotatedBox替代Transform.rotate;
2、视频控件需要主动判断视频是横向还是竖向的状态:objectFit: isVertical?RTCVideoViewObjectFit.RTCVideoViewObjectFitContain:RTCVideoViewObjectFit.RTCVideoViewObjectFitCover,
Container(
color: const Color(0x0F000000),
width: double.infinity,
height: videoHeight,
alignment: Alignment.center,
child: status == VideoCallStatus.SPEAKING
? LayoutBuilder(
builder: (context, constraints) {
final w = constraints.maxWidth;
final h = constraints.maxHeight;
// ✅ 自动根据方向切换布局逻辑
final view = RTCVideoView(
controller.getRender(cameraId),
objectFit: isVertical?RTCVideoViewObjectFit.RTCVideoViewObjectFitContain:RTCVideoViewObjectFit.RTCVideoViewObjectFitCover,
mirror: true,
placeholderBuilder: (ctx) =>
Container(color: Colors.black),
);
return Transform(
alignment: Alignment.center,
transform: camera.rxFlip.value
? Matrix4.diagonal3Values(-1, 1, 1)
: Matrix4.identity(),
child: RotatedBox(
quarterTurns: isVertical ? 1 : 0, // ✅ 用 RotatedBox 解决溢出问题
child: FittedBox(
fit: isVertical
? BoxFit.fitHeight // 竖屏填满高度
: BoxFit.fitWidth, // 横屏填满宽度
alignment: Alignment.center,
child: SizedBox(
width: w,
height: h,
child: view,
),
),
),
);
},
)
: readerToStart(cameraId, index),
),