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