The canvas has been tainted by cross-origin data in videojs - javascript

I'm try to play my video in canvas but I got this error:
Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
I can't change the source (the server to support cors), so what can I do to solve this?
document.addEventListener('DOMContentLoaded', function(){
var v = document.getElementById('my-video');
var canvas = document.getElementById('c');
var context = canvas.getContext('2d');
var back = document.createElement('canvas');
var backcontext = back.getContext('2d');
var cw,ch;
console.log({ v });
v.addEventListener('play', function(){
cw = v.clientWidth;
ch = v.clientHeight;
canvas.width = cw;
canvas.height = ch;
back.width = cw;
back.height = ch;
draw(v,context,backcontext,cw,ch);
},false);
},false);
function draw(v,c,bc,w,h) {
if(v.paused || v.ended) return false;
// First, draw it into the backing canvas
bc.drawImage(v,0,0,w,h);
// Grab the pixel data from the backing canvas
var idata = bc.getImageData(0,0,w,h);
var data = idata.data;
idata.data = data;
// Draw the pixels onto the visible canvas
c.putImageData(idata,0,0);
// Start over!
setTimeout(draw,20,v,c,bc,w,h);
}
#c {
position: absolute;
top: 50%;
left: 50%;
margin: -180px 0 0 20px;
}
<head>
<link href="https://vjs.zencdn.net/7.6.6/video-js.css" rel="stylesheet" />
<!-- If you'd like to support IE8 (for Video.js versions prior to v7) -->
<script src="https://vjs.zencdn.net/ie8/1.1.2/videojs-ie8.min.js"></script>
</head>
<body>
<video
id="my-video"
class="video-js"
controls
preload="auto"
width="640"
height="264"
poster="MY_VIDEO_POSTER.jpg"
data-setup="{}"
>
<source src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/mp4" />
<p class="vjs-no-js">
To view this video please enable JavaScript, and consider upgrading to a
web browser that
<a href="https://videojs.com/html5-video-support/" target="_blank"
>supports HTML5 video</a
>
</p>
</video>
<canvas id="c" ></canvas>
<script src="https://vjs.zencdn.net/7.6.6/video.js"></script>
</body>

Related

Dynamically load images into overlayed canvases and resize them

I have two canvases, which are overlaid. Now I want to load dynamically images into the canvases and adapt their size to the image size.
My problem now, is that after the canvases load the images and resize them self, they overlay all other html items below.
Here is the minimal example:
loadimage.onclick = function(e) {
//load image1
var img1 = new Image();
img1.onload = function() {
var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext("2d");
//resize canvas1
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
ctx.drawImage(this, 0, 0);
};
img1.src = "https://via.placeholder.com/250/0000FF/808080/";
//load image2
var img2 = new Image();
img2.onload = function() {
var canvas = document.getElementById("canvas2");
var ctx = canvas.getContext("2d");
//resize canvas1
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
ctx.drawImage(this, 75, 75);
};
img2.src = "https://via.placeholder.com/50/00FF00/808080/";
}
<div id="container" style="position: relative; width: 200px; height: 100px;">
<canvas id="canvas1" width="200" height="100" style="position: absolute; left: 0; top: 0; z-index: 0; border: 1px solid #000;"></canvas>
<canvas id="canvas2" width="200" height="100" style="position: absolute; left: 0; top: 0; z-index: 1; border: 1px solid #000;"></canvas>
</div>
<button id="loadimage" type="button">Load Content</button>
After pressing the "Load Content"
button, the button doesn 't move down.
I tried to change also the width and height properties of the "container"
div, but the behaviour did not change.
What am I missing here ?
So, the code has many problems. If you are beginner, don't worry. That's normal. ☺
Firstly, <canvas> is pair tag. That means that you have to close it using </canvas>. The correct form is <canvas someattribute="somevalue"></canvas>. Inside the <canvas> tag is place for alternative content that will be used when the browser does not support the <canvas> tag (it is quite new).
Omitting the </canvas> broke the page.
HTML dictates what tags must be closed and what shouldn't and <canvas> is one of tags that must be closed. The Validator could help you identify mistakes in the code. Note that it is quite pedantic.
The second problem is that you were using absolute positioning and the canvases, when resized, overlaid the button. Simply disable the positioning or use some more precise way of positioning. The third option is to resize the container div appropriately in the JS.
The container div had also set fixed size. By default, when the content is larger, it overflows.
You were probably trying to solve it using z-index. Setting z-indexes is usually quite tricky and I try to use it as the last resort. Both your z-index properties were not valid. It is z-index: NUMBER, not z- index or z index.
And the last bug I have found was that you were using canvas1 (undefined variable) instead of canvas in the second function.
loadimage.onclick = function(e) {
//load image1
var img1 = new Image();
img1.onload = function() {
var canvas = document.getElementById("canvas1");
var ctx = canvas1.getContext("2d");
//resize canvas1
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
ctx.drawImage(this, 0, 0);
};
img1.src = "https://via.placeholder.com/250/0000FF/808080/";
//load image2
var img2 = new Image();
img2.onload = function() {
var canvas = document.getElementById("canvas2");
var ctx = canvas.getContext("2d");
//resize canvas1
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
ctx.drawImage(this, 0, 0);
};
img2.src = "https://via.placeholder.com/50/00FF00/808080/";
}
<div id="container">
<canvas id="canvas1" width="200" height="100" style="border: 1px solid #000;"></canvas>
<canvas id="canvas2" width="200" height="100" style="border: 1px solid #000;"></canvas>
</div>
<button id="loadimage" type="button">Load Content</button>

