source: branches/4.2/com/jeroenwijering/models/SoundModel.as @ 75

Revision 75, 4.8 KB checked in by jeroen, 5 years ago (diff)

air version is working, string of fixes to 4.2

  • Property svn:executable set to *
Line 
1/**
2* Wrapper for playback of mp3 sounds.
3**/
4package com.jeroenwijering.models {
5
6
7import com.jeroenwijering.events.*;
8import com.jeroenwijering.models.ModelInterface;
9import com.jeroenwijering.player.Model;
10import flash.events.*;
11import flash.media.*;
12import flash.net.URLRequest;
13import flash.utils.clearInterval;
14import flash.utils.setInterval;
15
16
17public class SoundModel implements ModelInterface {
18
19
20        /** reference to the model. **/
21        private var model:Model;
22        /** sound object to be instantiated. **/
23        private var sound:Sound;
24        /** Sound control object. **/
25        private var transform:SoundTransform;
26        /** Sound channel object. **/
27        private var channel:SoundChannel;
28        /** Sound context object. **/
29        private var context:SoundLoaderContext;
30        /** Interval ID for the time. **/
31        private var interval:Number;
32        /** Current position. **/
33        private var position:Number;
34        /** Estimated duration. **/
35        private var duration:Number;
36
37
38        /** Constructor; sets up the connection and display. **/
39        public function SoundModel(mod:Model):void {
40                model = mod;
41                transform = new SoundTransform();
42                model.config['mute'] == true ? volume(0): volume(model.config['volume']);
43                context = new SoundLoaderContext(model.config['bufferlength']*1000);
44        };
45
46
47        /** Sound completed; send event. **/
48        private function completeHandler(evt:Event):void {
49                clearInterval(interval);
50                position = model.playlist[model.config['item']]['start'];
51                model.sendEvent(ModelEvent.TIME,{position:position,duration:duration});
52                model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.COMPLETED});
53        };
54
55
56        /** Catch errors. **/
57        private function errorHandler(evt:ErrorEvent):void {
58                model.sendEvent(ModelEvent.ERROR,{message:evt.text});
59                stop();
60        };
61
62
63        /** Forward ID3 data from the sound. **/
64        private function id3Handler(evt:Event):void {
65                try {
66                        var id3:ID3Info = sound.id3;
67                        var obj = {
68                                album:id3.album,
69                                artist:id3.artist,
70                                comment:id3.comment,
71                                genre:id3.genre,
72                                songName:id3.songName,
73                                track:id3.track,
74                                year:id3.year
75                        }
76                        model.sendEvent(ModelEvent.META,obj);
77                } catch (err:Error) {}
78        };
79
80
81        /** Load the sound. **/
82        public function load():void {
83                position = model.playlist[model.config['item']]['start'];
84                duration = model.playlist[model.config['item']]['duration'];
85                sound = new Sound();
86                sound.addEventListener(IOErrorEvent.IO_ERROR,errorHandler);
87                sound.addEventListener(ProgressEvent.PROGRESS,progressHandler);
88                sound.addEventListener(Event.ID3,id3Handler);
89                sound.load(new URLRequest(model.playlist[model.config['item']]['file']),context);
90                model.mediaHandler();
91                play();
92        };
93
94
95        /** Pause the sound. **/
96        public function pause():void {
97                clearInterval(interval);
98                channel.stop();
99                model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PAUSED});
100        };
101
102
103        /** Play the sound. **/
104        public function play():void {
105                channel = sound.play(position*1000,0,transform);
106                channel.removeEventListener(Event.SOUND_COMPLETE,completeHandler);
107                channel.addEventListener(Event.SOUND_COMPLETE,completeHandler);
108                interval = setInterval(timeHandler,100);
109                model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PLAYING});
110        };
111
112
113        /** Interval for the loading progress **/
114        private function progressHandler(evt:ProgressEvent):void {
115                var ldd = evt.bytesLoaded;
116                var ttl = evt.bytesTotal;
117                model.sendEvent(ModelEvent.LOADED,{loaded:ldd,total:ttl});
118        };
119
120
121        /** Change quality setting. **/
122        public function quality(typ:Boolean):void {};
123
124
125        /** Seek in the sound. **/
126        public function seek(pos:Number):void {
127                clearInterval(interval);
128                position = pos;
129                channel.stop();
130                play();
131        };
132
133
134        /** Destroy the sound. **/
135        public function stop():void {
136                clearInterval(interval);
137                if(channel) { channel.stop(); }
138                try {
139                        sound.close();
140                } catch (err:Error) {}
141        };
142
143
144        /** Interval for the position progress **/
145        private function timeHandler():void {
146                position = Math.round(channel.position/100)/10;
147                var dur = Math.round(sound.length*sound.bytesTotal/sound.bytesLoaded/100)/10;
148                if(sound.isBuffering == true && sound.bytesTotal > sound.bytesLoaded) {
149                        if(model.config['state'] != ModelStates.BUFFERING) {
150                                model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING});
151                        } else {
152                                var pct = Math.floor(sound.length/(channel.position+model.config['bufferlength']*1000)*100);
153                                        model.sendEvent(ModelEvent.BUFFER,{percentage:pct});
154                        }
155                } else if (model.config['state'] == ModelStates.BUFFERING && sound.isBuffering == false) {
156                        model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PLAYING});
157                }
158                if(dur > position) {
159                        model.sendEvent(ModelEvent.TIME,{position:position,duration:dur});
160                }
161                if(dur != duration && !isNaN(dur)) {
162                        duration = dur;
163                        model.sendEvent(ModelEvent.META,{duration:duration});
164                }
165        };
166
167
168        /** Set the volume level. **/
169        public function volume(vol:Number):void {
170                transform.volume = vol/100;
171                if(channel) {
172                        channel.soundTransform = transform;
173                }
174        };
175
176
177};
178
179
180}
Note: See TracBrowser for help on using the repository browser.