source: Dev/trunk/src/client/dojox/av/FLAudio.js @ 536

Last change on this file since 536 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 8.9 KB
Line 
1define(['dojo', 'dojox/embed/Flash', 'dojox/timing/doLater'],function(dojo, dijit){
2
3dojo.experimental("dojox.av.FLVideo");
4
5return dojo.declare("dojox.av.FLAudio", null, {
6
7        // summary:
8        //              Play MP3 files through the Flash SWF built in the
9        //              DEFT project.
10        // description:
11        //              This class is brand new, so there is a lot of
12        //              functionality not yet available. The initial
13        //              purpose is for playing "event" sounds like button
14        //              clicks, and for loading and controlling multiple
15        //              sounds at once. As of yet, streaming is not supported
16        //              and polling the sounds for events during playback
17        //              may still be missing information. Markup is not
18        //              supported, as it may not be needed.
19        //
20        //              TODO:
21        //              Streaming, playback events, crossdomain, CDN support,
22        //              (alternate SWF location), global volume, ID3 tag,
23        //              factor out doLater, onLoadStatus needs work,
24        //              play(position) / seek()
25        //
26        // example:
27        //              |       new dojox.av.FLAudio({
28        //              |               initialVolume:.7,
29        //              |               initialPan:0,
30        //              |               autoPlay:false
31        //              |       });
32
33        // id: String?
34        //              The id of this widget and the id of the SWF movie.
35        id:"",
36
37        // initialVolume: Number
38        //              From 0-1
39        //              Sets volume for all files unless changed with doPlay
40        //              or setVolume
41        initialVolume: 0.7,
42
43        // initialPan: Number
44        //              From -1 to 1 (-1 is left, 1 is right, 0 is middle)
45        //              Sets pan for all files unless changed with play
46        //              or setPan
47        initialPan: 0,
48
49        // autoPlay: Boolean
50        //              If true, all files will play upon load. If false,
51        //              they load and wait for doPlay() command.
52
53        // isDebug: Boolean?
54        //              Setting to true tells the SWF to output log messages to Firebug.
55        isDebug: false,
56
57        // statusInterval: Number
58        //              How often in milliseconds that the status of the
59        //              player is checked - both load and play
60        statusInterval:200,
61
62        // _swfPath: Uri
63        //              The path to the video player SWF resource
64        _swfPath: dojo.moduleUrl("dojox.av", "resources/audio.swf"),
65
66        // allowScriptAccess: String
67        //              Whether the SWF can access the container JS
68        allowScriptAccess:"always",
69
70        // allowNetworking: String
71        //              Whether SWF is restricted to a domain
72        allowNetworking: "all",
73
74        constructor: function(/*Object*/options){
75
76                // Provide this function for the SWF to ensure that the it is playing
77                // in HTML.
78                dojo.global.swfIsInHTML = function(){ return true; }
79
80                dojo.mixin(this, options || {});
81                if(!this.id){ this.id = "flaudio_"+new Date().getTime(); }
82                this.domNode = dojo.doc.createElement("div");
83                dojo.style(this.domNode, {
84                        position:"relative",
85                        width:"1px",
86                        height:"1px",
87                        top:"1px",
88                        left:"1px"
89                });
90                dojo.body().appendChild(this.domNode);
91                this.init();
92        },
93
94        init: function(){
95                // summary:
96                //              Initialize the media.
97
98                this._subs = [];
99                this.initialVolume = this._normalizeVolume(this.initialVolume);
100
101                var args = {
102                        path:this._swfPath,
103                        width:"1px",
104                        height:"1px",
105                        minimumVersion:9, // this may need to be 10, not sure
106                        expressInstall:true,
107                        params:{
108                                wmode:"transparent",
109                                allowScriptAccess:this.allowScriptAccess,
110                                allowNetworking:this.allowNetworking
111                        },
112                        // only pass in simple variables - no deep objects
113                        vars:{
114                                id:this.id,
115                                autoPlay:this.autoPlay,
116                                initialVolume:this.initialVolume,
117                                initialPan:this.initialPan,
118                                statusInterval:this.statusInterval,
119                                isDebug:this.isDebug
120                        }
121                };
122
123                this._sub("mediaError",    "onError");
124                this._sub("filesProgress", "onLoadStatus");
125                this._sub("filesAllLoaded", "onAllLoaded");
126                this._sub("mediaPosition", "onPlayStatus");
127                this._sub("mediaEnd", "onComplete");
128                this._sub("mediaMeta",     "onID3");
129
130                this._flashObject = new dojox.embed.Flash(args, this.domNode);
131                this._flashObject.onError = function(err){
132                        console.warn("Flash Error:", err);
133                };
134                this._flashObject.onLoad = dojo.hitch(this, function(mov){
135                        this.flashMedia = mov;
136                        this.isPlaying = this.autoPlay;
137                        this.isStopped = !this.autoPlay;
138                        this.onLoad(this.flashMedia);
139                });
140        },
141
142        //  ==============  //
143        //  Loading Files   //
144        //  ==============  //
145
146        load: function(/*Object*/options){
147                // summary:
148                //              Adds a media object to the playlist
149                //              ***This can be called repeatedly to add multiple items.
150                // options: Object
151                //              - url: String:
152                //                      (required) path to MP3 media
153                //                      url must be absolute or relative to SWF,
154                //                      not dojo or the html. An effort will be made
155                //                      to fix incorrect paths.
156                //              - id: String:
157                //                      (optional) an identifier to later determine
158                //                      which media to control.
159                // returns:
160                //              The normalized url, which can be used to identify the
161                //              audio.
162
163                if(dojox.timing.doLater(this.flashMedia, this)){ return false; }
164                if(!options.url){
165                        throw new Error("An url is required for loading media");
166                }else{
167                        options.url = this._normalizeUrl(options.url);
168                }
169                this.flashMedia.load(options);
170
171                return options.url; // String
172        },
173
174        //  =============================  //
175        //  Methods to control the sound   //
176        //  =============================  //
177
178        doPlay: function(/*Object*/options){
179                // summary:
180                //              Tell media to play, based on
181                //              the options passed.
182                // options: Object
183                //              - volume: Number:
184                //                      Sets the volume
185                //              - pan: Number:
186                //                      Sets left/right pan
187                //              - index:Number OR id:String OR url:String:
188                //                      Choose one of the above to identify
189                //                      the media you wish to control. id is
190                //                      set by you. index is the order in which
191                //                      media was added (zero based)
192                //                      NOTE: lack of an identifier will default
193                //                      to first (or only) item.
194
195                //      NOTE: Can't name this method "play()" as it causes
196                //                      an IE error.
197                this.flashMedia.doPlay(options);
198        },
199
200        pause: function(/*Object*/options){
201                // summary:
202                //              Tell media to pause, based on identifier in
203                //              the options passed.
204                // options: Object
205                //              index:Number OR id:String OR url:String.
206                //              See doPlay().
207
208                this.flashMedia.pause(options);
209        },
210
211        stop: function(/*Object*/options){
212                // summary:
213                //              Tell media to stop, based on identifier in
214                //              the options passed.
215                // options:
216                //              index:Number OR id:String OR url:String.
217                //              See doPlay().
218
219                this.flashMedia.doStop(options);
220        },
221
222        setVolume: function(/*Object*/options){
223                // summary:
224                //              Set media volume, based on identifier in
225                //              the options passed.
226                // options:
227                //              volume: Number
228                //              0 to 1
229                //              index:Number OR id:String OR url:String.
230                //              See doPlay().
231
232                this.flashMedia.setVolume(options);
233        },
234
235        setPan: function(/*Object*/options){
236                // summary:
237                //              Set media pan, based on identifier in
238                //              the options passed.
239                // options:
240                //              - pan:Number (from -1 to 1)
241                //              - index:Number OR id:String OR url:String (see doPlay())
242
243                this.flashMedia.setPan(options);
244        },
245
246        getVolume: function(/*Object*/options){
247                // summary:
248                //              Get media volume, based on identifier in
249                //              the options passed.
250                // options:
251                //              index:Number OR id:String OR url:String.
252                //              See doPlay().
253
254                return this.flashMedia.getVolume(options);
255        },
256
257        getPan: function(/*Object*/options){
258                // summary:
259                //              Set media pan, based on identifier in
260                //              the options passed.
261                // options:
262                //              index:Number OR id:String OR url:String.
263                //              See doPlay().
264
265                return this.flashMedia.getPan(options);
266        },
267
268        getPosition: function(/*Object*/options){
269                // summary:
270                //              Get the current time.
271                // options:
272                //              index:Number OR id:String OR url:String.
273                //              See doPlay().
274
275                return this.flashMedia.getPosition(options);
276        },
277
278        //  =============  //
279        //  Sound Events   //
280        //  =============  //
281        onError: function(msg){
282                // summary:
283                //              stub fired when an error occurs
284                console.warn("SWF ERROR:", msg)
285        },
286
287        onLoadStatus: function(/*Array*/events){
288                // summary:
289        },
290
291        onAllLoaded: function(){
292                // summary:
293                //              stub fired
294        },
295
296        onPlayStatus: function(/*Array*/events){
297                // summary:
298        },
299
300        onComplete: function(/*Array*/events){
301                // summary:
302                //              Fired at the end of a media file.
303        },
304
305        onLoad: function(){
306                // summary:
307                //              stub fired when SWF is ready
308        },
309        onID3: function(evt){
310                // summary:
311                //              Fired when the ID3 data is received.
312        },
313
314
315
316        destroy: function(){
317                // summary:
318                //              destroys flash
319                if(!this.flashMedia){
320                        this._cons.push(dojo.connect(this, "onLoad", this, "destroy"));
321                        return;
322                }
323                dojo.forEach(this._subs, function(s){
324                        dojo.unsubscribe(s);
325                });
326                dojo.forEach(this._cons, function(c){
327                        dojo.disconnect(c);
328                });
329                this._flashObject.destroy();
330                //dojo._destroyElement(this.flashDiv);
331        },
332
333
334
335        _sub: function(topic, method){
336                // summary:
337                //              helper for subscribing to topics
338                dojo.subscribe(this.id+"/"+topic, this, method);
339        },
340
341        _normalizeVolume: function(vol){
342                // summary:
343                //              Ensures volume is less than one
344                //
345                if(vol>1){
346                        while(vol>1){
347                                vol*=.1
348                        }
349                }
350                return vol;
351        },
352
353        _normalizeUrl: function(_url){
354                // summary:
355                //              Checks that path is relative to HTML file or
356                //              converts it to an absolute path.
357
358                if(_url && _url.toLowerCase().indexOf("http")<0){
359                        //
360                        // Appears to be a relative path. Attempt to  convert it to absolute,
361                        // so it will better target the SWF.
362                        var loc = window.location.href.split("/");
363                        loc.pop();
364                        loc = loc.join("/")+"/";
365
366                        _url = loc+_url;
367                }
368                return _url;
369        }
370
371});
372
373});
Note: See TracBrowser for help on using the repository browser.