/*****************************************************
|
*
|
* Copyright 2010 Adobe Systems Incorporated. All Rights Reserved.
|
*
|
*****************************************************
|
* The contents of this file are subject to the Berkeley Software Distribution (BSD) Licence
|
* (the "License"); you may not use this file except in
|
* compliance with the License.
|
*
|
* Software distributed under the License is distributed on an "AS IS"
|
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
* License for the specific language governing rights and limitations
|
* under the License.
|
*
|
*
|
* The Initial Developer of the Original Code is Adobe Systems Incorporated.
|
* Portions created by Adobe Systems Incorporated are Copyright (C) 2010 Adobe Systems
|
* Incorporated. All Rights Reserved.
|
*
|
*****************************************************/
|
|
/**
|
*
|
*/
|
(function($, undefined){
|
/**
|
*
|
*/
|
var StrobeMediaPlaybackHtml5 = function(element, options, javascriptCallbackFunctions){
|
this.$window = $(window);
|
this.$document = $(document);
|
this.element = element;
|
this.$element = $(element);
|
this.options = $.extend({}, $.fn.strobemediaplaybackhtml5.defaults, options);
|
this.jsCallbackFunctions = javascriptCallbackFunctions;
|
};
|
|
var strobeMediaPlaybackHtml5Methods = {
|
initialize: function(){
|
$(document).bind('webkitfullscreenchange', this, this.onFullscreenChange);
|
|
this.$element.bind("mousemove", this, this.onMouseMove);
|
|
this.$player = this.$element.find("video"); //$("#" + this.options.id)
|
this.player = this.$player.get(0);
|
if(this.player == null)
|
{
|
this.$player = $("#" + this.options.id);
|
this.player = this.$player.get(0);
|
}
|
|
this.$player.bind("timeupdate", this, this.onTimeUpdate);
|
this.$player.bind('play', this, this.onPlay);
|
this.$player.bind("playing", this, this.onPlaying);
|
this.$player.bind('pause', this, this.onPause);
|
this.$player.bind('ended', this, this.onEnded);
|
this.$player.bind("loadeddata", this, this.onLoadedData);
|
this.$player.bind("loadedmetadata", this, this.onMetaDataLoaded);
|
this.$player.bind("progress", this, this.onProgress);
|
this.$player.bind("click", this, this.onClick);
|
this.$player.bind("dblclick", this, this.onDoubleClick);
|
//this.$player.bind("contextmenu", this, function(event){ event.preventDefault(); }); //disable context menu
|
this.$player.bind("error", this, onError);
|
|
this.hidedelaytimeout, this.isdragging, this.trackswidth;
|
|
this.controlbar = this.$element.find(this.options.controlbarselector);
|
|
this.progressbar = this.controlbar.find(this.options.progressbarselector);
|
this.progressbar.bind('click', this, this.onSeekClick);
|
this.tracks = this.progressbar.find(this.options.tracksselector);
|
this.seekbar = this.progressbar.find(this.options.seekbarselector);
|
this.playedbar = this.progressbar.find(this.options.playedbarselector);
|
this.bufferbar = this.progressbar.find(this.options.bufferedbarselector);
|
|
this.playtoggle = this.controlbar.find(this.options.playtoggleselector);
|
this.playtoggle.bind('click', this, this.onPlayToggleClick);
|
this.playtoggle.bind("mousedown mouseup touchstart touchend", this, this.onButtonHover);
|
|
this.slider = this.controlbar.find(this.options.sliderselector);
|
this.slider.draggable({disabled: false, containment: "parent", axis: "x"});
|
this.slider.bind("dragstart", this, this.onSliderDragStart);
|
this.slider.bind("drag", this, this.onSliderDragging);
|
this.slider.bind("dragstop", this, this.onSliderDragStop);
|
this.slider.bind("mousedown mouseup touchstart touchend", this, this.onButtonHover);
|
|
this.volumeHigh = this.controlbar.find(this.options.volumeHigh);
|
this.volumeSlider = this.controlbar.find(this.options.volumeSlider);
|
this.volumeContainer = this.controlbar.find(this.options.volumeContainer);
|
this.fullview = this.controlbar.find(this.options.fullviewselector);
|
this.fullview.bind("click", this, this.onFullViewClick);
|
this.fullview.bind("mousedown mouseup touchstart touchend", this, this.onButtonHover);
|
|
//disable the fullview button until metadata is loaded; necessary for iPad native fullscreen to work
|
this.fullview.addClass("disabled");
|
|
this.$player.attr("preload", "true"); //start loading the video, if not already started
|
|
this.currenttime = this.controlbar.find(this.options.currenttimeselector);
|
this.duration = this.controlbar.find(this.options.durationtimeselector);
|
|
this.errorwindow = this.$element.find(this.options.errorwindowselector);
|
this.playOverlay = this.$element.find(this.options.playoverlay);
|
this.playOverlay.bind("click",this,this.onPlayToggleClick);
|
this.monitor = new VideoElementMonitor(null);
|
|
this.options.originalWidth = this.player.clientWidth;
|
if(isDesktop)
|
{
|
this.controlbar.css("width", this.options.originalWidth - 1.5);
|
if(this.options.originalWidth > 180)
|
this.progressbar.css("width", this.options.originalWidth - 180);
|
else
|
this.progressbar.css("width", "50%");
|
}
|
},
|
|
onSliderDragStart: function(event){
|
event.data.isdragging = true;
|
event.data.seekbar.css("width", event.data.playedbar.width()+"px").show();
|
},
|
|
onSliderDragging: function(event, ui){
|
event.data.seekbar.css("width", ui.position.left+"px");
|
},
|
|
onSliderDragStop: function(event, ui){
|
event.data.isdragging = false;
|
event.data.seekbar.hide();
|
event.data.player.currentTime = event.data.player.duration*((ui.position.left+event.data.slider.width()/2)/$(this).parent().width());
|
event.data.onTimeUpdate(event);
|
},
|
|
onProgress: function(event){
|
try{
|
var start = event.target.buffered.start();
|
var end = event.target.buffered.end()
|
var duration = event.target.duration;
|
event.data.bufferbar.css("width", ((end/duration)*100)+"%");
|
}catch(exception){}
|
},
|
|
onPlay: function(event){
|
event.data.playtoggle.addClass('paused');
|
playbackStart(event.data.options.id);
|
},
|
|
onPlaying: function(event){
|
event.data.slider.draggable("option", "disabled", false);
|
},
|
|
onPause: function(event){
|
event.data.playtoggle.removeClass('paused');
|
playbackPause(event.data.options.id);
|
},
|
|
onEnded: function(event){
|
event.data.showControls();
|
event.data.playtoggle.removeClass('paused');
|
playbackComplete(event.data.options.id);
|
},
|
|
onLoadedData: function(event){
|
event.data.bufferbar.css("width", "100%");
|
event.data.showControls();
|
event.data.duration.html(formatTimeStatus(0, event.target.duration)[1]);
|
event.data.trackswidth = event.data.tracks.width();
|
},
|
|
onMetaDataLoaded: function(event){
|
if(event.data.jsCallbackFunctions.onLoad != null)
|
event.data.jsCallbackFunctions.onLoad();
|
event.data.fullview.removeClass("disabled");
|
},
|
|
onMouseMove: function(event){
|
event.data.showControls();
|
if(!event.data.player.paused && !event.data.player.ended){
|
clearTimeout(event.data.hidedelaytimeout);
|
event.data.hidedelaytimeout = setTimeout(function(){event.data.hideControls(event);}, event.data.options.hidedelay);
|
}
|
},
|
|
onButtonHover: function(event){
|
$(this).toggleClass("hover");
|
},
|
|
onPlayToggleClick: function(event){
|
if(event.data.player.paused) event.data.player.play();
|
else if(event.data.player.ended)
|
{
|
//event.data.player.ended = false;
|
event.data.player.play();
|
event.data.onPlay(event);
|
}
|
else event.data.player.pause();
|
},
|
|
onSeekClick: function(event){
|
var time = event.data.player.duration * ((event.clientX - event.data.progressbar.offset().left) / event.data.progressbar.outerWidth());
|
if(time > 0) event.data.player.currentTime = time;
|
if(event.data.player.paused) event.data.onPause(event);
|
else event.data.onPlay(event);
|
},
|
|
onClick: function(event){
|
if(event.data.player.ended) event.data.hideControls(event);
|
else event.data.onMouseMove(event);
|
},
|
|
onDoubleClick: function(event){
|
event.data.onFullViewClick(event);
|
},
|
|
onFullViewClick: function(event){
|
try{
|
if(event.data.fullview.hasClass("disabled")) return; //do not do anything if the button is disabled
|
if(navigator.userAgent.match(/(Macintosh|Windows|Safari|Version\/5\.[1-9])/gi).length >= 3){ //at a minimum match one of the OSes, Safari, and the version
|
if($(document).context.webkitIsFullScreen) $(document).context.webkitCancelFullScreen();
|
else event.data.$element.context.webkitRequestFullScreen();
|
}else event.data.player.webkitEnterFullScreen();
|
}catch(error){
|
event.data.onFullscreenChange(event);
|
}
|
},
|
|
onFullscreenChange: function(event){
|
event.data.$element.toggleClass(event.data.options.fullscreenclass);
|
|
event.data.fullview.toggleClass(event.data.options.fullviewactiveclass);
|
|
/*event.data.progressbar.toggleClass("progressFullscreen");*/
|
var width = event.data.$element.css("width");
|
var height = event.data.$element.css("height");
|
width = width.substring(0, width.indexOf("px"));
|
height = height.substring(0, height.indexOf("px"));
|
if(isDesktop)
|
{
|
event.data.controlbar.css("width", width - 1.5);
|
if(this.options.originalWidth > 180)
|
this.progressbar.css("width", width - 180);
|
else
|
this.progressbar.css("width", "50%");
|
}
|
event.data.trackswidth = event.data.tracks.width();
|
if(event.data.player.ended) event.data.onTimeUpdate(event);
|
handlePlayoverlay(event.data.player.id, width, height);
|
document.getElementById(event.data.player.id).scrollIntoView();
|
},
|
|
onTimeUpdate: function(event){
|
var percent = event.data.player.currentTime/event.data.player.duration;
|
var px = percent*event.data.trackswidth;
|
event.data.playedbar.css("width", px+"px");
|
if(!event.data.isdragging) event.data.slider.css("left", px+"px");
|
var times = formatTimeStatus(event.data.player.currentTime, event.data.player.duration);
|
event.data.currenttime.html(times[0]);
|
event.data.duration.html(times[1]);
|
},
|
|
showControls: function(){
|
if(this.controlbar.is(":visible")) return;
|
this.controlbar.fadeIn(this.options.fadeinspeed);
|
},
|
|
hideControls: function(event){
|
if(event.data.player.paused && !event.data.player.ended) return;
|
event.data.controlbar.fadeOut(event.data.options.fadeoutspeed);
|
}
|
};
|
|
StrobeMediaPlaybackHtml5.prototype = strobeMediaPlaybackHtml5Methods;
|
|
/**
|
* jQuery plugin hook
|
*/
|
$.fn.strobemediaplaybackhtml5 = function(options, javascriptCallbackFunctions){
|
var instances = [], i;
|
var instance;
|
var result = this.each(function(){
|
instance = new StrobeMediaPlaybackHtml5(this, options, javascriptCallbackFunctions);
|
instances.push(instance);
|
});
|
|
for (i = 0; i < instances.length; i++) {
|
instances[i].initialize();
|
}
|
return instance;
|
};
|
|
/**
|
* jQuery plugin defaults
|
*/
|
$.fn.strobemediaplaybackhtml5.defaults = {
|
autoplay: false,
|
hidedelay: 6000,
|
fadeinspeed: "fast",
|
fadeoutspeed: 500,
|
controlbarselector: ".controls",
|
progressbarselector: ".progress",
|
tracksselector: ".tracks",
|
sliderselector: ".slider",
|
seekbarselector: ".seeking",
|
playedbarselector: ".played",
|
bufferedbarselector: ".buffered",
|
playtoggleselector: ".icon.playtoggle",
|
currenttimeselector: ".timestamp.current",
|
durationtimeselector: ".timestamp.duration",
|
errorwindowselector: ".errorwindow",
|
fullviewselector: ".icon.fullview",
|
fullscreenclass: "fullscreen",
|
fullviewactiveclass: "fullscreen",
|
playoverlay: ".playoverlay",
|
volumeHigh: ".icon.volume.high",
|
volumeSlider: ".volume-slider",
|
volumeContainer: ".volume-container"
|
};
|
|
function formatTimeStatus(currentPosition, totalDuration){
|
var h;
|
var m;
|
var s;
|
function prettyPrintSeconds(seconds, leadingMinutes, leadingHours){
|
seconds = Math.floor(isNaN(seconds) ? 0 : Math.max(0, seconds));
|
h = Math.floor(seconds / 3600);
|
m = Math.floor(seconds % 3600 / 60);
|
s = seconds % 60;
|
return ((h > 0 || leadingHours) ? (h + ":") : "") +
|
(((h > 0 || leadingMinutes) && m < 10) ? "0" : "") +
|
m +
|
":" +
|
(s < 10 ? "0" : "") +
|
s;
|
}
|
|
var totalDurationString = prettyPrintSeconds(totalDuration);
|
var currentPositionString = prettyPrintSeconds(currentPosition, h > 0 || m > 9, h > 0);
|
return [currentPositionString, totalDurationString];
|
}
|
|
var VideoElementMonitor = function($strobeMediaPlayback) {
|
this.videoElement = {
|
duration: 0,
|
currentTime: 0,
|
paused: true,
|
muted: false
|
};
|
this.$videoElement = $(this.videoElement);
|
}
|
|
StrobeMediaPlaybackHtml5.prototype = strobeMediaPlaybackHtml5Methods;
|
})(jQuery);
|