downloading multiple html5 generated images as a zip file - javascript

i am building a video hosting site. my video player generates video player screenshots by the onclick() function. i am also not sure if these images are deleted or stored after generating.
i have tried surfing around here trying to find a definitive assistance as i lack in javascript knowledge and it's so frustrating. please help me. ask me if you need any more info. :)
here is my html:
<body>
<div id="videoPanel">
<div id="instructions">
<video id="my_video_1" class="video-js vjs-default-skin" width="720px" height="400px" controls preload="none" poster='' autoplay data-setup='{ "aspectRatio":"640:500", "playbackRates": [1, 1.5, 2] }'>
<source src="/Custom-Video-Player/Masamune kun no Revenge - 07.mp4" type='video/mp4' />
</video>
</div>
<button id="clicker" onclick="shoot()">Capture</button><br />
<button id="download" onclick=""> download</button> <br/>
<div id="output" style="display: inline-block; top: 4px; position: relative; border: dotted 1px #ccc; padding: 2px;"></div>
</div>
</body>
this is the javascript for the screenshot generation:
var videoId = 'my_video_1';
var scaleFactor = 0.25;
var snapshots = [];
var w = 720 * scaleFactor;
var h = 400 * scaleFactor;
function capture(video, scaleFactor) {
if (scaleFactor == null) {
scaleFactor = 1;
}
var canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, w, h);
return canvas;
}
function shoot() {
var video = document.getElementById(videoId);
var output = document.getElementById('output');
var canvas = capture(video, scaleFactor);
canvas.onclick = function () {
window.open(this.toDataURL());
};
snapshots.unshift(canvas);
output.innerHTML = '';
for (var i = 0; i < 4; i++) {
output.appendChild(snapshots[i]);
}
}
theres also a download button that i want to be able to function as such:
it will number all images in accordance to their generation in regard to the 'capture' button, put them all in a zip file and download when download is pressed.

Related

Binding a Range Slider to Image Sequence

I want to show a timelapse video but have it with a Range slider so the user can drag it back and forth. I've tried with a video but I don't like the loading effect as you scroll. I also exported the video as images and binded it to the range slider. First question is, isn't there any plugins or applications out there that do this? Maybe i'm searching the wrong terms. Second is an image sequence the best way to do this? In my code below I can get it to partially work, but I can't figure out how to resize the image, and it's way to big for the canvas.
<style>
canvas {
height: 650px;
width: 1000px;
border: 1px solid black;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<canvas id="canvas" height="650px" width="1000px"></canvas>
<br>
<input id="my-input" type="range" min="1" max="50" value="1">
<script type="text/javascript">
var canvas = document.getElementById("canvas");
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
var totalImages = 50;
var videoFrames = [];
for (var i = 1; i <= totalImages; i++) {
var videoFrame = new Image;
var videoFrameUrl = 'http://dacwebdesign.com/testing/images/timelapse-' + i + '.jpg';
videoFrame.src = videoFrameUrl;
videoFrames.push(videoFrame);
}
$("#my-input").on("input", function(event) {
var currentImage = videoFrames[event.target.value - 1];
var context = canvas.getContext("2d");
context.drawImage(currentImage, 0, 0);
});
</script>
You can resize the images to fit your canvas with:
var currentImage = videoFrames[event.target.value - 1];
var context = canvas.getContext("2d");
var dstWidth = canvas.width;
var dstHeight = canvas.height;
var srcWidth = currentImage.naturalWidth;
var srcHeight = currentImage.naturalHeight;
context.drawImage(currentImage, 0, 0, srcWidth, srcHeight, 0, 0, dstWidth, dstHeight);
That does not take into account aspect ratios, so if your canvas has a different aspect ratio to your images, it will appear distorted.

Best way to capture paused video frame to canvas

I know how to copy on frame by frame basis from a playing HTML5 video to a canvas using 2D context.
But I want to work with a paused video, change dinamically its currentTime and copy current frame of video to canvas.
My guess is some process is not called yet when video position is set with currentTime property, although the video itself does update the image it shows (but not to the canvas).
I've found that it's posible to overcome this by setting a setTimeout to do the canvas ´drawImage´ in the next step.
You can see here a jsfiddle that proves the point.
As you can see in the fiddle you can play the video, and canvas updates, but if you pause the video, mouse scroll moves currentTime of video. There, a ´seTimeout´ is needed to update the canvas, if I call the drawImage method directly, canvas doesn't update.
In short, my question is:
Is there a better way to do this? Is it posible to do this without setTimeout and inside de loop itself? Pros & Cons?
Thank you very much for reading through here!
Every time you change the currentTime of your VideoElement, a seeked Event will trigger when the video actually changed its position.
var vid = document.getElementById("v");
var canvas = document.getElementById("c");
var context = canvas.getContext('2d');
var targetFrame = document.getElementById('t');
var cw = canvas.width = 200;
var ch = canvas.height = Math.round(cw / 1.7777);
var targetOffset = 0;
window.addEventListener('wheel', function(e) {
e.preventDefault();
targetOffset = targetOffset + (e.deltaY / 1000);
targetFrame.value = targetOffset;
seek(); // for demo purpose, we only listen to wheel
return false;
});
// that's all is needed
vid.addEventListener('seeked', function() {
context.drawImage(vid, 0, 0, cw, ch);
});
// for demo
// removed the rendering loop
// now it only changes the video's currentTime property
function seek() {
targetOffset = targetOffset * 0.9;
targetFrame.value = Math.round(targetOffset * 100) / 100;
var vct = vid.currentTime - targetOffset;
if (vct < 0) {
vct = vid.duration + vct;
} else if (vct > vid.duration) {
vct = vct - vid.duration;
}
vid.currentTime = vct;
}
.column {
float: left;
width: 50%;
}
.row:after {
content: "";
display: table;
clear: both;
}
#c {
border: 1px solid black;
}
<h3>
scroll up is forward
</h3>
<div class="row">
<div class="column">
<div>
Video element:
</div>
<video controls height="120" id="v" tabindex="-1" autobuffer="auto" preload="auto">
<source type="video/webm" src="https://www.html5rocks.com/tutorials/video/basics/Chrome_ImF.webm"/>
</video>
</div>
<div class="column">
<div>
Canvas element:
</div>
<canvas id="c"></canvas>
<div>
Momentum: <input type=text id="t">
</div>
</div>
</div>

