HTML5 Video - How to do a seamless play and/or loop of several videos?
After trying various things I have finally been able to create what seems to be a working solution. I haven't tested this on older browsers or other OSes, but this works on latest versions of Chrome, IE, Firefox and Opera. (Although some more feedback of whether this works on other systems would be appreciated)
The idea is to have all 3 videos output frames to HTML5 canvas. The original videos are hidden and preloaded in advance to avoid pause between loading.
Here is the code:
var playCounter = 0;
var clipArray = [];
var $video1 = $("#video1");
var $video2 = $("#video2");
var $video3 = $("#video3");
$video1.attr("src", "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4");
$video2.attr("src", "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerJoyrides.mp4");
$video3.attr("src", "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4");
var timerID;
var $canvas = $("#myCanvas");
var ctx = $canvas[0].getContext("2d");
function stopTimer() {
window.clearInterval(timerID);
}
$('#startPlayback').click(function() {
stopTimer();
playCounter = $('#playbackNum').val();
clipArray = [];
// addd element to the end of the array
clipArray.push(1);
for (var i = 0; i < playCounter; i++) {
clipArray.push(2);
}
clipArray.push(3);
$video2[0].load();
$video3[0].load();
$video1[0].play();
});
function drawImage(video) {
//last 2 params are video width and height
ctx.drawImage(video, 0, 0, 640, 360);
}
// copy the 1st video frame to canvas as soon as it is loaded
$video1.one("loadeddata", function() {
drawImage($video1[0]);
});
// copy video frame to canvas every 30 milliseconds
$video1.on("play", function() {
timerID = window.setInterval(function() {
drawImage($video1[0]);
}, 30);
});
$video2.on("play", function() {
timerID = window.setInterval(function() {
drawImage($video2[0]);
}, 30);
});
$video3.on("play", function() {
timerID = window.setInterval(function() {
drawImage($video3[0]);
}, 30);
});
function onVideoEnd() {
//stop copying frames to canvas for the current video element
stopTimer();
// remove 1st element of the array
clipArray.shift();
//IE fix
if (!this.paused) this.pause();
if (clipArray.length > 0) {
if (clipArray[0] === 1) {
$video1[0].play();
}
if (clipArray[0] === 2) {
$video2[0].play();
}
if (clipArray[0] === 3) {
$video3[0].play();
}
} else {
// in case of last video, make sure to load 1st video so that it would start from the 1st frame
$video1[0].load();
}
}
$video1.on("ended", onVideoEnd);
$video2.on("ended", onVideoEnd);
$video3.on("ended", onVideoEnd);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div id="border">
<video id="video1" width="640" height="360" hidden>
<source type="video/mp4">
Your browser does not support playing this Video
</video>
<video id="video2" width="640" height="360" hidden>
<source type="video/mp4">
Your browser does not support playing this Video
</video>
<video id="video3" width="640" height="360" hidden>
<source type="video/mp4">
Your browser does not support playing this Video
</video>
<div>
<canvas id="myCanvas" width="640" height="360"> </canvas>
</div>
<div role="controls">
<div>
<label>
Times the middle video will repeat itself:
</label>
</div>
<div>
<input id="playbackNum" value="1" />
</div>
<p>
<button id="startPlayback">Start</button>
</p>
</div>
</div>
Please note, the code is not very pretty and would benefit from some cleanup and optimization, but at least this should show the way to work around the problem and implement a seamless playback of several videos in HTML5. Also make sure to include jQuery source file in html file location for the code to work.
Related videos on Youtube
Tanuki
Updated on September 16, 2022Comments
-
Tanuki over 1 year
How can I reliably play several videos one after another seamlessly? As there is a small pause or flicker between playing 2 videos.
In my particular example I have 3 videos. I need to play all 3 of them seamlessly one after another, and I also need to loop middle video an arbitrary number of times (say 2 or 3). All of that needs to happen seamlessly and consistently across different browsers.
I've been trying everything under the moon, from starting video playback on video end, to using several video tags and hiding and replacing them, I even tried to implement this in Flash, but alas nothing works, and the same problem happens in current Flash as well.
I've seen this (or similar) question asked many times but I haven't seen a reliable solution yet.
Does anyone know a solution to this?
-
totymedli almost 6 yearsI crated a repo with different playlist techniques to see how seamless the different solutions are.
-
-
Tanuki over 8 yearsHi, thank you for the answer, but have you actually tried this yourself? I've seen a couple VideoJS answers that still haven't solved this. Also, if you know how to solve this with VideoJS, can you point me in a specific direction? As I know nothing about VideoJS.
-
myselfmiqdad over 8 yearsYes, I have worked with videoJS playlists. an example I have bookmarked is this github.com/jgallen23/videojs-playLists/blob/master/example/… there is also a playlist plugin for video js github.com/brightcove/videojs-playlist
-
Tanuki over 8 yearsOk, the 1st one doesn't work out of the box. I've removed poster images code and replaced online videos with my own links, but there still is a quick flicker (of loading animation mind you) in between the videos. It might be because of poster images, but I am very averse to the idea of having to create and load a picture of every video I want to play. Guess I will have to dig down deeper into this to see if that is possible in VideoJS at all. Still, thank you for the link, perhaps I will find the light at the end of this tunnel.
-
Zade about 7 yearsDo you have a URL where we can see this in action?
-
totymedli almost 6 yearsI created a video player with all the common controls in native JS based on this answer.
-
foba over 4 yearsIf you try doing this with really short clips with audio it sounds/looks choppy. I might try finding a solution to this but if someone else does in the meantime that would be great!
-
Tanuki over 4 yearsYes, I also found later that this solution doesnt work 100% for short clips. In some cases it would look jittery no matter what I did. I think I tried everything I could think of back then, but nothing really solved the problem. I am not sure how big people at youtube or say pluralsight can play back videos so consistently well. I am very surprised this question suddenly started gaining traction after 2 years since I posted it. But if anyone is looking at this now, please note that this is not a 100% working solution. Although if anyone can provide a fully working solution that would be great!
-
Will about 4 yearssmart solution. but not the best on mobile (IOS safari)