source: trunk/as3/com/jeroenwijering/models/VideoModel.as @ 12

Revision 12, 5.8 KB checked in by jeroen, 5 years ago (diff)

added caption display for 3GPP and Captionate

  • Property svn:executable set to *
Line 
1/**
2* Wrapper for playback of progressively downloaded video.
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.display.DisplayObject;
12import flash.media.SoundTransform;
13import flash.media.Video;
14import flash.net.*;
15import flash.utils.clearInterval;
16import flash.utils.setInterval;
17
18
19public class VideoModel implements ModelInterface {
20
21
22        /** reference to the model. **/
23        private var model:Model;
24        /** Video object to be instantiated. **/
25        private var video:Video;
26        /** NetConnection object for setup of the video stream. **/
27        private var connection:NetConnection;
28        /** NetStream instance that handles the stream IO. **/
29        private var stream:NetStream;
30        /** Sound control object. **/
31        private var transform:SoundTransform;
32        /** Interval ID for the time. **/
33        private var timeinterval:Number;
34        /** Interval ID for the loading. **/
35        private var loadinterval:Number;
36        /** Metadata received switch. **/
37        private var metadata:Boolean;
38
39
40        /** Constructor; sets up the connection and display. **/
41        public function VideoModel(mod:Model) {
42                model = mod;
43                connection = new NetConnection();
44                connection.addEventListener(NetStatusEvent.NET_STATUS,statusHandler);
45                connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR,errorHandler);
46                connection.objectEncoding = ObjectEncoding.AMF0;
47                connection.connect(null);
48                stream = new NetStream(connection);
49                stream.addEventListener(NetStatusEvent.NET_STATUS,statusHandler);
50                stream.addEventListener(IOErrorEvent.IO_ERROR,errorHandler);
51                stream.bufferTime = model.config['bufferlength'];
52                stream.client = this;
53                video = new Video(320,240);
54                video.attachNetStream(stream);
55                transform = new SoundTransform();
56                stream.soundTransform = transform;
57                quality(model.config['quality']);
58                model.config['mute'] == true ? volume(0): volume(model.config['volume']);
59        };
60
61
62        /** Catch security errors. **/
63        private function errorHandler(evt:ErrorEvent) {
64                model.sendEvent(ModelEvent.ERROR,{message:evt.text});
65        };
66
67
68        /** Load content. **/
69        public function load() {
70                stream.close();
71                stream.play(model.playlist[model.config['item']]['file']);
72                model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING});
73                loadinterval = setInterval(loadHandler,100);
74                timeinterval = setInterval(timeHandler,100);
75        };
76
77
78        /** Interval for the loading progress **/
79        private function loadHandler() {
80                var ldd = stream.bytesLoaded;
81                var ttl = stream.bytesTotal;
82                model.sendEvent(ModelEvent.LOADED,{loaded:ldd,total:ttl});
83                if(ldd == ttl && ldd > 0) {
84                        clearInterval(loadinterval);
85                }
86        };
87
88
89        /** Handler for captionate events. **/
90        public function onCaption(cps:String,spk:Number) {
91                var dat = {
92                        captions:cps,
93                        speaker:spk
94                };
95                model.sendEvent(ModelEvent.META,dat);
96        };
97
98
99        /** Get metadata information from netstream class. **/
100        public function onMetaData(info:Object) {
101                if(!metadata) {
102                        metadata = true;
103                        if(info.width) {
104                                video.width = info.width;
105                                video.height = info.height;
106                                model.mediaHandler(video);
107                        } else {
108                                model.mediaHandler();
109                        }
110                        var dat = new Object();
111                        for(var i in info) { dat[i] = info[i]; }
112                        model.sendEvent(ModelEvent.META,dat);
113                        if(model.playlist[model.config['item']]['start'] > 0) {
114                                seek(model.playlist[model.config['item']]['start']);
115                        }
116                }
117        };
118
119
120        /** Get textdata from netstream. **/
121        public function onTextData(info:Object) {
122                var dat = new Object();
123                for(var i in info) {
124                        dat[i] = info[i];
125                }
126                model.sendEvent(ModelEvent.META,dat);
127        };
128
129
130        /** Pause playback. **/
131        public function pause() {
132                clearInterval(timeinterval);
133                stream.pause();
134                model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PAUSED});
135        };
136
137
138        /** Resume playing. **/
139        public function play() {
140                stream.resume();
141                model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PLAYING});
142                timeinterval = setInterval(timeHandler,100);
143        };
144
145
146        /** Change the smoothing mode. **/
147        public function quality(qua:Boolean) {
148                if(qua == true) {
149                        video.smoothing = true;
150                        video.deblocking = 4;
151                } else {
152                        video.smoothing = false;
153                        video.deblocking = 1;
154                }
155        };
156
157
158        /** Change the smoothing mode. **/
159        public function seek(pos:Number) {
160                clearInterval(timeinterval);
161                stream.seek(pos);
162                play();
163        };
164
165
166        /** Receive NetStream status updates. **/
167        private function statusHandler(evt:NetStatusEvent) {
168                if(evt.info.code == "NetStream.Play.Stop" && stream.bytesLoaded == stream.bytesTotal) {
169                        clearInterval(timeinterval);
170                        model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.COMPLETED});
171                } else if (evt.info.code == "NetStream.Play.StreamNotFound") {
172                        stop();
173                        model.sendEvent(ModelEvent.ERROR,{message:'Video not found: '+model.playlist[model.config['item']]['file']});
174                }
175                model.sendEvent(ModelEvent.META,{info:evt.info.code});
176        };
177
178
179        /** Destroy the video. **/
180        public function stop() {
181                stream.close();
182                metadata = false;
183                clearInterval(loadinterval);
184                clearInterval(timeinterval);
185        };
186
187
188        /** Interval for the position progress **/
189        private function timeHandler() {
190                var bfr = Math.round(stream.bufferLength/stream.bufferTime*100);
191                var pos = Math.round(stream.time*10)/10;
192                var dur = model.playlist[model.config['item']]['duration'];
193                if(bfr < 100 && pos < Math.abs(dur-stream.bufferTime*2)) {
194                        model.sendEvent(ModelEvent.BUFFER,{percentage:bfr});
195                        if(model.config['state'] != ModelStates.BUFFERING && bfr < 50) {
196                                model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING});
197                        }
198                } else if (model.config['state'] == ModelStates.BUFFERING) {
199                        model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PLAYING});
200                }
201                if(dur > 0) {
202                        model.sendEvent(ModelEvent.TIME,{position:pos,duration:dur});
203                }
204        };
205
206
207        /** Set the volume level. **/
208        public function volume(vol:Number) {
209                transform.volume = vol/100;
210                stream.soundTransform = transform;
211        };
212
213
214};
215
216
217}
Note: See TracBrowser for help on using the repository browser.