使用CORS通过画布截取HTML5视频

jos*_*ley 6 javascript video html5 canvas

我在Chrome中获取视频截图时遇到问题,而且我已经用尽所有互联网和所有Stackoverflow的答案了; 没运气.

无论我尝试什么,当我尝试使用该canvas元素截取不同域上的视频的屏幕截图,甚至只是一个不同的端口时,我最终都会Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.出错.

这是我的设置:

Web应用程序URL
http://client.myapp.com/home.html

CDN网址(我已尝试过)
http://client.myapp.com:8181/somevideo.mp4
http://cdn.myapp.com/somevideo.mp4

标题从CDN发回MP4:

Accept-Ranges:bytes
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers:x-ms-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-lease-status,x-ms-lease-state,x-ms-blob-type,Accept-Ranges,Content-Length,Date,Transfer-Encoding
Content-Length:5253832
Content-Range:bytes 48-5253879/5253880
Content-Type:video/mp4
Date:Sat, 06 Feb 2016 17:24:05 GMT
ETag:"0x8D32E3EDB17EC00"
Last-Modified:Fri, 05 Feb 2016 15:13:08 GMT
Server:Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-blob-type:BlockBlob
x-ms-lease-state:available
x-ms-lease-status:unlocked
x-ms-request-id:88d3aaef-0629-4316-995f-021aa0153c32
x-ms-version:2015-04-05
Run Code Online (Sandbox Code Playgroud)

我有:

  • 添加crossOrigin="anonymous"到视频元素,但这只会使视频无法完全加载
  • 尝试在不同的端口上使用相同的域(如上所述)
  • 确保Access-Control-Allow-Origin回来*(如上)
  • 我不相信它是DRM,因为如果我将完全相同的视频文件复制到Web应用程序并在本地加载它,截图工作正常
  • 浏览此问题的所有答案,但这是针对图像而不是视频而且答案仅描述了之前的所有要点

然而,仍然是爆炸的错误.

编辑
新增代码:

var getScreenshotDataUrl = function(video, canvas, type) {
    type = type || "image/jpeg";
    var context = canvas.getContext("2d");
    var w = video.videoWidth;
    var h = video.videoHeight;
    canvas.width = w;
    canvas.height = h;
    context.fillRect(0, 0, w, h);
    context.drawImage(video, 0, 0, w, h);
    video.crossorigin = "anonymous";// makes no difference
    return canvas.toDataURL(type);
}
Run Code Online (Sandbox Code Playgroud)

请帮忙.

jos*_*ley 11

我已经回答了我自己的问题.

我现在有多可怕的头痛.

问题出在HTML5视频crossorigin/CORS规范的细微规范中.

我只在Chrome和Edge中测试过,但在撰写本文时,您需要了解以下内容:

正在载入您的HTML5视频会失败,如果你已经crossOrigin设置的,但您的视频正在从高于其他任何端口提供80 不是使用https:

这将失败
客户在http://www.myapp.com/player.html:

<video crossOrigin="anonymous" src="http://cdn.myapp.com:81/video.mp4"></video>
Run Code Online (Sandbox Code Playgroud)

这将成为
客户http://www.myapp.com/player.html:

<video crossOrigin="anonymous" src="https://cdn.myapp.com:81/video.mp4"></video>
Run Code Online (Sandbox Code Playgroud)

Chrome和Edge

getImageData()并且toDataURL()将被安全阻止,除非:

  • 加载视频之前,crossorigin设置为anonymoususe-credentials(如此处所定义).如果你做得太晚,它仍然会失败.

所有

最后,如果你要crossOrigin在javascript中设置,请确保为javascript属性使用正确的大小写:( crossOriginNOT crossorigin)

我在博客中更详细地写了这篇文章.