HarmonyOS 鸿蒙Next Flutter框架多设备开发指导-视频通话场景
HarmonyOS 鸿蒙Next Flutter框架多设备开发指导-视频通话场景
1.1 场景概述
在移动应用开发中,视频通话是一种常见的实时通信功能。不同设备的屏幕形态各异,如直板机、PAD、PC、折叠屏等,同时系统状态栏、导航栏、软键盘等元素也会占据屏幕空间。为了确保视频通话界面在各种设备和场景下都能正常显示,提供流畅的用户体验。本文将详细介绍 RN 视频通话组件的实现原理、适配指导以及具体的场景案例。
1.1.1 使用场景
在实时通信应用、社交软件、远程协作工具中,视频通话是很常见的功能,希望在不同设备上视频通话界面都能正常显示和交互。下面是不同设备上视频通话界面的差异,包括:直板机、PAD、PC、折叠屏(阔折叠、双折叠、三折叠)、智慧屏、座舱。
1.1.2 常见问题
开发过程中视频通话界面在不同设备上会存在差异,可能会出现以下问题:
- 摄像头画面被状态栏、导航栏遮挡
- 小窗口(画中画)位置不当导致画面截断
- 折叠屏设备折痕区域影响视频内容显示
- 分屏场景下视频窗口被另一个应用遮挡
- 横竖屏切换时视频布局错乱
1.1.3 多设备适配
1.1.3.1 视频通话多设备尺寸自适应适配
说明
根据断点布局实现视频通话界面的自适应:
| 横向断点 | sm | md | lg | xl |
|---|---|---|---|---|
| 属性 | 适配竖屏手机,小窗口位于右上角 | 适配横屏平板,小窗口自适应位置 | 适配折叠屏,小窗口自适应位置 | 适配 PC 屏,小窗口自适应位置 |
![]() |
![]() |
![]() |
![]() |
1.1.3.2 视频通话多设备窗口变化适配
- 适配点1:基于断点实现组件自适应在多设备布局适配,窗口响应(横竖屏、分屏、折叠开合等)

- 适配点2:组件尺寸自适应覆盖拉伸、均分、占比、缩放、延伸、隐藏、折行。

