source: Dev/branches/rest-dojo-ui/client/dojox/av/FLAudio.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 9.0 KB
Line 
1define(['dojo', 'dojox/embed/Flash', 'dojox/timing/doLater'],function(dojo, dijit){
2
3dojo.experimental("dojox.av.FLVideo");
4
5dojo.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        //
67        // allowScriptAccess: String
68        //              Whether the SWF can access the container JS
69        allowScriptAccess:"always",
70        //
71        // allowNetworking: String
72        //              Whether SWF is restricted to a domain
73        allowNetworking: "all",
74        //
75
76        constructor: function(/*Object*/options){
77
78                // Provide this function for the SWF to ensure that the it is playing
79                // in HTML.
80                dojo.global.swfIsInHTML = function(){ return true; }
81
82                dojo.mixin(this, options || {});
83                if(!this.id){ this.id = "flaudio_"+new Date().getTime(); }
84                this.domNode = dojo.doc.createElement("div");
85                dojo.style(this.domNode, {
86                        position:"relative",
87                        width:"1px",
88                        height:"1px",
89                        top:"1px",
90                        left:"1px"
91                });
92                dojo.body().appendChild(this.domNode);
93                this.init();
94        },
95
96        init: function(){
97                // summary:
98                // Initialize the media.
99                //
100                //
101                this._subs = [];
102                this.initialVolume = this._normalizeVolume(this.initialVolume);
103
104                var args = {
105                        path:this._swfPath.uri,
106                        width:"1px",
107                        height:"1px",
108                        minimumVersion:9, // this may need to be 10, not sure
109                        expressInstall:true,
110                        params:{
111                                wmode:"transparent",
112                                allowScriptAccess:this.allowScriptAccess,
113                                allowNetworking:this.allowNetworking
114                        },
115                        // only pass in simple variables - no deep objects
116                        vars:{
117                                id:this.id,
118                                autoPlay:this.autoPlay,
119                                initialVolume:this.initialVolume,
120                                initialPan:this.initialPan,
121                                statusInterval:this.statusInterval,
122                                isDebug:this.isDebug
123                        }
124                };
125
126                this._sub("mediaError",    "onError");
127                this._sub("filesProgress", "onLoadStatus");
128                this._sub("filesAllLoaded", "onAllLoaded");
129                this._sub("mediaPosition", "onPlayStatus");
130                this._sub("mediaEnd", "onComplete");
131                this._sub("mediaMeta",     "onID3");
132
133                this._flashObject = new dojox.embed.Flash(args, this.domNode);
134                this._flashObject.onError = function(err){
135                        console.warn("Flash Error:", err);
136                };
137                this._flashObject.onLoad = dojo.hitch(this, function(mov){
138                        this.flashMedia = mov;
139                        this.isPlaying = this.autoPlay;
140                        this.isStopped = !this.autoPlay;
141                        this.onLoad(this.flashMedia);
142                });
143        },
144
145        //  ==============  //
146        //  Loading Files   //
147        //  ==============  //
148
149        load: function(/*Object*/options){
150                // summary:
151                //              Adds a media object to the playlist
152                //              ***This can be called repeatedly to add multiple items.
153                //      options: Object
154                //              url: String
155                //                      (required) path to MP3 media
156                //                      url must be absolute or relative to SWF,
157                //                      not dojo or the html. An effort will be made
158                //                      to fix incorrect paths.
159                //              id: String
160                //                      (optional) an identifier to later determine
161                //                      which media to control.
162                //      returns:
163                //              The normalized url, which can be used to identify the
164                //              audio.
165                //
166                if(dojox.timing.doLater(this.flashMedia, this)){ return false; }
167                if(!options.url){
168                        throw new Error("An url is required for loading media");
169                        return false;
170                }else{
171                        options.url = this._normalizeUrl(options.url);
172                }
173                this.flashMedia.load(options);
174
175                return options.url; // String
176        },
177
178        //  =============================  //
179        //  Methods to control the sound   //
180        //  =============================  //
181
182        doPlay: function(/*Object*/options){
183                // summary:
184                //              Tell media to play, based on
185                //              the options passed.
186                // options: Object
187                //              volume: Number
188                //                      Sets the volume
189                //              pan: Number
190                //                      Sets left/right pan
191                //              index:Number OR id:String OR url:String
192                //                      Choose one of the above to indentify
193                //                      the media you wish to control. id is
194                //                      set by you. index is the order in which
195                //                      media was added (zero based)
196                //                      NOTE: lack of an identifier will default
197                //                      to first (or only) item.
198                //      NOTE: Can't name this method "play()" as it causes
199                //                      an IE error.
200                this.flashMedia.doPlay(options);
201        },
202
203        pause: function(/*Object*/options){
204                // summary:
205                //              Tell media to pause, based on identifier in
206                //              the options passed.
207                // options: Object
208                //              index:Number OR id:String OR url:String
209                //                      See doPlay()
210                //
211                this.flashMedia.pause(options);
212        },
213
214        stop: function(/*Object*/options){
215                // summary:
216                //              Tell media to stop, based on identifier in
217                //              the options passed.
218                // options:
219                //              index:Number OR id:String OR url:String
220                //                      See doPlay()
221                //
222                this.flashMedia.doStop(options);
223        },
224
225        setVolume: function(/*Object*/options){
226                // summary:
227                //              Set media volume, based on identifier in
228                //              the options passed.
229                // options:
230                //              volume: Number
231                //              0 to 1
232                //              index:Number OR id:String OR url:String
233                //                      See doPlay()
234                //
235                this.flashMedia.setVolume(options);
236        },
237
238        setPan: function(/*Object*/options){
239                // summary:
240                //              Set media pan, based on identifier in
241                //              the options passed.
242                // options:
243                //              pan:Number
244                //                      -1 to 1
245                //              index:Number OR id:String OR url:String
246                //                      See doPlay()
247                //
248                this.flashMedia.setPan(options);
249        },
250
251        getVolume: function(/*Object*/options){
252                // summary:
253                //              Get media volume, based on identifier in
254                //              the options passed.
255                // options:
256                //              index:Number OR id:String OR url:String
257                //                      See doPlay()
258                //
259                return this.flashMedia.getVolume(options);
260        },
261
262        getPan: function(/*Object*/options){
263                // summary:
264                //              Set media pan, based on identifier in
265                //              the options passed.
266                // options:
267                //              index:Number OR id:String OR url:String
268                //                      See doPlay()
269                //
270                return this.flashMedia.getPan(options);
271        },
272
273        getPosition: function(/*Object*/options){
274                // summary:
275                //              Get the current time.
276                // options:
277                //              index:Number OR id:String OR url:String
278                //                      See doPlay()
279                //
280                return this.flashMedia.getPosition(options);
281        },
282
283        //  =============  //
284        //  Sound Events   //
285        //  =============  //
286        onError: function(msg){
287                // summary:
288                //              stub fired when an error occurs
289                console.warn("SWF ERROR:", msg)
290        },
291
292        onLoadStatus: function(/*Array*/events){
293                // summary:
294        },
295
296        onAllLoaded: function(){
297                // summary:
298                //              stub fired
299        },
300
301        onPlayStatus: function(/*Array*/events){
302                // summary:
303        },
304
305        onComplete: function(/*Array*/events){
306                // summary:
307                //              Fired at the end of a media file.
308        },
309
310        onLoad: function(){
311                // summary:
312                //              stub fired when SWF is ready
313        },
314        onID3: function(evt){
315                //      summary:
316                //              Fired when the ID3 data is received.
317        },
318
319
320
321        destroy: function(){
322                // summary:
323                //              destroys flash
324                if(!this.flashMedia){
325                        this._cons.push(dojo.connect(this, "onLoad", this, "destroy"));
326                        return;
327                }
328                dojo.forEach(this._subs, function(s){
329                        dojo.unsubscribe(s);
330                });
331                dojo.forEach(this._cons, function(c){
332                        dojo.disconnect(c);
333                });
334                this._flashObject.destroy();
335                //dojo._destroyElement(this.flashDiv);
336        },
337
338
339
340        _sub: function(topic, method){
341                // summary:
342                // helper for subscribing to topics
343                dojo.subscribe(this.id+"/"+topic, this, method);
344        },
345
346        _normalizeVolume: function(vol){
347                // summary:
348                //              Ensures volume is less than one
349                //
350                if(vol>1){
351                        while(vol>1){
352                                vol*=.1
353                        }
354                }
355                return vol;
356        },
357
358        _normalizeUrl: function(_url){
359                // summary:
360                //              Checks that path is relative to HTML file or
361                //              convertes it to an absolute path.
362                //
363                if(_url && _url.toLowerCase().indexOf("http")<0){
364                        //
365                        // Appears to be a relative path. Attempt to  convert it to absolute,
366                        // so it will better target the SWF.
367                        var loc = window.location.href.split("/");
368                        loc.pop();
369                        loc = loc.join("/")+"/";
370
371                        _url = loc+_url;
372                }
373                return _url;
374        }
375
376});
377return dojox.av.FLAudio;
378});
Note: See TracBrowser for help on using the repository browser.