使用MediaPipe自拍分割调用captureStream遇画布非源清洁错误
Canvas captureStream() 报错 "Canvas is not origin-clean" 解决方案(MediaPipe自拍分割场景)
错误原因分析
- 跨域资源污染画布:只要画布绘制了跨域来源的资源(比如外部图片、跨域视频帧),浏览器就会标记画布为"非源清洁",直接禁用
captureStream()、toDataURL()这类导出画布内容的API。MediaPipe处理摄像头流时,如果视频源流存在跨域问题(比如第三方CDN源、本地用file://协议测试),也会触发这个限制。 - MediaPipe内置资源的跨域问题:MediaPipe运行时加载的模型文件、辅助图形如果来自跨域路径,也会间接污染画布。
替代的画布流捕获方法
方法1:直接拿MediaPipe处理后的输出流(绕开画布)
MediaPipe自拍分割可以直接处理视频流,没必要先画到画布再捕获。直接取处理后的帧转成流就行:
// 假设已初始化SelfieSegmentation实例 selfieSegmentation.onResults(results => { // 直接捕获处理后的图像帧流 const stream = results.image.clone().captureStream(); // 用这个流做后续操作(推流、录制都可以) });
方法2:用OffscreenCanvas规避跨域限制
OffscreenCanvas是脱离DOM的画布,不受跨域规则约束,先在上面绘制再捕获流:
const offscreenCanvas = new OffscreenCanvas(640, 480); const offscreenCtx = offscreenCanvas.getContext('2d'); selfieSegmentation.onResults(results => { // 在离屏画布绘制分割后的蒙版或画面 offscreenCtx.drawImage(results.segmentationMask, 0, 0, 640, 480); // 捕获离屏画布的流 const stream = offscreenCanvas.captureStream(); });
方法3:彻底解决画布跨域污染
如果确定是跨域资源导致的问题,可以试试这两个方向:
- 本地测试别用
file://协议,改用localhost启动服务,同源环境下不会触发跨域限制。 - 所有要画到画布的资源(包括外部图、视频)都确保同源;如果是第三方资源,给资源标签加
crossOrigin="anonymous",同时确保服务器返回正确的CORS响应头。
内容的提问来源于stack exchange,提问作者Thalyson Brandão
相关产品推荐
相关产品推荐

