/* BigVideo - The jQuery Plugin for Big Background Video (and Images) by John Polacek (@johnpolacek) Dual licensed under MIT and GPL. Dependencies: jQuery, jQuery UI (Slider), Video.js, ImagesLoaded */ (function (factory) { 'use strict'; if (typeof define === 'function' && define.amd) { // Register as an anonymous AMD module: define([ 'jquery', 'videojs', 'imagesloaded', 'jquery-ui' ], factory); } else { factory(jQuery, videojs); } })(function($, videojs) { $.BigVideo = function(options) { var defaults = { // If you want to use a single mp4 source, set as true useFlashForFirefox:true, // If you are doing a playlist, the video won't play the first time // on a touchscreen unless the play event is attached to a user click forceAutoplay:false, controls:false, doLoop:false, container:$('body'), shrinkable:false }; var BigVideo = {}, player, vidEl = '#big-video-vid', wrap = $('
'), video = $(''), mediaAspect = 16/9, vidDur = 0, defaultVolume = 0.8, isInitialized = false, isSeeking = false, isPlaying = false, isQueued = false, isAmbient = false, playlist = [], currMediaIndex, currMediaType; var settings = $.extend({}, defaults, options); function updateSize() { var containerW = settings.container.outerWidth() < $(window).width() ? settings.container.outerWidth() : $(window).width(), containerH = settings.container.outerHeight() < $(window).height() ? settings.container.outerHeight() : $(window).height(), containerAspect = containerW/containerH; if (settings.container.is($('body'))) { $('html,body').css('height',$(window).height() > $('body').css('height','auto').height() ? '100%' : 'auto'); } if (containerAspect < mediaAspect) { // taller if (currMediaType == 'video') { player .width(containerH*mediaAspect) .height(containerH); if (!settings.shrinkable) { $(vidEl) .css('top',0) .css('left',-(containerH*mediaAspect-containerW)/2) .css('height',containerH); } else { $(vidEl) .css('top',-(containerW/mediaAspect-containerH)/2) .css('left',0) .css('height',containerW/mediaAspect); } $(vidEl+'_html5_api') .css('width',containerH*mediaAspect) .css('height',containerH); $(vidEl+'_flash_api') .css('width',containerH*mediaAspect) .css('height',containerH); } else { // is image $('#big-video-image') .css({ width: 'auto', height: containerH, top:0, left:-(containerH*mediaAspect-containerW)/2 }); } } else { // wider if (currMediaType == 'video') { player .width(containerW) .height(containerW/mediaAspect); $(vidEl) .css('top',-(containerW/mediaAspect-containerH)/2) .css('left',0) .css('height',containerW/mediaAspect); $(vidEl+'_html5_api') .css('width',$(vidEl+'_html5_api').parent().width()+"px") .css('height','auto'); $(vidEl+'_flash_api') .css('width',containerW) .css('height',containerW/mediaAspect); } else { // is image $('#big-video-image') .css({ width: containerW, height: 'auto', top:-(containerW/mediaAspect-containerH)/2, left:0 }); } } } function initPlayControl() { // create video controls var markup = ''+ '
'+ '
'+ ''+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'; settings.container.append(markup); // hide until playVideo $('#big-video-control-container').css('display','none'); $('#big-video-control-timer').css('display','none'); // add events $('#big-video-control-track').slider({ animate: true, step: 0.01, slide: function(e,ui) { isSeeking = true; $('#big-video-control-progress').css('width',(ui.value-0.16)+'%'); player.currentTime((ui.value/100)*player.duration()); }, stop:function(e,ui) { isSeeking = false; player.currentTime((ui.value/100)*player.duration()); } }); $('#big-video-control-bar').click(function(e) { player.currentTime((e.offsetX/$(this).width())*player.duration()); }); $('#big-video-control-play').click(function(e) { e.preventDefault(); playControl('toggle'); }); player.on('timeupdate', function() { if (!isSeeking && (player.currentTime()/player.duration())) { var currTime = player.currentTime(); var minutes = Math.floor(currTime/60); var seconds = Math.floor(currTime) - (60*minutes); if (seconds < 10) seconds='0'+seconds; var progress = player.currentTime()/player.duration()*100; $('#big-video-control-track').slider('value',progress); $('#big-video-control-progress').css('width',(progress-0.16)+'%'); $('#big-video-control-timer').text(minutes+':'+seconds+'/'+vidDur); } }); } function playControl(a) { var action = a || 'toggle'; if (action == 'toggle') action = isPlaying ? 'pause' : 'play'; if (action == 'pause') { player.pause(); $('#big-video-control-play').css('background-position','-16px'); isPlaying = false; } else if (action == 'play') { player.play(); $('#big-video-control-play').css('background-position','0'); isPlaying = true; } else if (action == 'skip') { nextMedia(); } } function setUpAutoPlay() { player.play(); settings.container.off('click',setUpAutoPlay); } function nextMedia() { currMediaIndex++; if (currMediaIndex === playlist.length) currMediaIndex=0; playVideo(playlist[currMediaIndex]); } function playVideo(source) { // clear image $(vidEl).css('display','block'); currMediaType = 'video'; player.src(source); isPlaying = true; if (isAmbient) { $('#big-video-control-container').css('display','none'); player.ready(function(){ player.volume(0); }); doLoop = true; } else { $('#big-video-control-container').css('display','block'); player.ready(function(){ player.volume(defaultVolume); }); doLoop = false; } $('#big-video-image').css('display','none'); $(vidEl).css('display','block'); } function showPoster(source) { // remove old image $('#big-video-image').remove(); // hide video player.pause(); $(vidEl).css('display','none'); $('#big-video-control-container').css('display','none'); // show image currMediaType = 'image'; var bgImage = $(''); wrap.append(bgImage); $('#big-video-image').imagesLoaded(function() { mediaAspect = $('#big-video-image').width() / $('#big-video-image').height(); updateSize(); }); } BigVideo.init = function() { if (!isInitialized) { // create player settings.container.prepend(wrap); var autoPlayString = settings.forceAutoplay ? 'autoplay' : ''; player = $(''); player.css('position','absolute'); wrap.append(player); var videoTechOrder = ['html5','flash']; // If only using mp4s and on firefox, use flash fallback var ua = navigator.userAgent.toLowerCase(); var isFirefox = ua.indexOf('firefox') != -1; if (settings.useFlashForFirefox && (isFirefox)) { videoTechOrder = ['flash', 'html5']; } player = videojs(vidEl.substr(1), { controls:false, autoplay:true, preload:'auto', techOrder:videoTechOrder }); // add controls if (settings.controls) initPlayControl(); // set initial state updateSize(); isInitialized = true; isPlaying = false; if (settings.forceAutoplay) { $('body').on('click', setUpAutoPlay); } $('#big-video-vid_flash_api') .attr('scale','noborder') .attr('width','100%') .attr('height','100%'); // set events $(window).on('resize.bigvideo', function() { updateSize(); }); player.on('loadedmetadata', function(data) { if (document.getElementById('big-video-vid_flash_api')) { // use flash callback to get mediaAspect ratio mediaAspect = document.getElementById('big-video-vid_flash_api').vjs_getProperty('videoWidth')/document.getElementById('big-video-vid_flash_api').vjs_getProperty('videoHeight'); } else { // use html5 player to get mediaAspect mediaAspect = $('#big-video-vid_html5_api').prop('videoWidth')/$('#big-video-vid_html5_api').prop('videoHeight'); } updateSize(); var dur = Math.round(player.duration()); var durMinutes = Math.floor(dur/60); var durSeconds = dur - durMinutes*60; if (durSeconds < 10) durSeconds='0'+durSeconds; vidDur = durMinutes+':'+durSeconds; }); player.on('ended', function() { if (settings.doLoop) { player.currentTime(0); player.play(); } if (isQueued) { nextMedia(); } }); } }; /** * Show video or image file * * @param source: The file to show, can be: * - an array with objects for video files types * - a string to a single video file * - a string to a image file * @param options: An object with those possible attributes: * - boolean "ambient" to set video to loop * - function onShown */ BigVideo.show = function(source,options) { if (options === undefined) options = {}; isAmbient = options.ambient === true; if (isAmbient || options.doLoop) settings.doLoop = true; if (typeof(source) === 'string') { // if input was a string, try show that image or video var ext = ( source.lastIndexOf('?') > 0 ) ? source.substring(source.lastIndexOf('.')+1, source.lastIndexOf('?')) : source.substring( source.lastIndexOf('.')+1); if (ext == 'jpg' || ext == 'gif' || ext == 'png') { showPoster(source); } else if (ext == 'mp4' || ext == 'ogg' || ext == 'ogv'|| ext == 'webm') { playVideo(source); if (options.onShown) options.onShown(); isQueued = false; } } else if ($.isArray(source)) { // if the input was an array, pass it to videojs playVideo(source); } else if (typeof(source) === "object" && source.src && source.type) { // if the input was an object with valid attributes, wrap it in an // array and pass it to videojs playVideo([source]); } else { // fail without valid input throw("BigVideo.show received invalid input for parameter source"); } }; /** * Show a playlist of video files * * @param files: array of elements to pass to BigVideo.show in sequence * @param options: An object with those possible attributes: * - boolean "ambient" to set video to loop * - function onShown */ BigVideo.showPlaylist = function (files, options) { if (!$.isArray(files)) { throw("BigVideo.showPlaylist parameter files accepts only arrays"); } if (options === undefined) options = {}; isAmbient = options.ambient === true; if (isAmbient || options.doLoop) settings.doLoop = true; playlist = files; currMediaIndex = 0; this.show(playlist[currMediaIndex]); if (options.onShown) options.onShown(); isQueued = true; }; // Expose Video.js player BigVideo.getPlayer = function() { return player; }; // Remove/dispose the player BigVideo.remove = BigVideo.dispose = function() { isInitialized = false; wrap.remove(); $(window).off('resize.bigvideo'); if(player) { player.off('loadedmetadata'); player.off('ended'); player.dispose(); } }; // Expose BigVideoJS player actions play, pause, skip (if a playlist is available) // Example: BigVideo.triggerPlayer('skip') BigVideo.triggerPlayer = function(action){ playControl(action); }; return BigVideo; }; });