328 lines
8.2 KiB
JavaScript
328 lines
8.2 KiB
JavaScript
|
dojo.provide("dojox.av._Media");
|
||
|
|
||
|
dojo.declare("dojox.av._Media", null, {
|
||
|
// summary:
|
||
|
// Used as a mixin for dojox and AIR media
|
||
|
// description:
|
||
|
// Calculates the current status of the playing media and fires
|
||
|
// the appropriate events.
|
||
|
//
|
||
|
mediaUrl:"",
|
||
|
//
|
||
|
// initialVolume: Float?
|
||
|
// The initial volume setting of the player. Acccepts between 0 and 1.
|
||
|
initialVolume:1,
|
||
|
//
|
||
|
// autoPlay:Boolean?
|
||
|
// Whether the video automatically plays on load or not.
|
||
|
autoPlay: false,
|
||
|
//
|
||
|
// bufferTime: Number?
|
||
|
// Time in milliseconds that the video should be loaded before it will
|
||
|
// play. May pause and resume to build up buffer. Prevents stuttering.
|
||
|
// Note:
|
||
|
// Older FLVs, without a duration, cannot be buffered.
|
||
|
bufferTime: 2000,
|
||
|
//
|
||
|
// minBufferTime: Number
|
||
|
// Time in milliseconds bwteen the playhead time and loaded time that
|
||
|
// will trigger the buffer. When buffer is triggered, video will pause
|
||
|
// until the bufferTime amount is buffered.
|
||
|
// Note: Should be a small number, greater than zero.
|
||
|
minBufferTime:300,
|
||
|
//
|
||
|
// updateTime: Number
|
||
|
// How often, in milliseconds to get an update of the video position.
|
||
|
updateTime: 100,
|
||
|
//
|
||
|
// id: String?
|
||
|
// The id of this widget and the id of the SWF movie.
|
||
|
id:"",
|
||
|
//
|
||
|
// isDebug: Boolean?
|
||
|
// Setting to true tells the SWF to output log messages to Firebug.
|
||
|
isDebug: false,
|
||
|
//
|
||
|
// percentDownloaded: read-only-Number
|
||
|
// The percentage the media has downloaded; from 0-100
|
||
|
percentDownloaded:0,
|
||
|
//
|
||
|
// _flashObject: read-only-Object
|
||
|
// The dojox.embed object
|
||
|
_flashObject:null,
|
||
|
//
|
||
|
// flashMedia: read-only-SWF
|
||
|
// The SWF object. Methods are passed to this.
|
||
|
flashMedia:null,
|
||
|
//
|
||
|
_initStatus: function(){
|
||
|
// summary:
|
||
|
// Connect mediaStatus to the media.
|
||
|
//
|
||
|
this.status = "ready";
|
||
|
dojo.connect(this, "onPosition", this, "_figureStatus");
|
||
|
|
||
|
},
|
||
|
|
||
|
// ============== //
|
||
|
// Player Getters //
|
||
|
// ============== //
|
||
|
|
||
|
getTime: function(){
|
||
|
// summary:
|
||
|
// Returns the current time of the video
|
||
|
// Note:
|
||
|
// Consider the onPosition event, which returns
|
||
|
// the time at a set interval. Too many trips to
|
||
|
// the SWF could impact performance.
|
||
|
return this.flashMedia.getTime(); // Float
|
||
|
},
|
||
|
|
||
|
// ============= //
|
||
|
// Player Events //
|
||
|
// ============= //
|
||
|
|
||
|
onLoad: function(/* SWF */ mov){
|
||
|
// summary:
|
||
|
// Fired when the SWF player has loaded
|
||
|
// NOT when the video has loaded
|
||
|
//
|
||
|
},
|
||
|
|
||
|
onDownloaded: function(/* Number */percent){
|
||
|
// summary:
|
||
|
// Fires the amount of that the media has been
|
||
|
// downloaded. Number, 0-100
|
||
|
},
|
||
|
|
||
|
onClick: function(/* Object */ evt){
|
||
|
// summary:
|
||
|
// TODO: Return x/y of click
|
||
|
// Fires when the player is clicked
|
||
|
// Could be used to toggle play/pause, or
|
||
|
// do an external activity, like opening a new
|
||
|
// window.
|
||
|
},
|
||
|
|
||
|
onSwfSized: function(/* Object */ data){
|
||
|
// summary:
|
||
|
// Fired on SWF resize, or when its
|
||
|
// toggled between fullscreen.
|
||
|
},
|
||
|
|
||
|
onMetaData: function(/* Object */ data, /* Object */ evt){
|
||
|
// summary:
|
||
|
// The video properties. Width, height, duration, etc.
|
||
|
// NOTE: if data is empty, this is an older FLV with no meta data.
|
||
|
// Duration cannot be determined. In original FLVs, duration
|
||
|
// could only be obtained with Flash Media Server.
|
||
|
// NOTE: Older FLVs can still return width and height
|
||
|
// and will do so on a second event call
|
||
|
this.duration = data.duration;
|
||
|
},
|
||
|
|
||
|
onPosition: function(/* Float */ time){
|
||
|
// summary:
|
||
|
// The position of the playhead in seconds
|
||
|
},
|
||
|
|
||
|
onStart: function(/* Object */ data){
|
||
|
// summary:
|
||
|
// Fires when video starts
|
||
|
// Good for setting the play button to pause
|
||
|
// during an autoPlay for example
|
||
|
},
|
||
|
|
||
|
onPlay: function(/* Object */ data){
|
||
|
// summary:
|
||
|
// Fires when video starts and resumes
|
||
|
},
|
||
|
|
||
|
onPause: function(/* Object */ data){
|
||
|
// summary:
|
||
|
// Fires when the pause button is clicked
|
||
|
},
|
||
|
|
||
|
onEnd: function(/* Object */ data){
|
||
|
// summary:
|
||
|
// Fires when video ends
|
||
|
// Could be used to change pause button to play
|
||
|
// or show a post video graphic, like YouTube
|
||
|
},
|
||
|
|
||
|
onStop: function(){
|
||
|
// summary:
|
||
|
// Fire when the Stop button is clicked
|
||
|
// TODO: This is not hooked up yet and shouldn't
|
||
|
// fire.
|
||
|
},
|
||
|
|
||
|
onBuffer: function(/* Boolean */ isBuffering){
|
||
|
// summary:
|
||
|
// Fires a boolean to tell if media
|
||
|
// is paused for buffering or if buffering
|
||
|
// has finished
|
||
|
this.isBuffering = isBuffering;
|
||
|
},
|
||
|
|
||
|
onError: function(/* Object */ data, /* String */ url){
|
||
|
// summary:
|
||
|
// Fired when the player encounters an error
|
||
|
// example:
|
||
|
// | console.warn("ERROR-"+data.type.toUpperCase()+":",
|
||
|
// | data.info.code, " - URL:", url);
|
||
|
console.warn("ERROR-"+data.type.toUpperCase()+":", data.info.code, " - URL:", url);
|
||
|
},
|
||
|
|
||
|
onStatus: function(/* Object */data){
|
||
|
// summary:
|
||
|
// Simple status
|
||
|
},
|
||
|
|
||
|
onPlayerStatus: function(/* Object */data){
|
||
|
// summary:
|
||
|
// The status of the video from the SWF
|
||
|
// playing, stopped, bufering, etc.
|
||
|
},
|
||
|
|
||
|
onResize: function(){
|
||
|
|
||
|
},
|
||
|
|
||
|
_figureStatus: function(){
|
||
|
// summary:
|
||
|
// Calculate media status, based on playhead movement, and
|
||
|
// onStop and onStart events
|
||
|
// TODO:
|
||
|
// Figure in real status from the media for more accurate results.
|
||
|
//
|
||
|
var pos = this.getTime();
|
||
|
//console.log(pos, this.duration, (pos>this.duration-.5), (this.duration && pos>this.duration-.5))
|
||
|
|
||
|
if(this.status=="stopping"){
|
||
|
// stop was fired, need to fake pos==0
|
||
|
this.status = "stopped";
|
||
|
this.onStop(this._eventFactory());
|
||
|
|
||
|
}else if(this.status=="ending" && pos==this._prevPos){
|
||
|
this.status = "ended";
|
||
|
this.onEnd(this._eventFactory());
|
||
|
|
||
|
}else if(this.duration && pos>this.duration-.5){
|
||
|
this.status="ending"
|
||
|
|
||
|
}else if(pos===0 ){//|| this.status == "stopped"
|
||
|
if(this.status == "ready"){
|
||
|
//never played
|
||
|
}else{
|
||
|
//stopped
|
||
|
this.status = "stopped";
|
||
|
if(this._prevStatus != "stopped"){
|
||
|
this.onStop(this._eventFactory());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}else{
|
||
|
// pos > 0
|
||
|
if(this.status == "ready"){
|
||
|
//started
|
||
|
this.status = "started";
|
||
|
this.onStart(this._eventFactory());
|
||
|
this.onPlay(this._eventFactory());
|
||
|
|
||
|
}else if(this.isBuffering){
|
||
|
this.status = "buffering";
|
||
|
|
||
|
}else if(this.status == "started" || (this.status == "playing" && pos != this._prevPos)){
|
||
|
this.status = "playing";
|
||
|
//this.onPosition(this._eventFactory());
|
||
|
|
||
|
}else if(!this.isStopped && this.status == "playing" && pos == this._prevPos){
|
||
|
this.status = "paused";
|
||
|
console.warn("pause", pos, this._prevPos)
|
||
|
if(this.status != this._prevStatus){
|
||
|
this.onPause(this._eventFactory());
|
||
|
}
|
||
|
|
||
|
}else if((this.status == "paused" ||this.status == "stopped") && pos != this._prevPos){
|
||
|
this.status = "started";
|
||
|
this.onPlay(this._eventFactory());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this._prevPos = pos;
|
||
|
this._prevStatus = this.status;
|
||
|
this.onStatus(this.status);
|
||
|
|
||
|
|
||
|
},
|
||
|
|
||
|
_eventFactory: function(){
|
||
|
// summary:
|
||
|
// Creates a generic event object.
|
||
|
//
|
||
|
var evt = {
|
||
|
//position:this._channel.position,
|
||
|
//seconds:this.toSeconds(this._channel.position*.001),
|
||
|
//percentPlayed:this._getPercent(),
|
||
|
status:this.status
|
||
|
}
|
||
|
return evt; // Object
|
||
|
},
|
||
|
|
||
|
|
||
|
|
||
|
_sub: function(topic, method){
|
||
|
// summary:
|
||
|
// helper for subscribing to topics
|
||
|
dojo.subscribe(this.id+"/"+topic, this, method);
|
||
|
},
|
||
|
|
||
|
_normalizeVolume: function(vol){
|
||
|
// summary:
|
||
|
// Ensures volume is less than one
|
||
|
//
|
||
|
if(vol>1){
|
||
|
while(vol>1){
|
||
|
vol*=.1
|
||
|
}
|
||
|
}
|
||
|
return vol;
|
||
|
},
|
||
|
|
||
|
_normalizeUrl: function(_url){
|
||
|
// summary:
|
||
|
// Checks that path is relative to HTML file or
|
||
|
// convertes it to an absolute path.
|
||
|
//
|
||
|
if(_url && _url.toLowerCase().indexOf("http")<0){
|
||
|
//
|
||
|
// Appears to be a relative path. Attempt to convert it to absolute,
|
||
|
// so it will better target the SWF.
|
||
|
var loc = window.location.href.split("/");
|
||
|
loc.pop();
|
||
|
loc = loc.join("/")+"/";
|
||
|
|
||
|
_url = loc+_url;
|
||
|
}
|
||
|
return _url;
|
||
|
},
|
||
|
|
||
|
destroy: function(){
|
||
|
// summary:
|
||
|
// destroys flash
|
||
|
if(!this.flashMedia){
|
||
|
this._cons.push(dojo.connect(this, "onLoad", this, "destroy"));
|
||
|
return;
|
||
|
}
|
||
|
dojo.forEach(this._subs, function(s){
|
||
|
dojo.unsubscribe(s);
|
||
|
});
|
||
|
dojo.forEach(this._cons, function(c){
|
||
|
dojo.disconnect(c);
|
||
|
});
|
||
|
this._flashObject.destroy();
|
||
|
//dojo._destroyElement(this.flashDiv);
|
||
|
|
||
|
}
|
||
|
});
|