Skip to content

Instantly share code, notes, and snippets.

@adamjimenez
Created July 3, 2013 13:36
Show Gist options
  • Star 37 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save adamjimenez/5917897 to your computer and use it in GitHub Desktop.
Save adamjimenez/5917897 to your computer and use it in GitHub Desktop.
Generate thumbnails from video files using HTML5's video tag and canvas
<?php
//where you want your thumbnails to go
$thumbs_dir = 'uploads/thumbs/';
//this should be an array of video paths
$videos = array();
if( $_POST["name"] ){
// Grab the MIME type and the data with a regex for convenience
if (!preg_match('/data:([^;]*);base64,(.*)/', $_POST['data'], $matches)) {
die("error");
}
// Decode the data
$data = $matches[2];
$data = str_replace(' ','+',$data);
$data = base64_decode($data);
file_put_contents($thumbs_dir.$file, $data);
print 'done '.$name;
exit;
}
?>
<video id="video" src="" onerror="failed(event)" controls="controls" preload="none"></video>
<script>
var videos = <?=json_encode($videos);?>;
var index = 0;
var video = document.getElementById('video');
video.addEventListener('canplay', function() {
this.currentTime = this.duration / 2;
}, false);
video.addEventListener('seeked', function() {
getThumb();
}, false);
function nextVideo(){
if(videos[index]){
video.src = '/uploads/'+videos[index];
console.log(index);
console.log('loading: '+video.src);
video.load();
index++;
}else{
console.log('done');
}
}
function getThumb(){
var filename = video.src;
var w = video.videoWidth;//video.videoWidth * scaleFactor;
var h = video.videoHeight;//video.videoHeight * scaleFactor;
var canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, w, h);
//document.body.appendChild(canvas);
var data = canvas.toDataURL("image/jpg");
//send to php script
var xmlhttp = new XMLHttpRequest;
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
console.log('saved');
nextVideo();
}
}
console.log('saving');
xmlhttp.open("POST", location.href, true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send('name='+encodeURIComponent(filename)+'&data='+data);
}
function failed(e) {
// video playback failed - show a message saying why
switch (e.target.error.code) {
case e.target.error.MEDIA_ERR_ABORTED:
console.log('You aborted the video playback.');
break;
case e.target.error.MEDIA_ERR_NETWORK:
console.log('A network error caused the video download to fail part-way.');
break;
case e.target.error.MEDIA_ERR_DECODE:
console.log('The video playback was aborted due to a corruption problem or because the video used features your browser did not support.');
break;
case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
console.log('The video could not be loaded, either because the server or network failed or because the format is not supported.');
break;
default:
console.log('An unknown error occurred.');
break;
}
nextVideo();
}
//let's go
nextVideo();
</script>
@fatihmert
Copy link

Nice !
So How to can HTML5 get video frame image?

@adamjimenez
Copy link
Author

see line 19 when it's saved to the thumbs folder.

Copy link

ghost commented Aug 23, 2015

Looks really nice.
But I can't really get it to work. First I tried to upload a file via POST but that seems wrong.

I can't manage to find out how to start. Is there a basic HOW TO for newbies?

@hostagex
Copy link

There are a few things wrong with the above code. Not sure how the poster was able to even run this. But you need to get a better name for the file you will be saving. Line:54. As this grabs the entire url for the video and then sends that off as the file name. I would suggest stripping the last 4 lines of the videos[index-1] at the same place. And then adding '.jpg' at the end of the filename. Passing that in a post will work. Then change the $file on line 19 to be the variable in the $_POST['name']. You will also need to fill the array with the files you want to create thumbnails for. By doing

$videos = array('path/file.mp4',path/2file.mp4','/path/to/file/3.mp4');

@fre2mansur
Copy link

is there any way to get screenshot from video url?

@Vishal949
Copy link

Message: Undefined index: name

@Lutex
Copy link

Lutex commented Jun 2, 2018

Very good! Thanks!

@LRoss16
Copy link

LRoss16 commented Jan 31, 2021

Has someone managed to get a working example of this? Trying to implement it but not been successful so far

@ahaomar
Copy link

ahaomar commented Jun 22, 2021

Not working undefine index name could you please explain more how exactly it working please

@adamjimenez
Copy link
Author

Disable PHP notices/ warnings.

@ahaomar
Copy link

ahaomar commented Jun 22, 2021

error_reporting(0);
error_reporting(E_ALL ^ E_WARNING);
error_reporting(E_ALL & ~E_WARNING & ~E_NOTICE);
after adding this warrning goes but still images not saved

`<?php
//where you want your thumbnails to go
$thumbs_dir = 'uploads/thumbs/';
error_reporting(0);
error_reporting(E_ALL ^ E_WARNING);
error_reporting(E_ALL & ~E_WARNING & ~E_NOTICE);
//this should be an array of video paths
$videos = array("animation.mp4");

if( $_POST["name"] ){
// Grab the MIME type and the data with a regex for convenience
if (!preg_match('/data:([^;]);base64,(.)/', $_POST['data'], $matches)) {
die("error");
}

// Decode the data
$data = $matches[2];
$data = str_replace(' ','+',$data);
$data = base64_decode($data);

file_put_contents($thumbs_dir.$file, $data);

print 'done '.$name;
exit;

}
?>

<script> var videos = ; var index = 0; var video = document.getElementById('video'); video.addEventListener('canplay', function() { this.currentTime = this.duration / 2; }, false); video.addEventListener('seeked', function() { getThumb(); }, false); function nextVideo(){ if(videos[index]){ video.src = '/uploads/'+videos[index]; console.log(index); console.log('loading: '+video.src); video.load(); index++; }else{ console.log('done'); } } function getThumb(){ var filename = video.src; var w = video.videoWidth;//video.videoWidth * scaleFactor; var h = video.videoHeight;//video.videoHeight * scaleFactor; var canvas = document.createElement('canvas'); canvas.width = w; canvas.height = h; var ctx = canvas.getContext('2d'); ctx.drawImage(video, 0, 0, w, h); //document.body.appendChild(canvas); var data = canvas.toDataURL("image/jpg"); //send to php script var xmlhttp = new XMLHttpRequest; xmlhttp.onreadystatechange = function(){ if (xmlhttp.readyState==4 && xmlhttp.status==200){ console.log('saved'); nextVideo(); } } console.log('saving'); xmlhttp.open("POST", location.href, true); xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xmlhttp.send('name='+encodeURIComponent(filename)+'&data='+data); } function failed(e) { // video playback failed - show a message saying why switch (e.target.error.code) { case e.target.error.MEDIA_ERR_ABORTED: console.log('You aborted the video playback.'); break; case e.target.error.MEDIA_ERR_NETWORK: console.log('A network error caused the video download to fail part-way.'); break; case e.target.error.MEDIA_ERR_DECODE: console.log('The video playback was aborted due to a corruption problem or because the video used features your browser did not support.'); break; case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED: console.log('The video could not be loaded, either because the server or network failed or because the format is not supported.'); break; default: console.log('An unknown error occurred.'); break; } nextVideo(); } //let's go nextVideo(); </script>`

@ahaomar
Copy link

ahaomar commented Jun 22, 2021

any idea please i am really stuck my server dont allow to install fmmpg extension i need solutions kindly guide me please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment