CORS error when reading video from canvas (tainted canvas) - javascript

I'm running an HLS stream that I want to write to a canvas; and then read pixels from the canvas.
The video gets rendered to the canvas A-ok, but it gets kicked off at:
myPixel = c.getImageData(200, 200, 1, 1).data;
where it fails with:
[Error] SecurityError: DOM Exception 18: An attempt was made to break through the security policy of the user agent.
[Error] Unable to get image data from canvas because the canvas has been tainted by cross-origin data.
I've set the cross-domain settings on the Wowza streaming server to:
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="*" to-ports="*" secure="false"/>
<allow-http-request-headers-from domain="*" headers="*" secure="false"/>
and crossOrigin="anonymous" on the client side video element.
It works and fails with different computers on the same network, all running Safari 7.0.2/Mac.
Any good ideas for debugging this?

If your modifications work on some computers and not on other identically configured computers, try clearing the cache on the misbehaving computers.
Force a reload on the misbehaving macs like this:
Hold Shift and Cmd and press R.

Related

Setting currentTime on html5 video throws "PIPELINE_ERROR_DECODE: video decode error" on windows Chrome

Seeking the video (changing its currentTime by setting it explicitly rather than using the play function) may cause it to throw
MediaError {code: 3, message: "PIPELINE_ERROR_DECODE: video decode error"}
It only occurs on Chrome and on Windows.
I managed to fix by changing turn it off Chrome's "use hardware acceleration when available" option under settings and then resetting Chrome.
However I'd like some permanent solution that doesn't involve asking the user to set browser settings.
My server is returning 206 as this answer specifies https://stackoverflow.com/a/36101965/1351652
I am waiting for the load events, video works fine for playing and sometimes skipping works.
It seems the error is more frequent if I try to seek repetedly, very fast. I do have a listener that doesn't let the client seek the video if the previous call to setCurrentTime didn't finish (seeked event)
On the server side I'm using node + express. My videos are in a static folder and I serve them using
app.use('/videos',validateToken,express.static('videos'))
validateToken is checking for a JWT token in the url

MediaRecorder changes size without provocation

I'm using the MediaRecorder API along with the Canvas captureStream method to encode a VP8 video stream of a canvas in browser. This data is sent to FFmpeg via binary web socket.
var outputCaptureStream = $('canvas')[0].captureStream(30);
var mediaRecoder = new MediaRecoder(outputCaptureStream, {
mimeType: 'video/webm'
});
mediaRecorder.ondataavailable = function (e) {
ffmpegStdin.write(e.data);
}
mediaRecoder.start(1000);
For some reason, the stream seems to be randomly switching to a lower resolution mid-stream. FFmpeg isn't happy about this:
Input stream #0:0 frame changed from size:1280x720 fmt:yuv420p to size:1024x576 fmt:yuv420p
[vp8 # 0x2a02c00] Upscaling is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.
[vp8 # 0x2a02c00] If you want to help, upload a sample of this file to ftp://upload.ffmpeg.org/incoming/ and contact the ffmpeg-devel mailing list. (ffmpeg-devel#ffmpeg.org)
I suspect that it has something to do with excessive CPU usage and that Firefox is trying to be helpful by scaling down the video. My questions:
Does Firefox scale down the video on the fly?
If so, what conditions cause this to happen? (CPU load? Stream backpressure?)
Is it possible to prevent Firefox from doing this?
Is there a different explanation for this behavior that I'm missing?
Firefox will rescale (downscale) WebRTC/getUserMedia video if it detects the system's CPU is being overloaded. There are a few prefs in about:config that control this behavior, but it's not controllable via JS.
You can disable the feature by setting
media.navigator.load_adapt=false
You can look at the other media.navigator.load_adapt.* flags for some control over the behavior. By default you will get downscaling if the CPU gets pegged more than 90% for 3 seconds.

Security error when attempting to manipulate image data of SVG in canvas

http://jsfiddle.net/5emz372r/
I am programmatically generating an SVG data URI, then rendering it in the canvas. Any attempts to use getImageData from that point on throw this error:
SecurityError: DOM Exception 18: An attempt was made to break through the security policy of the user agent.
Does drawing an SVG to canvas automatically taint the canvas?
Side note: My ultimate goal here is to render a custom webfont (loaded by data URI) onto the canvas; is there an alternate way of doing this?
Your fiddle is broken, keeps crashing when I go to it.
The likely cause of this issue is you are trying to access a photo, or file, that is located on another domain. Browser security wont let you do this in most cases.
SECURITY_ERR: DOM Exception 18 when applying document.domain on both sites. How do I resolve this?

KineticJS: Kinetic warning: Unable to get data URL

I have two Kineticjs canvases and when trying to create an image in one canvas from the other canvas I get this error after calling toImage() on the canvas with the new image:
Kinetic warning: Unable to get data URL. Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported
I am pretty sure the reason why I am getting this error is because the "toImage()
method requires that the image is hosted on a web server with the same domain as the code executing it." How can I get around this warning so that I can create objects from one canvas and add them to another?
The app I am creating will run locally and will never run online so I don't have to worry about security issues. Also I read around that I can enable cross origin resource sharing but that seems a little complex and over the top since they require the setting up of a web server I think.
So is there any trick I can do to make one canvas able to create an image in another canvas for a Chrome kineticjs web app? And then being able to successfully call toImage()?
Here is how I am creating the image in the canvas:
var folderImage = new Image();
//folderImage.crossOrigin="anonymous"; // gives me file error if unchecked
folderImage.onload = function() {
var folderPic = new Kinetic.Image({
x: 0,
y: 0,
image: folderImage,
width: sideLen,
height: sideLen
});
subFolderGroup.add(folderPic);
subTextGroup.moveToTop();
mainBody4Dynamic.draw();
};
folderImage.src = 'assets/images/folder.png';
And when I call toImage() in the other layer all I am calling is the layer.toImage()
The browser treats the user's local drive as other-domain. That's good because you don't want your browser "getting friendly" with your banking records on your hard drive.
This means running locally with local images will taint the canvas (a CORS violation).
The simplest workaround is to install a web-server on your local machine and host the web-page plus images on a single domain. (=== automatic CORS compliance). PHP and IIS both work well on a dev machine.
Another workaround is complying with CORS restrictions by hosting your images on an internet imaging host that has configured its server to deliver images in a CORS compliant manor. Then all you have to do is add myImage.crossOrigin="anonymous". I believe dropbox.com does this--or they used to.
While in development, it sometimes works to put both your .html and your images on the desktop.

can not get canvas.getContext('2d').getImageData(x,x,x,x)

can not get the imageData
the browser console "Unable to get image data from canvas because the canvas has been tainted by cross-origin data."
In order to prevent shenanigans, the browser keeps track of image data. When you put an image from a different domain on your canvas, the canvas becomes "tainted" and the browser won't let you look at its pixels anymore.
This is necessary to prevent a variety of XSS/CSRF attacks.
See Pointy's answer for an explanation. This can be an annoying problem when testing files from the local filesystem. On Google Chrome / Chromium there's a workaround: Call it with the following command line option:
chromium-browser --allow-file-access-from-files

Categories

Resources