Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web based fullscreen slideshow with video elements

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

  • image.jpeg
  • image2.jpeg
  • videoclip.mp4
  • image3.jpeg
  • someothervide.mp4

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?

like image 679
Rati_Ge Avatar asked Dec 10 '12 19:12

Rati_Ge


2 Answers

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).

like image 182
insertusernamehere Avatar answered Nov 01 '22 16:11

insertusernamehere


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! ;)

like image 3
Dim13i Avatar answered Nov 01 '22 17:11

Dim13i