1.2 开发指导
1.2.1 Flutter开发
1.2.1.1 关键能力
1.2.1.1.1 PlatformView 桥接相机与远端适配
Flutter 无法直接调用 HarmonyOS 的 CameraKit 和 MediaKit,因此通过 PlatformView + MethodChannel 实现原生能力嵌入。
相机预览 (CameraOhosView):原生侧通过 XComponent(type: SURFACE) 获取 Surface,交给 CameraKit 进行相机预览渲染。Flutter 侧通过 OhosView(viewType: ‘com.videocall.ohos/cameraView’) 嵌入。
远端视频 (RemoteVideoOhosView):原生侧同样使用 XComponent 提供 Surface 给 AVPlayer,模拟远端视频画面。Flutter 侧通过 OhosView(viewType: ‘com.videocall.ohos/remoteVideoView’) 嵌入。
1.2.1.1.2 相机宽高比自适应
相机预览的宽高比与屏幕不一定匹配,需要进行自适应处理以避免画面拉伸:
原生侧选择最优 Profile:遍历设备支持的所有预览分辨率,计算每个 Profile 的宽高比与屏幕宽高比的差值,选择差值最小的(见 CameraOhosView.ets 的 selectBestProfile 方法)。
Flutter 侧计算显示尺寸:通过 getCameraSize() 获取相机分辨率,结合屏幕尺寸计算出保持宽高比的最优显示区域,再通过 setXComponentRect() 通知原生侧调整 Surface 尺寸。
Future<void> _setupCameraAspectRatio() async {
final cameraSize = await _cameraController?.getCameraSize();
//根据横竖屏计算 cameraAspectRatio
//按 cover 策略计算 displayWidth / displayHeight
await _cameraController?.setXComponentRect(displayWidth.toInt(), displayHeight.toInt());
}
1.2.1.1.3 远端视频宽高比适配
远端视频同样需要宽高比适配,采用 FIT(缩小至完全显示) 策略:
Future<void> _updateVideoArea({int retryCount = 0}) async {
final videoSize = await _remoteVideoController?.getVideoSize();
final diffW = windowWidth / videoWidth;
final diffH = windowHeight / videoHeight;
if (diffW <= diffH) {
_remoteVideoWidthPercent = 1.0;
_remoteVideoHeightPercent = diffW * videoHeight / windowHeight;
} else {
_remoteVideoHeightPercent = 1.0;
_remoteVideoWidthPercent = diffH * videoWidth / windowWidth;
}
}
配合 FractionallySizedBox 实现视频区域的动态缩放:
FractionallySizedBox(
widthFactor: _remoteVideoWidthPercent,
heightFactor: _remoteVideoHeightPercent,
child: RemoteVideoOhosView(_onRemoteVideoViewCreated),
)
原生侧同时设置 VIDEO_SCALE_TYPE_FIT_CROP 保证视频在 Surface 内不拉伸。
1.2.1.1.4 画中画 (PiP)
通过 PipManager 封装 HarmonyOS 的 PiPWindow API,实现视频通话画中画功能:
模板类型:PiPWindow.PiPTemplateType.VIDEO_CALL
内容尺寸:从 XComponent 的 SurfaceRect 获取
状态流转:ABOUT_TO_START → STARTED → ABOUT_TO_STOP → STOPPED
Flutter 联动:状态变化通过 onPipStateChanged 回调 Flutter 侧,Flutter 根据状态切换大小窗画面
// Flutter 侧:监听 PiP 状态,实现大小窗切换
void _handlePipStateChange(String state, {required bool isCamera}) {
if (state == 'STOPPED') {
if (_isRemoteShow && isCamera) {
_isRemoteShow = false;
_remoteVideoController?.startPip();
} else if (!_isRemoteShow && !isCamera) {
_isRemoteShow = true;
_cameraController?.startPip();
}
}
}
1.2.1.1.5 屏幕变化自适应
通过 WidgetsBindingObserver.didChangeMetrics 监听屏幕尺寸变化(如旋转、折叠屏展开),动态重新计算布局:
void didChangeMetrics() {
super.didChangeMetrics();
_onWindowSizeChanged(); // 重新计算相机宽高比 + 重启预览 + 更新远端视频区域
}
1.2.1.1.6 安全区适配
使用 Flutter 的 SafeArea 组件确保通话控制按钮不被系统状态栏、导航栏遮挡,同时视频画面全屏展示
Stack(children: [
// 视频层:全屏
Container(
width: double.infinity,
height: double.infinity,
color: !_isRemoteShow ? Colors.black : Colors.transparent,
child: CameraOhosView(_onCameraViewCreated),
),
//控制层:安全区内
Positioned.fill(
child: SafeArea(child: Column(...))
),
])
1.2.1.2 指导案例
1.2.1.2.1 原生插件注册
在 EntryAbility.ets 中注册 VideoCallPlugin:
export default class EntryAbility extends FlutterAbility {
configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine)
this.addPlugin(new VideoCallPlugin());
}
}
1.2.1.2.2 PlatformView 工厂注册
在 VideoCallPlugin.ets 中注册两个 PlatformView 工厂:
export class VideoCallPlugin implements FlutterPlugin {
onAttachedToEngine(binding: FlutterPluginBinding): void {
// 注册相机预览 PlatformView
binding.getPlatformViewRegistry()?.registerViewFactory(
'com.videocall.ohos/cameraView',
new CameraViewFactory(binding.getBinaryMessenger(), StandardMessageCodec.INSTANCE)
);
// 注册远端视频 PlatformView
binding.getPlatformViewRegistry()?.registerViewFactory(
'com.videocall.ohos/remoteVideoView',
new RemoteVideoFactory(binding.getBinaryMessenger(), StandardMessageCodec.INSTANCE)
);
}
}
1.2.1.2.3 Flutter 侧嵌入 PlatformView
通过 OhosView 将原生视图嵌入 Flutter 布局:
// 相机预览
OhosView(
viewType: 'com.videocall.ohos/cameraView',
onPlatformViewCreated: _onPlatformViewCreated,
creationParams: const <String, dynamic>{},
creationParamsCodec: const StandardMessageCodec(),
);
// 远端视频
OhosView(
viewType: 'com.videocall.ohos/remoteVideoView',
onPlatformViewCreated: _onPlatformViewCreated,
creationParams: const <String, dynamic>{},
creationParamsCodec: const StandardMessageCodec(),
);
1.2.1.2.4 相机宽高比适配步骤
- 原生侧在 startCamera() 中调用 selectBestProfile() 选择与屏幕宽高比最匹配的分辨率
- Flutter 侧通过 getCameraSize() 获取选中的分辨率
- 根据屏幕尺寸和相机分辨率计算 cover 策略下的显示宽高
- 通过 setXComponentRect() 设置原生 Surface 尺寸
- 屏幕旋转/折叠时,在 didChangeMetrics 中重新执行上述流程
1.2.1.2.5 画中画集成步骤
- 原生侧创建 PipManager,传入 XComponentController 和 UIAbilityContext
- 配置 PiPConfiguration,模板类型设为 VIDEO_CALL
- 注册 stateChange 回调,通过 MethodChannel 通知 Flutter
- Flutter 侧在 Controller 中监听 pipStateStream,根据 STOPPED 状态实现大小窗切换逻辑
1.2.1.2.6 响应式布局适配
根据屏幕高度动态调整控件尺寸,适配不同形态设备:
final screenHeight = MediaQuery.of(context).size.height;
final isSmallHeight = screenHeight < 600;
final iconSize = isSmallHeight ? 28.0 : 56.0;
final topMarginPercent = isSmallHeight ? 0.10 : 0.20;
final bottomMarginPercent = isSmallHeight ? 0.10 : 0.20;
1.2.1.3 示例代码
视频通话的Sample示例代码地址:example,开发者可以通过该地址查看完整的视频通话示例代码,并根据自己的需求进行修改和扩展。
更多关于HarmonyOS 鸿蒙Next Flutter框架多设备开发指导-视频通话场景的实战教程也可以访问 https://www.itying.com/category-92-b0.html
在HarmonyOS Next中,使用Flutter框架开发多设备视频通话,需通过Flutter插件封装鸿蒙原生API(如OHOS::Media::AVPlayer、OHOS::DistributedHardware::DeviceManager)。利用分布式软总线实现设备发现与连接,通过Flutter MethodChannel调用native音视频采集与渲染接口。注意在Flutter UI侧适配不同屏幕尺寸与折叠状态。
更多关于HarmonyOS 鸿蒙Next Flutter框架多设备开发指导-视频通话场景的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
该指南系统梳理了HarmonyOS Next上基于Flutter框架实现视频通话多设备适配的关键方案。通过PlatformView+MethodChannel桥接原生CameraKit与MediaKit,结合断点布局(sm/md/lg/xl)实现从小屏手机到折叠屏、PC的界面自适应。核心适配点包括相机与远端视频宽高比匹配、SafeArea安全区覆盖、屏幕形态变化监听(didChangeMetrics)和画中画(PiP)状态同步。示例代码展示了OhosView工厂注册、相机最优Profile选择、大小窗切换逻辑等,有效解决了遮挡、变形、窗口截断等常见问题。整体为多设备视频通话场景提供了可落地的开发范式。