How to append HTML5 video snapshots to a scrolling DIV without Jquery

How can I take multiple snapshots (via onclick buttons) from an HTML5 video playing locally, and add the snapshot images with timestamp to a scrollable div without jQuery or external libraries?
I'm able to make a snapshot via canvas but how can I convert the canvas image to a small file size format and append the image (with a href="" scrpt) to a scrolling div?
codepine example http://codepen.io/anon/pen/OVGZEg
HTML
<span> Working example</span>
<br>
<video controls id="sourceVid">
<source src="http://html5multimedia.com/code/ch9/media/elephants-dream-medium.mp4" type="video/mp4">
<source src="../media/elephants-dream-medium.webm" type="video/webm">
</video>
<canvas></canvas>
<br>
<button id="snap" onclick="snap()">Take Snapshot</button>
<br>
<br>
<br>
<!----------------------------------------
Desired Result
---------------------------------------->
<div id="DesiredResult" style="background-color:grey;width: 100%;">
<br>
Desired Result
<br>
How can I take a snapshot & add it to scrolling DIV on the left?
<br>
<video controls id="Result" style="float: left;" >
<source src="http://html5multimedia.com/code/ch9/media/elephants-dream-medium.mp4" type="video/mp4">
<source src="../media/elephants-dream-medium.webm" type="video/webm">
</video>
<div id="snapshotscroll" >
<div id="snapshot#1" class="snapshots" style="background-color:#FE2E2E;" >
snapshot image
<br>#1
</div>
<div id="snapshot#1" class="snapshots" style="background-color:#FA5858;" >
snapshot image
<br>#2
</div>
<div id="snapshot#1" class="snapshots" style="background-color:#F78181;" >
snapshot image
<br>#3
</div>
<div id="snapshot#1" class="snapshots" style="background-color:#F5A9A9;" >
snapshot image
<br>#4
</div>
<div id="snapshot#1" class="snapshots" style="background-color:#F6CECE;" >
snapshot image
<br>#5
</div>
</div>
</div>
<button id="snap" onclick="alert('How can I take a snapshot & add it to scrolling DIV on the left?')">Take Snapshot</button>
CSS
video, canvas {
border:1px solid #000;
}
#snapshotscroll {
overflow-y: scroll;
height:258px;
width:220px;
}
.snapshots {
width: 200px;
height: 100px;
border: 1px solid #000;
}
JAVASCRIPT
// Get handles on the video and canvas elements
var video = document.getElementById('sourceVid');
var canvas = document.querySelector('canvas');
// Get a handle on the 2d context of the canvas element
var context = canvas.getContext('2d');
// Define some vars required later
var w, h, ratio;
// Add a listener to wait for the 'loadedmetadata' state so the video's dimensions can be read
video.addEventListener('loadedmetadata', function() {
// Calculate the ratio of the video's width to height
ratio = video.videoWidth / video.videoHeight;
// Define the required width as 100 pixels smaller than the actual video's width
w = 200;
// Calculate the height based on the video's width and the ratio
h = 100;
// Set the canvas width and height to the values just calculated
canvas.width = w;
canvas.height = h;
}, false);
// Takes a snapshot of the video
function snap() {
// Define the size of the rectangle that will be filled (basically the entire element)
context.fillRect(0, 0, w, h);
// Grab the image from the video
context.drawImage(video, 0, 0, w, h);
}
I ended up getting your example working with a few tweaks. This example uses a counter to keep track of which div to append the snapshot to.
Live Working Example (full screen it):
var w = 200, h = 100, snapnum = 1;
// Takes a snapshot of the video
function snap() {
var cv = document.createElement("canvas");
cv.width = w;
cv.height = h;
console.log(document.getElementById("snapshot#" + snapnum));
document.getElementById("snapshot#" + snapnum).textContent = "";
document.getElementById("snapshot#" + snapnum).appendChild(cv);
var cx = cv.getContext('2d');
cx.fillRect(0, 0, w, h);
// Grab the image from the video
cx.drawImage(document.getElementById('Result'), 0, 0, w, h);
snapnum++;
}
video, canvas {
border:1px solid #000;
}
#snapshotscroll {
overflow-y: scroll;
height:258px;
width:220px;
}
.snapshots {
width: 200px;
height: 100px;
border: 1px solid #000;
}
<!---------------------------------------- Desired Result ---------------------------------------->
<div id="DesiredResult" style="background-color:grey;width: 100%;">
<br>Desired Result
<br>
<video controls id="Result" style="float: left;">
<source src="http://html5multimedia.com/code/ch9/media/elephants-dream-medium.mp4" type="video/mp4">
<source src="../media/elephants-dream-medium.webm" type="video/webm">
</video>
<div id="snapshotscroll">
<div id="snapshot#1" class="snapshots" style="background-color:#FE2E2E;">snapshot image
<br>#1</div>
<div id="snapshot#2" class="snapshots" style="background-color:#FA5858;">snapshot image
<br>#2</div>
<div id="snapshot#3" class="snapshots" style="background-color:#F78181;">snapshot image
<br>#3</div>
<div id="snapshot#4" class="snapshots" style="background-color:#F5A9A9;">snapshot image
<br>#4</div>
<div id="snapshot#5" class="snapshots" style="background-color:#F6CECE;">snapshot image
<br>#5</div>
</div>
</div>
<button id="snap" onclick="snap()">Take Snapshot</button>
JSFiddle Version: https://jsfiddle.net/y80m3z33/

