Canvas渲染视频流边缘出现绿线的原因及修复方案
Canvas渲染视频流侧边偶现绿线问题
触发场景
- 测试环境为Chrome浏览器
- 待绘制内容为摄像头采集的
MediaStream视频流 - 当Canvas元素尺寸小于视频实际分辨率时,视频侧边偶尔出现绿线
初始实现核心代码
let videoConstraints: MediaTrackConstraints; if (options) { if (!CameraResolutions[options.resolution]) options.resolution = CameraQuality.Auto; videoConstraints = { deviceId: options.deviceId, frameRate: { ideal: 30 }, // facingMode: options.facingMode, width: { ideal: CameraResolutions[options.resolution][0] }, // 720 height: { ideal: CameraResolutions[options.resolution][1] }, // 720 }; } const constraints: MediaStreamConstraints = { video: videoConstraints ?? true, audio: false, }; navigator.mediaDevices.getUserMedia(options.constraints); // ... this.ctx.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
临时规避方案
最初通过缩小绘制区域、增加偏移留边的方式调整绘制逻辑,可解决大部分场景下的问题,但方案稳定性不足,无法覆盖所有触发情况,调整后的代码如下:
const w = this.canvas.width - 10; const h = this.canvas.height - 10; const x = 5; // 让视频在canvas中居中 const y = 5; this.ctx.drawImage(this.video, x, y, w, h);
根因定位
最终排查确认问题根源:项目使用的WebRTC SDK开启了simulcast功能,编码格式采用VP8,该编码对渲染尺寸有强制对齐要求——Canvas宽高必须可被4、8或16整除,尺寸不满足对齐规则时就会出现边缘绿线的异常。
最终修复方案
计算Canvas尺寸时,按照16对齐的规则生成符合编码要求的尺寸,计算公式如下:
Math.round(Math.min(videoWidth, maxSize) / 16) * 16;
内容的提问来源于stack exchange,提问作者Exlord
相关产品推荐
相关产品推荐

