Flutter全屏模式切换直播视频源黑屏问题求助
解决全屏模式下切换直播频道黑屏问题
问题背景
开发直播视频流APP,竖屏切换视频源功能正常(通过Provider管理视频源,切换时销毁并重建播放器),但横屏全屏模式下切换频道时,新视频仅播放音频、屏幕黑屏,退出全屏返回竖屏后才显示画面。
核心原因
- 切换频道时未保留当前全屏状态,新初始化的Chewie控制器不知道处于全屏模式,导致渲染尺寸不匹配
- 自定义控件中重复销毁播放器控制器,与主组件的销毁逻辑冲突
- 播放器初始化时未确保组件处于mounted状态,导致视图更新异常
解决方案
1. 保留全屏状态并传递给新控制器
在频道切换时记录当前全屏状态,初始化新Chewie时传入该状态,确保新播放器以全屏模式渲染:
修改_onChannelChange方法:
void _onChannelChange() { // 记录当前是否处于全屏 final wasFullScreen = _chewieController?.isFullScreen ?? false; // 先按顺序销毁旧控制器 _chewieController?.dispose(); _controller.dispose(); setState(() { _currentPlayChannel = Provider.of<ChannelProvider>(context, listen: false).getSelectedVideo; // 更新全屏状态标记 _isFullModel = wasFullScreen; iniVideo(); }); }
确保iniVideo中ChewieController的fullScreenByDefault使用_isFullModel:
_chewieController = ChewieController( videoPlayerController: _controller, // ...其他配置 fullScreenByDefault: _isFullModel, // ...其他配置 );
2. 移除自定义控件中多余的播放器销毁逻辑
自定义控件的_selectChannel方法中,不要手动调用controller.dispose(),主组件的监听器会处理控制器的销毁重建,重复销毁会导致视图异常:
修改自定义控件代码:
Future<void> _selectChannel(BuildContext context, Map channel, int index) async { // 移除 await controller.dispose(); 这行代码 Provider.of<ChannelProvider>(context, listen: false).selectChannel(channel); }
3. 增加mounted判断,避免无效状态更新
在iniVideo中增加mounted判断,确保仅在组件存活时更新状态:
Future<void> iniVideo() async { _controller = VideoPlayerController.networkUrl(Uri.parse(_currentPlayChannel['link'])); await _controller.initialize(); if (!mounted) return; // 组件已销毁则终止后续操作 // ...应用内评分逻辑 setState(() { _chewieController = ChewieController(/* ...完整配置 */); }); }
4. 监听全屏状态变化,实时更新标记
添加监听实时同步Chewie的全屏状态,确保切换频道时状态准确:
@override void initState() { super.initState(); _currentPlayChannel = Provider.of<ChannelProvider>(context, listen: false).getSelectedVideo; Provider.of<ChannelProvider>(context, listen: false).addListener(_onChannelChange); iniVideo(); } void _listenToFullScreenChanges() { _chewieController?.addListener(() { if (_chewieController?.isFullScreen != _isFullModel) { setState(() { _isFullModel = _chewieController?.isFullScreen ?? false; }); } }); } // 在iniVideo中创建ChewieController后添加监听 Future<void> iniVideo() async { // ...初始化_controller逻辑 if (mounted) { // ...其他逻辑 setState(() { _chewieController = ChewieController(/* ...配置 */); _listenToFullScreenChanges(); // 绑定全屏状态监听 }); } }
内容的提问来源于stack exchange,提问作者Zubdev
相关产品推荐
相关产品推荐

