iOS 15.1系统下VueJS实现的视频流功能无法显示如何解决?
iOS 15/15.1 视频流无法渲染问题解决方案
这是iOS 15~15.1版本WebKit内核的已知Bug,内核的UI渲染队列没有正确触发video标签的帧刷新逻辑,摄像头视频流本身传输、解码都正常,因此可以正常截图,只有页面初始渲染时画面没有正常绘制,切换前后台触发全页面重绘后即可恢复。
可落地解决方案
- 放弃依赖autoplay属性,手动调用play方法:iOS 15.x对video标签的autoplay属性判定逻辑存在缺陷,即使配置了autoplay和playsinline属性,也可能没有触发播放动作。
- 赋值流后强制触发页面重绘:通过极小成本的样式修改触发video标签的重排/重绘,即可让内核正确渲染视频帧。
- 赋值流前先清空srcObject缓存:避免内核残留的旧媒体资源影响新流的渲染判定。
修改后代码示例
<template> <video playsinline ref="video" class="video" :class="{ 'video-mobile': $mq === 'sm' }" /> </template> <script> // ... async mounted () { if (!this.deviceSupported) { this.handleError('NoSupportedDevice') return } try { let stream = await navigator.mediaDevices.getUserMedia(this.constraints) const videoEl = this.$refs.video // 先清空原有srcObject避免缓存影响 videoEl.srcObject = null // 等待一个渲染帧后再赋值流 await this.$nextTick() videoEl.srcObject = stream // 手动调用play,配合playsinline可绕过iOS大部分自动播放限制 try { await videoEl.play() } catch (e) { console.log('play触发失败,可引导用户点击页面后重试', e) } // 强制触发重绘:修改透明度后改回,视觉上无感知 videoEl.style.opacity = 0.99 setTimeout(() => { videoEl.style.opacity = 1 }, 50) } catch (error) { console.log(error, 'camera_error') this.handleError(error.name) } }, </script>
额外注意点
- 如果页面初始化时没有用户交互动作触发摄像头调用,需要提前引导用户点击一次页面任意位置,否则iOS的自动播放限制会拦截play调用
- 不要给video标签加muted之外的额外CSS动画、transform属性,会进一步加剧15.x版本的渲染异常概率
内容的提问来源于stack exchange,提问作者Victor
相关产品推荐
相关产品推荐

