HTML5 screenshot with canvas using CORS

I have a problem with video screenshots in Chrome, and I have exhausted all the Internet and all Stackoverflow answers; bad luck.

No matter what I try, when I try to use the canvas element to take a screenshot of a video that is in a different domain or even just a different port, then I get the error Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. .

Here is my setup:

Web application url
http://client.myapp.com/home.html

CDN URLs (I tried both)
http://client.myapp.com:8181/somevideo.mp4
http://cdn.myapp.com/somevideo.mp4

Headers sent from MP4 from CDN:

 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 

I have:

  • Added crossOrigin="anonymous" to the video element, but it just makes the video not load at all
  • I tried even the same domain on another port (as mentioned above)
  • Make sure Access-Control-Allow-Origin returns with * (as above)
  • I do not believe this is DRM, as the screenshot works fine if I copy the same video file to a web application and upload it locally.
  • Go through all the answers to this question , but it’s all the same for the images, not the video, and the answers describe only all the previous points.

However, an error still occurred.

Edit
Added code:

 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); } 

Please, help.

+5
source share
1 answer

I answered my question.

What a terrible headache I have now.

The problem lies somewhere in the subtle specification of the HTML5 / CORS video correction specification.

I tested only in Chrome and Edge, but here is what you need to know at the time of writing:

Chrome

Downloading your HTML5 video will fail if you have crossOrigin installed, but your video will be transmitted from any port except 80 and not using https

THIS WILL NOT BE A FAULT
Customer at http://www.myapp.com/player.html :

 <video crossOrigin="anonymous" src="http://cdn.myapp.com:81/video.mp4"></video> 

THIS IS SUCCESSFUL
Customer at http://www.myapp.com/player.html :

 <video crossOrigin="anonymous" src="https://cdn.myapp.com:81/video.mp4"></video> 

Chrome and Edge

getImageData() and toDataURL() will be blocked if:

  • crossorigin is set to anonymous or use-credentials ( as defined here ) before the video loads. If you do it too late, it will still fail.

Everything

Finally, if you are going to set crossOrigin in javascript, be sure to use the correct package for the javascript property: crossOrigin (NOT crossOrigin )

I wrote this a bit more on my blog .

+10
source

Source: https://habr.com/ru/post/1242448/


All Articles