I want to develop HTML 5 based slideshow with images and videos on full screen. this will be some sort of screensaver on one of our kiosks when there is no user activity for a couple of minutes. we already have image based slideshow on full-screen implemented so there is no problem with this, but now we want to add Video auto-playback functionality as well so for example lets say this is the order of screensaver content
after jquery script runs we want to run through those files continuously and either show image for few seconds or auto-start video and move to the next slide when playing video is finished
can someone suggest how to do this and if there are any already implemented plugins for jQuery can you provide with links?
Actually this is pretty easy to solve. Find all explanations within the comments of the JavaScript. Wrap that all in a closure like $(document).ready(function () {});
and you're ready to go.
HTML
<div id="canvas" class="canvas"></div>
CSS
div.canvas {
display: table-cell;
width: 1280px;
height: 800px;
background: black;
vertical-align: middle;
}
div.canvas > video {
display: block;
margin: auto;
}
div.canvas > img {
display: block;
margin: auto;
}
JavaScript - Variables
// array containing links to the content
var content = ['movie_1.m4v', 'movie_2.m4v', 'image_1.jpg', 'image_2.jpg'];
// element where anything will be played
var canvas = $('#canvas');
// duration an image is shown in ms (milliseconds)
var durationImage = 1000;
// basic source for image and video tag
var srcImage = '<img src="$" alt="">';
var srcVideo = '<video autoplay><source src="$" type="video/mp4"></source></video>';
// current position
var current = -1;
// regex for getting file extension (from http://stackoverflow.com/questions/680929/how-to-extract-extension-from-filename-string-in-javascript)
var regex = /(?:\.([^.]+))?$/;
JavaScript - Function
// method to play the next content element
function playNext() {
// increase current element and set it to 0 if end is reached
++current;
if (content.length == current) {
current = 0;
}
// get file and its extension and check whether it's valid
var source = null;
var file = content[current];
var extension = regex.exec(file)[1];
if ('jpg' == extension) {
source = srcImage;
}
if ('m4v' == extension) {
source = srcVideo;
}
// if source seems valid
if (null !== source) {
// replace placeholder with the content and insert content into canvas
source = source.replace('$', file);
canvas.html(source);
// if content is an image play next after set duration
if ('jpg' == extension) {
setTimeout(function() { playNext(); }, durationImage);
}
// if content is a video, bind 'onend' event handler to it, to play next
if ('m4v' == extension) {
canvas.find('video').bind("ended", function() {
playNext();
});
}
}
}
JavaScript - Finally: initial function call
// show first (remember current = -1 from above :) )
playNext();
Demo
Demo on jsfiddle.net
A note on the demo: The demo runs in Safari only (maybe in IE9 too) because of the video format provided (video/quicktime).
First of all I'll start by giving you this LINK. Here you can find a lot of useful information about video events (like: ended, loaded, playing, etc.).
Also, here is the LINK to the fiddle/demo (tested on Chrome).
This is the html structure:
<section class="slideshow">
<ul>
<img src="" class="loader" />
<div class="pause"></div>
<li>img/video</li>
<li>img/video</li>
<li>img/video</li>
<li>img/video</li>
<li>img/video</li>
</ul>
</section>
We have a simple <section>
which contains all of our images and video. I've also added a GIF
loader to show that we are loading something at the beginning (there is no need to see the pictures loading slowly), and a Pause
button.
The Css to set all the elements and their size:
.slideshow {
width: 700px;
height: 300px;
background: #efefef;
position: relative;
background: white;
box-shadow: 0px 0px 5px black;
margin: 20px auto;
}
.slideshow ul {
width: 100%;
height: 100%;
position: relative;
list-style: none;
overflow: hidden;
display: none;
}
.slideshow ul li {
position: absolute;
left: 100%;
}
.slideshow ul li:first-child {
left: 0%;
}
video {
background: #434343;
}
.loader {
width: 50px;
height: 50px;
position: absolute;
left: 50%;
top: 50%;
margin-left: -25px;
margin-top: -25px;
}
.pause {
display: none;
width: 50px;
height: 50px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -25px;
margin-top: -25px;
border-radius: 50%;
background: rgba(0,0,0,.6);
z-index: 100;
line-height: 50px;
text-align: center;
font-size: 1.0em;
font-weight: bold;
color: white;
cursor: pointer;
}
And finally the Javascript/jQuery part:
// Some variables
var timer;
var sWidth = 400, sHeight = 200, border = 10;
var slideshowSet = false;
var video;
var videoSet = false;
var slidePause = false;
var $el;
var $currentEl = $('.slideshow').find('li').eq(0);
// On document ready
$(function() {
// Set slideshow dimensions + border
setSlideDimensions(sWidth, sHeight, border);
// Show pause button
$('.slideshow').hover(
function(){
if(slideshowSet) {
$('.pause').stop().fadeIn(200);
}
},
function() {
if(slideshowSet) {
$('.pause').fadeOut(200);
}
}
);
// Pause button
$('.pause').click(function() {
if($(this).text() == '| |') {
// Pause slideshow
slidePause = true;
$(this).text('►');
clearTimeout(timer);
if($currentEl.find('video').size() == 1){
video.pause();
}
} else {
// Play slideshow
$(this).text('| |');
if($currentEl.find('video').size() == 1){
video.play();
} else {
timer = setTimeout(slide, 2000);
}
}
});
});
// Window ready (all images loaded, but not videos!!)
$(window).ready(function() {
// Hide loader GIF
$('.loader').fadeOut(200);
// Show slideshow
$('.slideshow ul').fadeIn(200);
// Start slideshow
timer = setTimeout(slide, 2000);
slideshowSet = true;
});
// Function to slide
function slide() {
videoSet = false;
var $el = $('.slideshow').find('li');
$el.eq(1).add($el.eq(0)).animate({'left': '-='+sWidth}, {queue: false, duration: 300, complete: function() {
$el.eq(0).animate({'left': '100%'}, 0);
if($(this).index() == 1){
$('.slideshow ul').append($el.eq(0));
$currentEl = $el.eq(1);
// We chek if it's a video
if($(this).find('video').size() == 1) {
//If yes we set the variable
video = $(this).find('video')[0];
videoSets();
// If video can play
if (video.canPlayType) {
// Play video
video.play();
} else {
// Error message
alert('No html5');
}
} else {
// If not a video we set timeout to next slide
timer = setTimeout(slide, 2000);
}
}
}});
}
// Function to set all video events
function videoSets(){
if(!videoSet) {
videoSet = true;
// Video ended
video.addEventListener("ended", function () {
timer = setTimeout(slide, 2000);
});
// Video Playing
video.addEventListener("playing", function () {
clearTimeout(timer);
if(slidePause) {
$('.pause').text('| |');
video.play();
slidePause = false;
}
});
}
}
// Function to set slideshow dimensions
function setSlideDimensions(w, h, b) {
$('.slideshow').css({width: w, 'height': h, 'padding': b});
$('.slideshow ul li img, .slideshow ul li video').css({width: w, 'height': h});
}
There is more work to do with the video events. I would preload all videos if possible (not too big) and then start the slideshow so to be sure that there are no "empty moments". If you have too many videos you could start loading the first ones (2/3) and then start the slideshow. By putting the attribute preload
to your <video>
tag they will start and keep loading once the document is loaded (normally).
Also in your <video>
tag you can insert more than one video with all differents formats so that you expand its compatibility cross-browser.
If you have any other question feel free to ask. It may not be perfect as I did this for the first time! ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With