1/* BigVideo by John Polacek @johnpolacek Licensed under MIT and GPL. 2 Dependencies: jQuery, jQuery UI (Slider), Video.js, ImagesLoaded */ 3(function (factory) { 4 'use strict'; 5 if (typeof define === 'function' && define.amd) { 6 // Register as an anonymous AMD module: 7 define([ 8 'jquery', 9 'videojs', 10 'imagesloaded', 11 'jquery-ui' 12 ], factory); 13 } else { 14 factory(jQuery, videojs); 15 } 16})(function($, videojs) { 17 18 $.BigVideo = function(options, element) { 19 20 var defaults = { 21 // If you want to use a single mp4 source, set as true 22 useFlashForFirefox:true, 23 // If you are doing a playlist, the video won't play the first time 24 // on a touchscreen unless the play event is attached to a user click 25 forceAutoplay:false, 26 controls:false, 27 doLoop:false, 28 container: element ? $(element) : $('body'), 29 shrinkable:false 30 }; 31 32 var BigVideo = this, 33 player, 34 vidEl = '.big-video-vid', 35 wrap = $('<div class="big-video-wrap"></div>'), 36 video = $(''), 37 mediaAspect = 16/9, 38 vidDur = 0, 39 defaultVolume = 0.8, 40 isInitialized = false, 41 isSeeking = false, 42 isPlaying = false, 43 isQueued = false, 44 isAmbient = false, 45 playlist = [], 46 currMediaIndex, 47 currMediaType; 48 49 var settings = $.extend({}, defaults, options); 50 var container = settings.container; 51 var vid = container.find(vidEl); 52 53 function updateSize() { 54 var $body = $('body'), 55 $containerBVWrap = container.find('.big-video-wrap'), 56 windowW = $containerBVWrap.width(), 57 windowH = $containerBVWrap.height(), 58 windowAspect = windowW/windowH; 59 60 if ( settings.container.is( $body ) ) { 61 $( 'html,body' ).css( 'height', $( window ).height() > $body.css( 'height', 'auto' ).height() ? '100%' : 'auto' ); 62 } 63 if (windowAspect < mediaAspect) { 64 // taller 65 if (currMediaType === 'video') { 66 player 67 .width(windowH*mediaAspect) 68 .height(windowH); 69 if (!settings.shrinkable) { 70 vid 71 .css('top',0) 72 .css('left',-(windowH*mediaAspect-windowW)/2) 73 .css('height',windowH); 74 } else { 75 vid 76 .css('top',-(windowW/mediaAspect-windowH)/2) 77 .css('left',0) 78 .css('height',windowW/mediaAspect); 79 } 80 container.find(vidEl+'_html5_api') 81 .css('width',windowH*mediaAspect) 82 .css('height',windowH); 83 container.find('object[id*=_flash_api]').parent() 84 .css('width',$(window).height()*mediaAspect) 85 .css('height',$(window).height()); 86 container.find('video').css('width', ''); 87 } else { 88 // is image 89 container.find('.big-video-image') 90 .css({ 91 width: 'auto', 92 height: windowH, 93 top:0, 94 left:-(windowH*mediaAspect-windowW)/2 95 }); 96 } 97 } else { 98 // wider 99 if (currMediaType === 'video') { 100 player 101 .width(windowW) 102 .height(windowW/mediaAspect); 103 vid 104 .css('top',-(windowW/mediaAspect-windowH)/2) 105 .css('left',0) 106 .css('height',windowW/mediaAspect); 107 container.find(vidEl+'_html5_api') 108 .css('width',container.find(vidEl+'_html5_api').parent().width()+"px") 109 .css('height','auto'); 110 container.find('object[id*=_flash_api]').parent() 111 .css('width', $(window).width()) 112 .css('height',$(window).width()/mediaAspect); 113 container.find('video').css('width', '100%'); 114 } else { 115 // is image 116 container.find('.big-video-image') 117 .css({ 118 width: windowW, 119 height: 'auto', 120 top:-(windowW/mediaAspect-windowH)/2, 121 left:0 122 }); 123 } 124 } 125 } 126 127 function initPlayControl() { 128 // create video controller 129 var markup = [ 130 '<div class="big-video-control-container">', 131 '<div class="big-video-control">', 132 '<a href="#" class="big-video-control-play"></a>', 133 '<div class="big-video-control-middle">', 134 '<div class="big-video-control-bar">', 135 '<div class="big-video-control-bound-left"></div>', 136 '<div class="big-video-control-progress"></div>', 137 '<div class="big-video-control-track"></div>', 138 '<div class="big-video-control-bound-right"></div>', 139 '</div>', 140 '</div>', 141 '<div class="big-video-control-timer"></div>', 142 '</div>', 143 '</div>' 144 ].join(''); 145 container.append(markup); 146 147 // hide until playVideo 148 container.find('.big-video-control-container').css('display','none'); 149 container.find('.big-video-control-timer').css('display','none'); 150 151 // add events 152 container.find('.big-video-control-track').slider({ 153 animate: true, 154 step: 0.01, 155 slide: function(e,ui) { 156 isSeeking = true; 157 container.find('.big-video-control-progress').css('width',(ui.value-0.16)+'%'); 158 player.currentTime((ui.value/100)*player.duration()); 159 }, 160 stop:function(e,ui) { 161 isSeeking = false;
162 player.currentTime((ui.value/100)*player.duration()); 163 } 164 }); 165 container.find('.big-video-control-bar').click(function(e) { 166 player.currentTime((e.offsetX/$(this).width())*player.duration()); 167 }); 168 container.find('.big-video-control-play').click(function(e) { 169 e.preventDefault(); 170 playControl('toggle'); 171 }); 172 player.on('timeupdate', function() { 173 if (!isSeeking && (player.currentTime()/player.duration())) { 174 var currTime = player.currentTime(); 175 var minutes = Math.floor(currTime/60); 176 var seconds = Math.floor(currTime) - (60*minutes); 177 if (seconds < 10) seconds='0'+seconds; 178 var progress = player.currentTime()/player.duration()*100; 179 container.find('.big-video-control-track').slider('value',progress); 180 container.find('.big-video-control-progress').css('width',(progress-0.16)+'%'); 181 container.find('.big-video-control-timer').text(minutes+':'+seconds+'/'+vidDur); 182 } 183 }); 184 } 185 186 function playControl(a) { 187 var action = a || 'toggle'; 188 if (action === 'toggle') action = isPlaying ? 'pause' : 'play'; 189 if (action === 'pause') { 190 player.pause(); 191 container.find('.big-video-control-play').css('background-position','-16px'); 192 isPlaying = false; 193 } else if (action === 'play') { 194 player.play(); 195 container.find('.big-video-control-play').css('background-position','0'); 196 isPlaying = true; 197 } else if (action === 'skip') { 198 nextMedia(); 199 } 200 } 201 202 function setUpAutoPlay() { 203 player.play(); 204 settings.container.off('click',setUpAutoPlay); 205 } 206 207 function nextMedia() { 208 currMediaIndex++; 209 if (currMediaIndex === playlist.length) currMediaIndex=0; 210 playVideo(playlist[currMediaIndex]); 211 } 212 213 function playVideo(source) { 214 // clear image 215 vid.css('display','block'); 216 currMediaType = 'video'; 217 player.src(source); 218 isPlaying = true; 219 if (isAmbient) { 220 container.find('.big-video-control-container').css('display','none'); 221 player.ready(function(){ 222 player.volume(0); 223 }); 224 doLoop = true; 225 } else { 226 container.find('.big-video-control-container').css('display','block'); 227 player.ready(function(){ 228 player.volume(defaultVolume); 229 }); 230 doLoop = false; 231 } 232 container.find('.big-video-image').css('display','none'); 233 vid.css('display','block'); 234 } 235 236 function showPoster(source) { 237 // remove old image 238 container.find('.big-video-image').remove(); 239 240 // hide video 241 player.pause(); 242 vid.css('display','none'); 243 container.find('.big-video-control-container').css('display','none'); 244 245 // show image 246 currMediaType = 'image'; 247 var bgImage = $('<img class="big-video-image" src='+source+' />'); 248 wrap.append(bgImage); 249 250 container.find('.big-video-image').imagesLoaded(function() { 251 mediaAspect = container.find('.big-video-image').width() / container.find('.big-video-image').height(); 252 updateSize(); 253 }); 254 } 255 256 BigVideo.init = function() { 257 if (!isInitialized) { 258 259 // create player 260 settings.container.prepend(wrap); 261 var autoPlayString = settings.forceAutoplay ? 'autoplay' : ''; 262 player = $('<video class="'+vidEl.substr(1)+'" class="video-js vjs-default-skin" preload="auto" data-setup="{}" '+autoPlayString+' webkit-playsinline></video>'); 263 player.css('position','absolute'); 264 wrap.append(player); 265 266 vid = container.find(vidEl); 267 268 var videoTechOrder = ['html5','flash']; 269 // If only using mp4s and on firefox, use flash fallback 270 var ua = navigator.userAgent.toLowerCase(); 271 var isFirefox = ua.indexOf('firefox') != -1; 272 if (settings.useFlashForFirefox && (isFirefox)) { 273 videoTechOrder = ['flash', 'html5']; 274 } 275 276 player = videojs(vid[0], { 277 controls:false, 278 autoplay:true, 279 preload:'auto', 280 techOrder:videoTechOrder 281 }); 282 283 // add controls 284 if (settings.controls) initPlayControl(); 285 286 // set initial state 287 updateSize(); 288 isInitialized = true; 289 isPlaying = false; 290 291 if (settings.forceAutoplay) { 292 $('body').on('click', setUpAutoPlay); 293 } 294 295 container.find('object[id*=_flash_api]') 296 .attr('scale','noborder') 297 .attr('width','100%') 298 .attr('height','100%'); 299 300 // set events 301 $(window).on('resize.bigvideo', function() { 302 updateSize(); 303 }); 304 305 player.on('loadedmetadata', function(data) { 306 if (container.find('object[id*=_flash_api]').length) { 307 // use flash callback to get mediaAspect ratio 308 mediaAspect = 309 container.find('object[id*=_flash_api]')[0].vjs_getProperty('videoWidth') / 310 container.find('object[id*=_flash_api]')[0].vjs_getProperty('videoHeight'); 311 } else { 312 // use html5 player to get mediaAspect 313 mediaAspect = 314 container.find('video').prop('videoWidth') / 315 container.find('video').prop('videoHeight'); 316 } 317 updateSize(); 318 var dur = Math.round(player.duration()); 319 var durMinutes = Math.floor(dur/60); 320 var durSeconds = dur - durMinutes*60; 321 if (durSeconds < 10) durSeconds='0'+durSeconds; 322 vidDur = durMinutes+':'+durSeconds; 323 }); 324 325 player.on('ended', function() { 326 if (settings.doLoop) { 327 player.currentTime(0); 328 player.play(); 329 } 330 if (isQueued) { 331 nextMedia(); 332 } 333 }); 334 } 335 }; 336 337 BigVideo.show = function(source,options) { 338 if (options === undefined) options = {}; 339 if (!source && container.data('video') !== '') { 340 source = container.data('video'); 341 } 342 isAmbient = options.ambient === true; 343 if (isAmbient || options.doLoop) settings.doLoop = true; 344 if (typeof(source) === 'string') {
345 var ext = source.substring(source.lastIndexOf('.')+1); 346 if (ext === 'jpg' || ext === 'gif' || ext === 'png') { 347 showPoster(source); 348 } else { 349 if (options.altSource && navigator.userAgent.toLowerCase().indexOf('firefox') > -1) { 350 source = options.altSource; 351 } 352 playVideo(source); 353 if (options.onShown) options.onShown(); 354 isQueued = false; 355 } 356 } else { 357 playlist = source; 358 currMediaIndex = 0; 359 playVideo(playlist[currMediaIndex]); 360 if (options.onShown) options.onShown(); 361 isQueued = true; 362 } 363 }; 364 365 // Expose Video.js player 366 BigVideo.getPlayer = function() { 367 return player; 368 }; 369 370 // Remove/dispose the player 371 BigVideo.remove = BigVideo.dispose = function() { 372 isInitialized = false; 373 374 wrap.remove(); 375 $(window).off('resize.bigvideo'); 376 377 if(player) { 378 player.off('loadedmetadata'); 379 player.off('ended'); 380 player.dispose(); 381 } 382 }; 383 384 // Expose BigVideoJS player actions play, pause, skip (if a playlist is available) 385 // Example: BigVideo.triggerPlayer('skip') 386 BigVideo.triggerPlayer = function(action){ 387 playControl(action); 388 }; 389 390 }; 391 392 //jquery shim 393 $.fn.bigvideo = function (options) { 394 if (typeof options === 'string') { 395 var args = Array.prototype.slice.call(arguments, 1); 396 this.each(function () { 397 var instance = $.data(this, 'bigvideo'); 398 if (!instance) { 399 $.error('Cannot call methods on bigvideo prior to initialization; Attempted to call method "' + options + '"'); 400 return; 401 } 402 if (!$.isFunction(instance[options]) || options.charAt(0) === '_') { 403 $.error('No such method "' + options + '" for bigvideo instance'); 404 return; 405 } 406 instance[options].apply(instance, args); 407 }); 408 } else { 409 this.each(function () { 410 $.data(this, 'bigvideo', new $.BigVideo(options, this)); 411 }); 412 } 413 return this; 414 }; 415 416});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.