307 lines
7.6 KiB
JavaScript
307 lines
7.6 KiB
JavaScript
|
dojo.provide("dojox.av.FLVideo");
|
||
|
dojo.experimental("dojox.av.FLVideo");
|
||
|
dojo.require("dijit._Widget");
|
||
|
dojo.require("dojox.embed.Flash");
|
||
|
dojo.require("dojox.av._Media");
|
||
|
|
||
|
dojo.declare("dojox.av.FLVideo", [dijit._Widget, dojox.av._Media], {
|
||
|
|
||
|
// summary:
|
||
|
// Inserts a Flash FLV video into the HTML page and provides methods
|
||
|
// and events for controlling the video. Also plays the H264/M4V codec
|
||
|
// with a little trickery: change the '.M4V' extension to '.flv'.
|
||
|
//
|
||
|
// example:
|
||
|
//
|
||
|
// markup:
|
||
|
// | <div id="vid" initialVolume=".7",
|
||
|
// | mediaUrl="../resources/Grog.flv"
|
||
|
// | dojoType="dojox.av.FLVideo"></div>
|
||
|
// programmatic:
|
||
|
// | new dojox.av.FLVideo({
|
||
|
// | initialVolume:.7,
|
||
|
// | mediaUrl:"../resources/Grog.flv"
|
||
|
// | }, "vid");
|
||
|
//
|
||
|
// mediaUrl: String
|
||
|
// REQUIRED: The Url of the video file that will be played.
|
||
|
// NOTE: Must be either an absolute URL or relative to the HTML file.
|
||
|
// Relative paths will be converted to abslute paths
|
||
|
//
|
||
|
// _swfPath: Uri
|
||
|
// The path to the video player SWF resource
|
||
|
_swfPath: dojo.moduleUrl("dojox.av", "resources/video.swf"),
|
||
|
//
|
||
|
//
|
||
|
postCreate: function(){
|
||
|
// summary:
|
||
|
// Initialize the media.
|
||
|
//
|
||
|
//
|
||
|
this._subs = [];
|
||
|
this._cons = [];
|
||
|
this.mediaUrl = this._normalizeUrl(this.mediaUrl);
|
||
|
this.initialVolume = this._normalizeVolume(this.initialVolume);
|
||
|
|
||
|
var args = {
|
||
|
path:this._swfPath.uri,
|
||
|
width:"100%",
|
||
|
height:"100%",
|
||
|
minimumVersion:9,
|
||
|
expressInstall:true,
|
||
|
params:{
|
||
|
allowFullScreen:true,
|
||
|
wmode:"transparent"
|
||
|
},
|
||
|
// only pass in simple variables - no deep objects
|
||
|
vars:{
|
||
|
videoUrl:this.mediaUrl,
|
||
|
id:this.id,
|
||
|
autoPlay:this.autoPlay,
|
||
|
volume:this.initialVolume,
|
||
|
isDebug:this.isDebug
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Setting up dojo.subscribes that listens to events
|
||
|
// from the player
|
||
|
this._sub("stageClick", "onClick");
|
||
|
this._sub("stageSized", "onSwfSized");
|
||
|
this._sub("mediaStatus", "onPlayerStatus");
|
||
|
this._sub("mediaMeta", "onMetaData");
|
||
|
this._sub("mediaError", "onError");
|
||
|
this._sub("mediaStart", "onStart");
|
||
|
this._sub("mediaEnd", "onEnd");
|
||
|
|
||
|
this._flashObject = new dojox.embed.Flash(args, this.domNode);
|
||
|
this._flashObject.onError = function(err){
|
||
|
console.warn("Flash Error:", err);
|
||
|
alert(err);
|
||
|
};
|
||
|
this._flashObject.onLoad = dojo.hitch(this, function(mov){
|
||
|
this.flashMedia = mov;
|
||
|
this.isPlaying = this.autoPlay;
|
||
|
this.isStopped = !this.autoPlay;
|
||
|
this.onLoad(this.flashMedia);
|
||
|
this._initStatus();
|
||
|
this._update();
|
||
|
});
|
||
|
|
||
|
},
|
||
|
|
||
|
// ============================= //
|
||
|
// Methods to control the player //
|
||
|
// ============================= //
|
||
|
|
||
|
play: function(/* String? */newUrl){
|
||
|
// summary:
|
||
|
// Plays the video. If an url is passed in, plays the new link.
|
||
|
this.isPlaying = true;
|
||
|
this.isStopped = false;
|
||
|
this.flashMedia.doPlay(this._normalizeUrl(newUrl));
|
||
|
},
|
||
|
|
||
|
pause: function(){
|
||
|
// summary:
|
||
|
// Pauses the video
|
||
|
this.isPlaying = false;
|
||
|
this.isStopped = false;
|
||
|
//this.onPause();
|
||
|
this.flashMedia.pause();
|
||
|
},
|
||
|
|
||
|
seek: function(/* Float */ time ){
|
||
|
// summary:
|
||
|
// Goes to the time passed in the argument
|
||
|
this.flashMedia.seek(time);
|
||
|
},
|
||
|
|
||
|
|
||
|
// ===================== //
|
||
|
// Player Getter/Setters //
|
||
|
// ===================== //
|
||
|
|
||
|
volume: function(/* Float */ vol){
|
||
|
// summary:
|
||
|
// Sets the volume of the video to the time in the
|
||
|
// argument - between 0 - 1.
|
||
|
//
|
||
|
if(vol){
|
||
|
if(!this.flashMedia) {
|
||
|
this.initialVolume = vol;
|
||
|
}
|
||
|
this.flashMedia.setVolume(this._normalizeVolume(vol));
|
||
|
}
|
||
|
if(!this.flashMedia || !this.flashMedia.doGetVolume) {
|
||
|
return this.initialVolume;
|
||
|
}
|
||
|
return this.flashMedia.getVolume(); // Float
|
||
|
},
|
||
|
|
||
|
// ============= //
|
||
|
// Player Events //
|
||
|
// ============= //
|
||
|
|
||
|
/*=====
|
||
|
onLoad: function(mov){
|
||
|
// summary:
|
||
|
// Fired when the SWF player has loaded
|
||
|
// NOT when the video has loaded
|
||
|
},
|
||
|
|
||
|
onDownloaded: function(percent){
|
||
|
// summary:
|
||
|
// Fires the amount of that the media has been
|
||
|
// downloaded. Number, 0-100
|
||
|
},
|
||
|
|
||
|
onClick: function(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.
|
||
|
},
|
||
|
|
||
|
onSwfSized: function(data){
|
||
|
// summary:
|
||
|
// Fired on SWF resize, or when its
|
||
|
// toggled between fullscreen.
|
||
|
},
|
||
|
|
||
|
onMetaData: function(data, 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
|
||
|
},
|
||
|
|
||
|
onPosition: function( time){
|
||
|
// summary:
|
||
|
// The position of the playhead in seconds
|
||
|
},
|
||
|
|
||
|
onStart: function( data){
|
||
|
// summary:
|
||
|
// Fires when video starts
|
||
|
// Good for setting the play button to pause
|
||
|
// during an autoPlay for example
|
||
|
},
|
||
|
|
||
|
onPlay: function(data){
|
||
|
// summary:
|
||
|
// Fires when video starts and resumes
|
||
|
},
|
||
|
|
||
|
onPause: function(data){
|
||
|
// summary:
|
||
|
// Fires when the pause button is clicked
|
||
|
},
|
||
|
|
||
|
onEnd: function(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(isBuffering){
|
||
|
// summary:
|
||
|
// Fires a boolean to tell if media
|
||
|
// is paused for buffering or if buffering
|
||
|
// has finished
|
||
|
this.isBuffering = isBuffering;
|
||
|
},
|
||
|
|
||
|
onError: function(data, url){
|
||
|
// summary:
|
||
|
// Fired when the player encounters an error
|
||
|
// example:
|
||
|
// | console.warn("ERROR-"+data.type.toUpperCase()+":",
|
||
|
// | data.info.code, " - URL:", url);
|
||
|
},
|
||
|
|
||
|
onStatus: function(data){
|
||
|
// summary:
|
||
|
// Simple status
|
||
|
},
|
||
|
|
||
|
onPlayerStatus: function(data){
|
||
|
// summary:
|
||
|
// The status of the video from the SWF
|
||
|
// playing, stopped, bufering, etc.
|
||
|
},
|
||
|
|
||
|
onResize: function(){
|
||
|
// summary:
|
||
|
// Fired on page resize
|
||
|
},
|
||
|
=====*/
|
||
|
|
||
|
// =============== //
|
||
|
// Private Methods //
|
||
|
// =============== //
|
||
|
|
||
|
_checkBuffer: function(/* Float */time, /* Float */bufferLength){
|
||
|
// summary:
|
||
|
// Checks that there is a proper buffer time between
|
||
|
// current playhead time and the amount of data loaded.
|
||
|
// Works only on FLVs with a duration (not older). Pauses
|
||
|
// the video while continuing download.
|
||
|
//
|
||
|
if(this.percentDownloaded == 100){
|
||
|
if(this.isBuffering){
|
||
|
this.onBuffer(false);
|
||
|
this.flashMedia.doPlay();
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if(!this.isBuffering && bufferLength<.1){
|
||
|
this.onBuffer(true);
|
||
|
this.flashMedia.pause();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var timePercentLoad = this.percentDownloaded*.01*this.duration;
|
||
|
|
||
|
// check if start buffer needed
|
||
|
if(!this.isBuffering && time+this.minBufferTime*.001>timePercentLoad){
|
||
|
this.onBuffer(true);
|
||
|
this.flashMedia.pause();
|
||
|
|
||
|
// check if end buffer needed
|
||
|
}else if(this.isBuffering && time+this.bufferTime*.001<=timePercentLoad){
|
||
|
this.onBuffer(false);
|
||
|
this.flashMedia.doPlay();
|
||
|
}
|
||
|
|
||
|
},
|
||
|
_update: function(){
|
||
|
// summary:
|
||
|
// Helper function to fire onPosition, check download progress,
|
||
|
// and check buffer.
|
||
|
var time = Math.min(this.getTime() || 0, this.duration);
|
||
|
var dObj = this.flashMedia.getLoaded();
|
||
|
this.percentDownloaded = Math.ceil(dObj.bytesLoaded/dObj.bytesTotal*100);
|
||
|
this.onDownloaded(this.percentDownloaded);
|
||
|
this.onPosition(time);
|
||
|
if(this.duration){
|
||
|
this._checkBuffer(time, dObj.buffer);
|
||
|
}
|
||
|
// FIXME: need to remove this on destroy
|
||
|
setTimeout(dojo.hitch(this, "_update"), this.updateTime);
|
||
|
}
|
||
|
|
||
|
});
|