I have an issue with getting a snapshot from a video to use as a header image. Underneath I have the code I currently use, but the output I get is only a black image. In the console I don't get any issues. I do this after I have uploaded the video to the fileserver I use.
let video = $(videoPath).find('#newVideo').get(0);
let canvas = document.createElement('canvas');
video.onloadedmetadata = function() {
video.play();
canvas.width = 640;
canvas.height = 480;
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
var dataURI = canvas.toDataURL('image/jpeg');
let $previewBox = $(".post-preview-box");
let $previewCardImg = $previewBox.find(".card-img");
I have used How to take a snapshot of HTML5-JavaScript-based video player? as a base to get a snapshot and then added some other things in the hope it would work, but so far I have been unable to do.
Any help or input on what to try is welcome.
Edit 04-03-2020 (april third): To give more clarification I will add a console out of the dataURI and changes to code I made.
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCACWASwDAREAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD8qqACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD//2Q==
Added the currentTime of the video and set it to 3 (I also have tried it with 5).
let video = $(videoPath).find('#newVideo').get(0);
let canvas = document.createElement('canvas');
video.onloadedmetadata = function() {
video.currentTime = 3;
video.play();
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
var dataURI = canvas.toDataURL('image/jpeg');
let $previewBox = $(".post-preview-box");
console.log(dataURI);
let $previewCardImg = $previewBox.find(".card-img");
Without seeing all your code, here is an example which gets 10 screens.
var screens = [];
var video = document.getElementById('video');
var video_preview = document.getElementById('video_preview');
var loadingContainer = document.getElementById('loading-container')
function loadVideo(event) {
loadingContainer.style.display = 'block'
screens = [];
var reader = new FileReader()
reader.onload = function(e) {
video.src = video_preview.src = e.target.result;
video.autoplay = video_preview.autoplay = true;
video.hasLoaded = video_preview.hasLoaded = false;
video_preview.addEventListener('canplay', function() {
video_preview.hasLoaded = true;
video.play();
})
video.addEventListener('canplay', function() {
// first time
if (!video.hasLoaded) {
console.log('Loaded: video duration: ', this.duration, event.target.files[0].size)
loadingContainer.innerText = 'Generating screens...'
video.hasLoaded = true;
var self = this;
(function repeat(i) {
setTimeout(function() {
var timestamp = ((self.duration / 10) * i) / 1.1; // fudge abit so dont get start/end frames
console.log('seeking to:', timestamp)
self.currentTime = timestamp
if (--i) {
// next
repeat(i);
} else {
//
loadingContainer.style.display = 'none'
// all screens grabbed
var str = '<div style="position:relative;width:calc(100% + .25rem)">'
screens.reverse().forEach(function(screen) {
str += '<img src="' + screen + '" style="width:32%" class="img-thumbnail m-1" />';
});
str += '</div>';
document.getElementById("screens-container").innerHTML = str;
}
}, 500) // how fast to attempt to grab screens
})(11); // iterations i.e how many screens
}
}, false);
video.addEventListener('seeked', function() {
console.log('grabbing screen for', this.currentTime)
takeScreen();
}, false);
}
reader.readAsDataURL(event.target.files[0]);
}
function takeScreen() {
var filename = video.src;
var w = video.videoWidth;
var h = video.videoHeight;
var canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, w, h);
var data = canvas.toDataURL("image/jpg");
screens.push(data)
loadingContainer.innerText = 'Generated ' + screens.length + ' out of 10 screens...'
}
function failed(e) {
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;
}
}
body,
html {
margin: 0;
padding: 0
}
li {
display: inline-block;
list-style-type: none
}
.jumbotron {
margin-bottom: 1rem;
}
<div class="container">
<div class="card">
<div class="card-header" style="background-color: #e9ecef">
<h5 class="card-title">Video Preview</h5>
<video id="video_preview" onerror="failed(event)" controls="controls" preload="none" muted style="width: 100%"></video>
<video id="video" onerror="failed(event)" controls="controls" preload="none" muted style="display:none"></video>
<div class="card-body">
<a href="javascript:void(0)" class="btn btn-sm btn-primary btn-block" onClick="$('[type=\'file\']').trigger('click')">
<i class="fa fa-upload"></i> Load Video
</a>
<form id="uploadForm" ref="uploadForm" action='/upload' method='post' enctype="multipart/form-data">
<input type="file" name="file" accept="video/*" style="display: none" onchange="loadVideo(event)">
</form>
<div id="loading-container" style="display:none">Loading...</div>
</div>
<div class="card-body">
<h5 class="card-title">Screens</h5>
<div id="screens-container"></div>
</div>
</div>
</div>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
For a more complete example see: https://codesandbox.io/s/clipseed-hfhee
</div>