Flutter WebRTC视频通话首次运行摄像头不显示热重载后正常如何解决
问题原因
该问题是因为RTC视频渲染器初始化、视频流绑定完成的时机晚于首次UI渲染,首次渲染时RTCVideoView绑定的渲染器还没有可用的视频帧数据,热重载会强制触发全量UI刷新,此时渲染器已就绪就会正常显示画面。
解决方案
- 方案1:监听渲染器状态主动触发UI重建
在本地流、远端流绑定到对应RTCVideoRenderer之后,以及监听渲染器的首帧渲染回调,两个时机都调用setState触发当前页面的UI刷新即可,示例代码如下:
// 本地流初始化逻辑示例 Future<void> initLocalMedia() async { final mediaConstraints = <String, dynamic>{ 'audio': true, 'video': true, }; // 确认权限已授予后再获取流 _localStream = await navigator.mediaDevices.getUserMedia(mediaConstraints); _localRenderer.srcObject = _localStream; // 流绑定完成后触发一次UI刷新 if (mounted) setState(() {}); // 监听首帧渲染回调,再次刷新避免偶发不显示问题 _localRenderer.onFirstFrameRendered = () { if (mounted) setState(() {}); }; } // 远端流接收逻辑也做同样处理 void onRemoteStream(MediaStream stream) { _remoteRenderer.srcObject = stream; if (mounted) setState(() {}); _remoteRenderer.onFirstFrameRendered = () { if (mounted) setState(() {}); }; }
- 方案2:增加就绪状态判断延迟渲染视频组件
新增权限、流就绪状态判断,只有确认所有前置逻辑完成后再渲染RTCVideoView组件,避免提前渲染空的视频视图:
Expanded( child: Padding( padding: const EdgeInsets.all(8.0), child: _isMediaReady // 自定义的流初始化完成状态位 ? Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded(child: RTCVideoView(_localRenderer, mirror: true)), Expanded(child: RTCVideoView(_remoteRenderer)), ], ) : const Center(child: CircularProgressIndicator()), ), )
- 其他补充
如果使用的是低于0.9.40版本的flutter_webrtc库,存在官方已知的首帧渲染bug,可升级到最新稳定版后复测。
内容的提问来源于stack exchange,提问作者ᴅ ᴇ ʙ ᴊ ᴇᴇ ᴛ
相关产品推荐
相关产品推荐

