123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- /*
- Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
- Available via Academic Free License >= 2.1 OR the modified BSD license.
- see: http://dojotoolkit.org/license for details
- */
- if(!dojo._hasResource["dojox.av.FLAudio"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
- dojo._hasResource["dojox.av.FLAudio"] = true;
- dojo.provide("dojox.av.FLAudio");
- dojo.experimental("dojox.av.FLAudio");
- dojo.require("dojox.embed.Flash");
- dojo.require("dojox.timing.doLater");
- dojo.declare("dojox.av.FLAudio", null, {
- // summary:
- // Play MP3 files through the Flash SWF built in the
- // DEFT project.
- // description:
- // This class is brand new, so there is a lot of
- // functionality not yet available. The initial
- // purpose is for playing "event" sounds like button
- // clicks, and for loading and controlling multiple
- // sounds at once. As of yet, streaming is not supported
- // and polling the sounds for events during playback
- // may still be missing information. Markup is not
- // supported, as it may not be needed.
- //
- // TODO:
- // Streaming, playback events, crossdomain, CDN support,
- // (alternate SWF location), global volume, ID3 tag,
- // factor out doLater, onLoadStatus needs work,
- // play(position) / seek()
- //
- // example:
- // | new dojox.av.FLAudio({
- // | initialVolume:.7,
- // | initialPan:0,
- // | autoPlay:false
- // | });
- //
- // id: String?
- // The id of this widget and the id of the SWF movie.
- id:"",
- //
- // initialVolume: Number
- // From 0-1
- // Sets volume for all files unless changed with doPlay
- // or setVolume
- initialVolume: 0.7,
- //
- // initialPan: Number
- // From -1 to 1 (-1 is left, 1 is right, 0 is middle)
- // Sets pan for all files unless changed with play
- // or setPan
- initialPan: 0,
- //
- // autoPlay: Boolean
- // If true, all files will play upon load. If false,
- // they load and wait for doPlay() command.
- //
- // isDebug: Boolean?
- // Setting to true tells the SWF to output log messages to Firebug.
- isDebug: false,
- //
- // statusInterval: Number
- // How often in milliseconds that the status of the
- // player is checked - both load and play
- statusInterval:200,
- //
- // _swfPath: Uri
- // The path to the video player SWF resource
- _swfPath: dojo.moduleUrl("dojox.av", "resources/audio.swf"),
- //
- //
- // allowScriptAccess: String
- // Whether the SWF can access the container JS
- allowScriptAccess:"always",
- //
- // allowNetworking: String
- // Whether SWF is restricted to a domain
- allowNetworking: "all",
- //
- constructor: function(/*Object*/options){
- // Provide this function for the SWF to ensure that the it is playing
- // in HTML.
- dojo.global.swfIsInHTML = function(){ return true; }
- dojo.mixin(this, options || {});
- if(!this.id){ this.id = "flaudio_"+new Date().getTime(); }
- this.domNode = dojo.doc.createElement("div");
- dojo.style(this.domNode, {
- position:"relative",
- width:"1px",
- height:"1px",
- top:"1px",
- left:"1px"
- });
- dojo.body().appendChild(this.domNode);
- this.init();
- },
- init: function(){
- // summary:
- // Initialize the media.
- //
- //
- this._subs = [];
- this.initialVolume = this._normalizeVolume(this.initialVolume);
- var args = {
- path:this._swfPath.uri,
- width:"1px",
- height:"1px",
- minimumVersion:9, // this may need to be 10, not sure
- expressInstall:true,
- params:{
- wmode:"transparent",
- allowScriptAccess:this.allowScriptAccess,
- allowNetworking:this.allowNetworking
- },
- // only pass in simple variables - no deep objects
- vars:{
- id:this.id,
- autoPlay:this.autoPlay,
- initialVolume:this.initialVolume,
- initialPan:this.initialPan,
- statusInterval:this.statusInterval,
- isDebug:this.isDebug
- }
- };
- this._sub("mediaError", "onError");
- this._sub("filesProgress", "onLoadStatus");
- this._sub("filesAllLoaded", "onAllLoaded");
- this._sub("mediaPosition", "onPlayStatus");
- this._sub("mediaEnd", "onComplete");
- this._sub("mediaMeta", "onID3");
- this._flashObject = new dojox.embed.Flash(args, this.domNode);
- this._flashObject.onError = function(err){
- console.warn("Flash Error:", err);
- };
- this._flashObject.onLoad = dojo.hitch(this, function(mov){
- this.flashMedia = mov;
- this.isPlaying = this.autoPlay;
- this.isStopped = !this.autoPlay;
- this.onLoad(this.flashMedia);
- });
- },
- // ============== //
- // Loading Files //
- // ============== //
- load: function(/*Object*/options){
- // summary:
- // Adds a media object to the playlist
- // ***This can be called repeatedly to add multiple items.
- // options: Object
- // url: String
- // (required) path to MP3 media
- // url must be absolute or relative to SWF,
- // not dojo or the html. An effort will be made
- // to fix incorrect paths.
- // id: String
- // (optional) an identifier to later determine
- // which media to control.
- // returns:
- // The normalized url, which can be used to identify the
- // audio.
- //
- if(dojox.timing.doLater(this.flashMedia, this)){ return false; }
- if(!options.url){
- throw new Error("An url is required for loading media");
- return false;
- }else{
- options.url = this._normalizeUrl(options.url);
- }
- this.flashMedia.load(options);
- return options.url; // String
- },
- // ============================= //
- // Methods to control the sound //
- // ============================= //
- doPlay: function(/*Object*/options){
- // summary:
- // Tell media to play, based on
- // the options passed.
- // options: Object
- // volume: Number
- // Sets the volume
- // pan: Number
- // Sets left/right pan
- // index:Number OR id:String OR url:String
- // Choose one of the above to indentify
- // the media you wish to control. id is
- // set by you. index is the order in which
- // media was added (zero based)
- // NOTE: lack of an identifier will default
- // to first (or only) item.
- // NOTE: Can't name this method "play()" as it causes
- // an IE error.
- this.flashMedia.doPlay(options);
- },
- pause: function(/*Object*/options){
- // summary:
- // Tell media to pause, based on identifier in
- // the options passed.
- // options: Object
- // index:Number OR id:String OR url:String
- // See doPlay()
- //
- this.flashMedia.pause(options);
- },
- stop: function(/*Object*/options){
- // summary:
- // Tell media to stop, based on identifier in
- // the options passed.
- // options:
- // index:Number OR id:String OR url:String
- // See doPlay()
- //
- this.flashMedia.doStop(options);
- },
- setVolume: function(/*Object*/options){
- // summary:
- // Set media volume, based on identifier in
- // the options passed.
- // options:
- // volume: Number
- // 0 to 1
- // index:Number OR id:String OR url:String
- // See doPlay()
- //
- this.flashMedia.setVolume(options);
- },
- setPan: function(/*Object*/options){
- // summary:
- // Set media pan, based on identifier in
- // the options passed.
- // options:
- // pan:Number
- // -1 to 1
- // index:Number OR id:String OR url:String
- // See doPlay()
- //
- this.flashMedia.setPan(options);
- },
- getVolume: function(/*Object*/options){
- // summary:
- // Get media volume, based on identifier in
- // the options passed.
- // options:
- // index:Number OR id:String OR url:String
- // See doPlay()
- //
- return this.flashMedia.getVolume(options);
- },
- getPan: function(/*Object*/options){
- // summary:
- // Set media pan, based on identifier in
- // the options passed.
- // options:
- // index:Number OR id:String OR url:String
- // See doPlay()
- //
- return this.flashMedia.getPan(options);
- },
- getPosition: function(/*Object*/options){
- // summary:
- // Get the current time.
- // options:
- // index:Number OR id:String OR url:String
- // See doPlay()
- //
- return this.flashMedia.getPosition(options);
- },
- // ============= //
- // Sound Events //
- // ============= //
- onError: function(msg){
- // summary:
- // stub fired when an error occurs
- console.warn("SWF ERROR:", msg)
- },
- onLoadStatus: function(/*Array*/events){
- // summary:
- },
- onAllLoaded: function(){
- // summary:
- // stub fired
- },
- onPlayStatus: function(/*Array*/events){
- // summary:
- },
- onComplete: function(/*Array*/events){
- // summary:
- // Fired at the end of a media file.
- },
- onLoad: function(){
- // summary:
- // stub fired when SWF is ready
- },
- onID3: function(evt){
- // summary:
- // Fired when the ID3 data is received.
- },
- 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);
- },
- _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;
- }
- });
- }
|