Reputation: 3
I loop over a part of a HTML video and simultaneously draw a Canvas with the current frame of the video. When the Videos starts over, there is always 1 gray frame at the canvas. If the loop region is long, its not a big problem, but for my needs these regions are maybe 0.5 seconds and then the canvas starts to flicker if you loop over and over again.
When drawing the canvas, I also tried different video properties (ended, loop, networkState, readyState) - doesnt help
I provided a jsfiddle to show you my problem. (just press play at the video) https://jsfiddle.net/Lz17fnf3/2/
$('#v').on('timeupdate', function () {
if ($('#v')[0].currentTime > 2) {//Loop for one second
$('#v')[0].currentTime = 1;
}
var $this = $('#v')[0]; //cache
(function loop() {
if (!$this.paused && !$this.ended) {
drawCanvas();
setTimeout(loop, 1000 / 25); // drawing at 25fps
}
})();
});
function drawCanvas() {
var elem = document.getElementById('c');
var c = elem.getContext('2d');
var v = $('#v')[0];
$('#c').attr('width', v.videoWidth);
$('#c').attr('height', v.videoHeight);
if (v.readyState == 4) {
c.drawImage(v, 0, 0, v.videoWidth, v.videoHeight, 0, 0, v.videoWidth, v.videoHeight);
}
}
Upvotes: 0
Views: 1169
Reputation: 1588
The reason it flickers is because when you assign the width
or height
to a canvas element, this action resets the entire context of the canvas, most likely that is causing the blank frame. Try moving all the canvas/context definitions outside the drawCanvas
.
Something like:
var elem = document.getElementById('c');
var c = elem.getContext('2d');
var v = $('#v')[0];
// In order to set the canvas width & height, we need to wait for the video to load.
function init() {
if (v.readyState == 4) {
$('#c').attr('width', v.videoWidth);
$('#c').attr('height', v.videoHeight);
} else {
requestAnimationFrame(init);
}
}
init();
$('#v').on('timeupdate', function () {
if ($('#v')[0].currentTime > 2) { //Loop for one second
$('#v')[0].currentTime = 1;
}
var $this = $('#v')[0]; //cache
(function loop() {
if (!$this.paused && !$this.ended) {
drawCanvas();
setTimeout(loop, 1000 / 25); // drawing at 25fps
}
})();
});
function drawCanvas() {
c.drawImage(v, 0, 0, v.videoWidth, v.videoHeight, 0, 0, v.videoWidth, v.videoHeight);
}
Upvotes: 1