Mousemove in canvas with video issue

I have following code which moves image over canvas as I want, using mousemove:
<!DOCTYPE html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<style type="text/css">
#canvas {
padding: 0px;
margin: 0px;
top:0;
left:0;
z-index: 30;
position: absolute;
width: 50%;
height: 50%;
}
</style>
</head>
<body>
<video id="video" autoplay="true" loop="true" >
<source src="video/xyz.ogg" type="video/ogg" />
<source src="video/xyz.mp4" type="video/mp4" />
<canvas id="canvas"></canvas>
<script>
document.addEventListener('DOMContentLoaded', function(){
var v = document.getElementById('video');
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var canvas = $('canvas');
canvas.mousemove(function(e){
$('#imgFollow').offset({left:e.pageX-20,top:e.pageY+10});
});
</script>
<a id="imgFollow"><img width="75px" height="75px"
src="http://i.imgur.com/Jwhcy45.png" class="canvas"/></a>
</body>
</html>
But when I draw video over canvas using this:
document.addEventListener('DOMContentLoaded', function(){
var v = document.getElementById('video');
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
//var cw = Math.floor(canvas.clientWidth / 100);
//var ch = Math.floor(canvas.clientHeight / 100);
var cw = Math.floor(canvas.clientWidth);
var ch = Math.floor(canvas.clientHeight);
canvas.width = cw;
canvas.height = ch;
v.addEventListener('play', function(){
draw(this,context,cw,ch);
},false);
},false);
function draw(v,c,w,h) {
if(v.paused || v.ended) return false;
c.drawImage(v,0,0,w,h);
setTimeout(draw,20,v,c,w,h);
}
var canvas = $('canvas');
canvas.mousemove(function(e){
$('#imgFollow').offset({left:e.pageX-20,top:e.pageY+10});
});
</script>
<a id="imgFollow"><img width="75px" height="75px"
src="http://i.imgur.com/Jwhcy45.png" class="canvas"/></a>" class="canvas"/></a>`
and then using mousemove to move image over it, it doesn't show the image over the video.
I am able to see through the side that it is working, but not displaying over video. Any answer or suggestion?

How to increase size of canvas image in html

I have taken 2 canvas one is the source and another is ther target. When I mouse over the image in canvas it should get enlarged in canvas2
How can I increase the height of image in canvas2 i want magnify effect .Below is the code.
Thanks
Husein
<html>
<body>
<input type="button" onclick="h()">
<p>Image to use:</p>
<p>Canvas:</p>
<canvas id="myCanvas" onmousemove="h()" width="250" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<p>Canvas2:</p>
<canvas id="myCanvas2" width="100" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var image = new Image();
image.crossOrigin="anonymous";
image.src="img_the_scream.jpg"
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=image ;
ctx.drawImage(img,0,0);
var d=document.getElementById("myCanvas2");
var ctx1=d.getContext("2d");
function h()
{
var img=ctx.getImageData(event.clientX-80,event.clientY-100,100,100);
ctx1.clearRect ( 0 , 0 , d.width , d.height );
ctx1.putImageData(img,0,0);
//d.width="200";
//d.height="200";
}
</script>
</body>
</html>
All you have to do is use toDataUrl and drawImage instead of getImageData and putImageData. Example:
function h() {
var img=new Image();
img.src = ctx.toDataUrl();
img.onload = function() {
ctx1.drawImage(img,0,0,c.width*horizontalMagnification,c.height*verticalMagnification);
};
}
Alternatively, you could just call ctx1.scale(horizontalMagnification,verticalMagnification); before you use putImageData.

How do I get a video to be play on the canvas under my canvas animation?

How do I get a video to be play on the canvas under my canvas animation?
For instance this clip.
So this animation moves along the bottom of the video.
Code:
<html>
<head>
<script type='text/javascript' src='http://code.jquery.com/jquery-1.8.3.js'></script>
<script type="text/javascript">
var context;
var text = "";
var textDirection ="";
$(function()
{
context = document.getElementById("cvs").getContext("2d");
setInterval("animate()", 360);
textDirection ="right";
textXpos = 5;
text = "This is my video..";
});
function animate() {
// Clear screen
context.clearRect(0, 0, 500, 500);
context.globalAlpha = 1;
context.fillStyle = '#fff';
context.fillRect(0, 0, 500, 500);
var metrics = context.measureText(text);
var textWidth = metrics.width;
if (textDirection == "right") {
textXpos += 10;
if (textXpos > 500 - textWidth) {
textDirection = "left";
}
}
else {
textXpos -= 10;
if (textXpos < 10) {
textDirection = "right";
}
}
context.font = '20px _sans';
context.fillStyle = 'black';
context.textBaseline = 'top';
context.fillText ( text, textXpos, 180);
}
</script>
</head>
<body>
<div id="page">
<canvas id="cvs" width="500" height="500">
Your browser does not support the HTML 5 Canvas.
</canvas>
</div>
</body>
</html>
I don't think you need to play the video in the canvas. Just create a video element in your HTML and use CSS to place your canvas element over it.
HTML:
<div id="page">
<video id="video" autoplay loop>
<source id='mp4'
src="http://media.w3.org/2010/05/sintel/trailer.mp4"
type='video/mp4'>
<source id='webm'
src="http://media.w3.org/2010/05/sintel/trailer.webm"
type='video/webm'>
<source id='ogv'
src="http://media.w3.org/2010/05/sintel/trailer.ogv"
type='video/ogg'>
<p>Your user agent does not support the HTML5 Video element.</p>
</video>
<canvas id="cvs" width="500" height="500">
Your browser does not support the HTML 5 Canvas.
</canvas>
</div>
CSS:
#cvs {
position: absolute;
top: 0px;
left: 0px;
}
Fiddle.

Categories