drawImage in canvas from a video frame change the hue

I wrote a simple script that take a frame from a video and draw it to a canvas. My problem is that the colors are changing between the video and the drawn image.
I put here the result next to the original to make it easier to see. The original one is on the left. It's seems to be way more visible on chrome browser btw. All the test I made where on OSX.
Here a snippet, canvas on left, video on right:
// Get our mask image
var canvas = document.querySelector(".canvas");
var video = document.querySelector(".video");
var ctx = canvas.getContext('2d');
function drawMaskedVideo() {
ctx.drawImage(video, 0, 0, video.videoWidth/2, video.videoHeight, 0,0, video.videoWidth/2, video.videoHeight);
}
requestAnimationFrame(function loop() {
drawMaskedVideo();
requestAnimationFrame(loop.bind(this));
});
html, body {
margin: 0 auto;
}
.video, .canvas {
width: 100%;
}
.canvas {
position: absolute;
top: 0;
left: 0;
}
<video class="video" autoplay="autoplay" muted="muted" preload="auto" loop="loop">
<source src="http://mazwai.com/system/posts/videos/000/000/214/original/finn-karstens_winter-wonderland-kiel.mp4" type="video/mp4">
</video>
<canvas class='canvas' width='1280' height='720'></canvas>
I'd like to know why this thing happen, and if it possible to get rid of it in a cross browser way ?
Here the simple script I wrote:
let video = document.querySelector('#my-video') // .mp4 file used
let w = video.videoWidth;
let h = video.videoHeight;
let canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
let ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, w, h)
document.querySelector('.canvas-container').appendChild(canvas);
The solution might be as simple as setting a css filter to the video element:
.video {
-webkit-filter: contrast(100%);
}
I can't reason about this since it was discovered accident (playing with your demo and reading related answers), so I leave the technical explanation for someone else and leave you with some magic for now.
Any sufficiently advanced technology is indistinguishable from magic.
— Arthur C. Clarke
// Get our mask image
var canvas = document.querySelector(".canvas");
var video = document.querySelector(".video");
var ctx = canvas.getContext('2d');
function drawMaskedVideo() {
ctx.drawImage(video, 0, 0, video.videoWidth/2, video.videoHeight, 0,0, video.videoWidth/2, video.videoHeight);
}
requestAnimationFrame(function loop() {
drawMaskedVideo();
requestAnimationFrame(loop.bind(this));
});
html, body {
margin: 0 auto;
}
.video, .canvas {
width: 100%;
}
.video {
-webkit-filter: contrast(100%);
}
.canvas {
position: absolute;
top: 0;
left: 0;
}
<video class="video" autoplay="autoplay" muted="muted" preload="auto" loop="loop">
<source src="http://mazwai.com/system/posts/videos/000/000/214/original/finn-karstens_winter-wonderland-kiel.mp4" type="video/mp4">
</video>
<canvas class='canvas' width='1280' height='720'></canvas>
Note:
Running this on a Macbook Pro (2,3 GHz Intel Core i5) I could see no difference performance wise. Tracked CPU during the video playback and both demos idle at around 28%.

randomise array html5 java script

