You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
356 lines
8.9 KiB
356 lines
8.9 KiB
define(['dojo'],function(dojo){ |
|
|
|
dojo.experimental("dojox.av.FLVideo"); |
|
|
|
return 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 between 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, |
|
|
|
// allowScriptAccess: String |
|
// Whether the SWF can access the container JS |
|
allowScriptAccess:"always", |
|
|
|
// allowNetworking: String |
|
// Whether SWF is restricted to a domain |
|
allowNetworking: "all", |
|
|
|
// wmode: String |
|
// The render type of the SWF |
|
wmode: "transparent", |
|
|
|
// allowFullScreen: Boolean |
|
// Whether to allow the SWF to go to fullscreen |
|
allowFullScreen:true, |
|
|
|
_initStatus: function(){ |
|
// summary: |
|
// Connect mediaStatus to the media. |
|
// |
|
this.status = "ready"; |
|
this._positionHandle = 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: |
|
// Fires when the player is clicked |
|
// Could be used to toggle play/pause, or |
|
// do an external activity, like opening a new |
|
// window. |
|
|
|
// TODO: Return x/y of click |
|
}, |
|
|
|
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 |
|
|
|
console.warn("onMeta", data) |
|
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 |
|
// converts it to an absolute path. |
|
|
|
console.log(" url:", _url); |
|
|
|
if(_url && (_url.toLowerCase().indexOf("http")<0 || _url.indexOf("/") == 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("/")+"/"; |
|
console.log(" loc:", loc); |
|
_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); |
|
|
|
} |
|
}); |
|
});
|
|
|