<!-- with thanks to http://stackoverflow.com/questions/25407926/spawn-random-images-
in-canvas-in-javascript-->
<!--http://www.freesfx.co.uk/download/?type=mp3&id=11028
--audio loader--
http://stackoverflow.com/questions/18826147/javascript-audio-play-on-
click-->
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<title>Street</title>
<script type="text/javascript">
var can, ctx;
var sprite = new Array();
var counter = 0;
var rot = 0;
var centerX = -320;
var centerY = -170;
var sprite = new Array(id); // Array to hold the filenames
function init() {
can = document.getElementById("can");
ctx = can.getContext("2d");
// get images into array
sprite[0] = document.getElementById("b1");
sprite[1] = document.getElementById("b2");
sprite[2] = document.getElementById("b3");
sprite[3] = document.getElementById("b4");
// draw lights out
draw();
// wait 3 sec, then begin animation
var t = setTimeout(light, 30);
}
function light() {
var wait = 600;
counter++;
if (counter == 4) {
counter = 0;
wait += (Math.random() * 1500);
rot += .01;
}
draw();
setTimeout(light, wait);
}
function draw() {
ctx.clearRect(0, 0, can.width, can.height);
ctx.save();
ctx.translate(can.width / 2, can.height / 2);
ctx.drawImage(sprite[counter], centerX, centerY);
ctx.restore();
}
function choseRandom(range) {
if (Math.random)
return Math.round(Math.random() * (range-1));
else {
var now = new Date();
return (now.getTime() / 1000) % range;
}
}
var choice = choseRandom(id);
</script>
</head>
<body onload="init()">
<audio id="Mp3Me" autoplay autobuffer controls>
<source src="au1.mp3">
<source src="au1.ogg">
</audio>
<img id="b1" style="display:none" src="1.png" >
<img id="b2" style="display:none" src="2.png" >
<img id="b3" style="display:none" src="3.png" >
<img id="b4" style="display:none" src="4.png" >
<canvas class="canvas" id="can" width="640" height="350" style=" border:1px solid #6F2E0D; ">
</canvas>
<script>
function play(){
var audio = document.getElementById("audio");
audio.play();
}
</script>
<input type="button" value="PLAY" onclick="play()">
<audio id="audio" src="door.mp3" ></audio>
<div id="container"></div>
<script language="JavaScript">
document.writeln('<td' + '><img src="'
+ ranimage[choice] + '" height="180" width="160" border="0" ><' +
'/td>');
</script>
<div id='container'>
<img id = "image2" src='door.png' />
</body>
</html>
The above code works with thanks to stack overflow.
Basically at the moment this code displays images in sequence non randomly, it uses the array to fetch them, and show them. The code then regulates the speed of the image display. There is also a sound player, and a button with a sound.
I managed after some considerable searching to animate a simple sequence of png files. However I have been trying to ad start stop button and a math random function (preferably the music on-click would start everything going).
I want to add a random function to the array,so that it displays images randomly. however the best I could do was, not to brake the code, or to get is to speed up the animation. Can some one please modify my code to add these functions or please point me to some place that would help.
The randomized array would be really useful.
Demo: http://jsfiddle.net/techsin/dtz0yj4y/
Code
function shuffle (arr) {
arr.forEach(function(e,i){
var rand = ~~(Math.random()*(arr.length-1));
arr[i] = arr[rand];
arr[rand] = e;
});
}
var myArr = [1,2,3,4,5];
shuffle(myArr); //myArr is now shuffled!
Example...
(there was a mistake, updated)
For example,
var array = [1,2,3,4,5]
for(i=0; i<array.length;i++){
var dist = Math.floor( Math.random() * array.length )
var swp = array[i]
array[i] = array[dist]
array[dist] = swp
}
console.log(array) //=> shuffled

How use canvas from external video?

I have the following code:
<!DOCTYPE html>
<title>Video/Canvas Gray Effect</title>
<script>
document.addEventListener('DOMContentLoaded', function(){
var v = document.getElementById('v');
var canvas = document.getElementById('c');
var context = canvas.getContext('2d');
var back = document.createElement('canvas');
var backcontext = back.getContext('2d');
var cw,ch;
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;
// Loop through the pixels, turning them grayscale
for(var i = 0; i < data.length; i+=4) {
var r = data[i];
var g = data[i+1];
var b = data[i+2];
var brightness = (3*r+4*g+b)>>>3;
data[i] = brightness;
data[i+1] = brightness;
data[i+2] = brightness;
}
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);
}
</script>
<video id=v controls loop>
<source src=video.webm type=video/webm>
</video>
<canvas id=c></canvas>
<style>
#c {
position: absolute;
top: 50%;
left: 50%;
margin: -180px 0 0 20px;
}
#v {
position: absolute;
top: 50%;
left: 50%;
margin: -180px 0 0 -500px;
}
</style>
The canvas work only if the video hosted in my site, but if a external video the canvas not working only work if make a proxy using the same domain, for example:
Working if a hosted the video on my site:
<video id=v controls loop>
<source src=video.webm type=video/webm>
</video>
Working if a use a proxy, but I will not use a proxy:
<video id=v controls loop>
<source src=./proxy.php?url_toexternal_video=http://host.com/video.webm type=video/webm>
</video>
Not working if a use the direct link to the video:
<video id=v controls loop>
<source src=http://host.com/video.webm type=video/webm>
</video>
any way to make it work if it is from an external video? Thanks! ;)
Nope, there's no way to use getImageData on a canvas that has been tainted by cross-origin content.

Categories