Changeset 806


Ignore:
Timestamp:
01/25/10 21:33:52 (3 years ago)
Author:
pablo
Message:
Location:
trunk/fl5
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/fl5/src/com/longtailvideo/jwplayer/events/MediaEvent.as

    r662 r806  
    187187                public override function toString():String { 
    188188                        var retString:String = '[MediaEvent type="' + type + '"'; 
     189                        var defaults:MediaEvent = new MediaEvent(""); 
    189190 
    190191                        if (this.type == MediaEvent.JWPLAYER_MEDIA_META) { 
     
    193194                                } 
    194195                        } else { 
    195                                 retString += ' bufferPercent="' + bufferPercent + '"'; 
    196                                 retString += ' duration="' + duration + '"'; 
    197                                 retString += ' position="' + position + '"'; 
    198                                 retString += ' offset="' + offset + '"'; 
    199                                 retString += ' volume="' + volume + '"'; 
    200                                 retString += ' mute="' + mute + '"'; 
    201                                 retString += ' message="' + message + '"'; 
     196                                if (bufferPercent != defaults.bufferPercent) retString += ' bufferPercent="' + bufferPercent + '"'; 
     197                                if (duration != defaults.duration) retString += ' duration="' + duration + '"'; 
     198                                if (position != defaults.position) retString += ' position="' + position + '"'; 
     199                                if (offset != defaults.offset) retString += ' offset="' + offset + '"'; 
     200                                if (volume != defaults.volume) retString += ' volume="' + volume + '"'; 
     201                                if (mute != defaults.mute) retString += ' mute="' + mute + '"'; 
     202                                if (message != defaults.message) retString += ' message="' + message + '"'; 
    202203                        } 
    203204                         
  • trunk/fl5/src/com/longtailvideo/jwplayer/media/HTTPMediaProvider.as

    r776 r806  
    183183 
    184184                /** Get metadata information from netstream class. **/ 
    185                 public function onData(dat:Object):void { 
     185                public function onClientData(dat:Object):void { 
    186186                        if (dat.width) { 
    187187                                _video.width = dat.width; 
  • trunk/fl5/src/com/longtailvideo/jwplayer/media/MediaProvider.as

    r796 r806  
    297297                 * **/ 
    298298                protected function getConfigProperty(property:String):* { 
    299                         return _config.pluginConfig(provider)[property]; 
     299                        if (item.hasOwnProperty(_provider + "." + property)) { 
     300                                return item[_provider + "." + property]; 
     301                        } else { 
     302                                return _config.pluginConfig(provider)[property]; 
     303                        } 
    300304                } 
    301305                 
     
    316320                        if (m) { 
    317321                                _media = new MovieClip(); 
    318                                 _media.visible = false; 
     322                                //_media.visible = false; 
    319323                                _media.addChild(m); 
    320324                                if (_width * _height > 0) { 
  • trunk/fl5/src/com/longtailvideo/jwplayer/media/RTMPMediaProvider.as

    r796 r806  
    77 **/ 
    88package com.longtailvideo.jwplayer.media { 
    9         import com.jeroenwijering.events.*; 
    10         import com.longtailvideo.jwplayer.events.MediaEvent; 
    11         import com.longtailvideo.jwplayer.model.PlayerConfig; 
    12         import com.longtailvideo.jwplayer.model.PlaylistItem; 
    13         import com.longtailvideo.jwplayer.player.PlayerState; 
    14         import com.longtailvideo.jwplayer.utils.NetClient; 
    15         import com.longtailvideo.jwplayer.utils.TEA; 
    16          
    17         import flash.events.*; 
    18         import flash.media.*; 
    19         import flash.net.*; 
    20         import flash.utils.*; 
    21          
    22         public class RTMPMediaProvider extends MediaProvider { 
    23                 /** Video object to be instantiated. **/ 
    24                 protected var _video:Video; 
    25                 /** NetConnection object for setup of the video stream. **/ 
    26                 protected var _connection:NetConnection; 
    27                 /** Loader instance that loads the XML file. **/ 
    28                 private var _loader:URLLoader; 
    29                 /** NetStream instance that handles the stream IO. **/ 
    30                 protected var _stream:NetStream; 
    31                 /** Sound control object. **/ 
    32                 protected var _transformer:SoundTransform; 
    33                 /** Save the location of the XML redirect. **/ 
    34                 private var _smil:String; 
    35                 /** ID for the position positionInterval. **/ 
    36                 protected var _positionInterval:Number; 
    37                 /** Save that a file is unpublished. **/ 
    38                 protected var _unpublished:Boolean; 
    39                 /** Whether the buffer has filled **/ 
    40                 private var _bufferFull:Boolean; 
    41                 /** Save that the video has been started. **/ 
    42                 protected var _streamStarted:Boolean; 
    43                 /** Whether the stream is active **/ 
    44                 private var _streamActive:Boolean; 
    45                  
     9    import com.longtailvideo.jwplayer.events.MediaEvent; 
     10    import com.longtailvideo.jwplayer.events.PlayerEvent; 
     11    import com.longtailvideo.jwplayer.model.PlayerConfig; 
     12    import com.longtailvideo.jwplayer.model.PlaylistItem; 
     13    import com.longtailvideo.jwplayer.model.PlaylistItemLevel; 
     14    import com.longtailvideo.jwplayer.player.PlayerState; 
     15    import com.longtailvideo.jwplayer.utils.AssetLoader; 
     16    import com.longtailvideo.jwplayer.utils.Configger; 
     17    import com.longtailvideo.jwplayer.utils.Logger; 
     18    import com.longtailvideo.jwplayer.utils.NetClient; 
     19    import com.longtailvideo.jwplayer.utils.TEA; 
     20     
     21    import flash.events.*; 
     22    import flash.media.*; 
     23    import flash.net.*; 
     24    import flash.utils.*; 
     25 
     26    /** 
     27     * Wrapper for playback of video streamed over RTMP. Can playback MP4, FLV, MP3, AAC and live streams. 
     28     * Server-specific features are: 
     29     * - The SecureToken functionality of Wowza (with the 'token' flahvar). 
     30     * - Load balancing with SMIL files (with the 'rtmp.loadbalance=true' flashvar). 
     31     **/ 
     32    public class RTMPMediaProvider extends MediaProvider { 
     33        /** Save if the bandwidth checkin already occurs. **/ 
     34        private var _bandwidthChecked:Boolean; 
     35        /** Interval for bw checking - with dynamic streaming. **/ 
     36        private var _bandwidthInterval:Number; 
     37        /** NetConnection object for setup of the video stream. **/ 
     38        private var _connection:NetConnection; 
     39        /** Is dynamic streaming possible. **/ 
     40        private var _dynamic:Boolean; 
     41                /** The currently playing RTMP stream. **/ 
     42                private var _currentFile:String; 
     43                /** The currently active RTMP stream. **/ 
     44                private var _currentStream:String; 
     45        /** ID for the position interval. **/ 
     46        private var _positionInterval:Number; 
     47        /** Loader instance that loads the XML file. **/ 
     48        private var _xmlLoader:AssetLoader; 
     49        /** NetStream instance that handles the stream IO. **/ 
     50        private var _stream:NetStream; 
     51        /** Interval ID for subscription pings. **/ 
     52        private var _subscribeInterval:Number; 
     53        /** Offset in seconds of the last seek. **/ 
     54        private var _timeoffset:Number = -1; 
     55        /** Sound control object. **/ 
     56        private var _transformer:SoundTransform; 
     57        /** Save that a stream is streaming. **/ 
     58        private var _isStreaming:Boolean; 
     59        /** Level to which we're transitioning. **/ 
     60        private var _transitionLevel:Number = -1; 
     61        /** Video object to be instantiated. **/ 
     62        private var _video:Video; 
     63                /** Whether or not the buffer is full **/ 
     64                private var _bufferFull:Boolean = false; 
     65 
    4666                public function RTMPMediaProvider() { 
    4767                        super('rtmp'); 
    4868                } 
    49  
    50  
     69                 
     70                 
    5171                /** Constructor; sets up the connection and display. **/ 
    5272                public override function initializeMediaProvider(cfg:PlayerConfig):void { 
    5373                        super.initializeMediaProvider(cfg); 
    54                         _connection = new NetConnection(); 
    55                         _connection.addEventListener(NetStatusEvent.NET_STATUS, statusHandler); 
    56                         _connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler); 
    57                         _connection.addEventListener(IOErrorEvent.IO_ERROR, errorHandler); 
    58                         _connection.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler); 
    59                         _connection.objectEncoding = ObjectEncoding.AMF0; 
    60                         _connection.client = new NetClient(this); 
    61                         _loader = new URLLoader(); 
    62                         _loader.addEventListener(Event.COMPLETE, loaderHandler); 
    63                         _loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler); 
    64                         _loader.addEventListener(IOErrorEvent.IO_ERROR, errorHandler); 
    65                         _video = new Video(320, 240); 
    66                         _video.smoothing = config.smoothing; 
    67                         _transformer = new SoundTransform(); 
     74            _connection = new NetConnection(); 
     75            _connection.addEventListener(NetStatusEvent.NET_STATUS, statusHandler); 
     76            _connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler); 
     77            _connection.addEventListener(IOErrorEvent.IO_ERROR, errorHandler); 
     78            _connection.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler); 
     79            _connection.objectEncoding = ObjectEncoding.AMF0; 
     80            _connection.client = new NetClient(this); 
     81            _xmlLoader = new AssetLoader(); 
     82            _xmlLoader.addEventListener(Event.COMPLETE, loaderHandler); 
     83            _xmlLoader.addEventListener(ErrorEvent.ERROR, errorHandler); 
     84            _transformer = new SoundTransform(); 
     85            _video = new Video(320, 240); 
     86            _video.smoothing = config.smoothing; 
     87        } 
     88 
     89        /** Check if the player can use dynamic streaming (server versions and no load balancing). **/ 
     90        private function checkDynamic(str:String):void { 
     91            var clt:Number = Number((new PlayerEvent('')).client.split(' ')[1].split(',')[0]); 
     92            var mjr:Number = Number(str.split(',')[0]); 
     93            var mnr:Number = Number(str.split(',')[1]); 
     94            if (!(getConfigProperty('loadbalance') && clt > 9 && (mjr > 3 || (mjr == 3 && mnr > 4)))) { 
     95                _dynamic = true; 
     96            } else { 
     97                _dynamic = false; 
     98            } 
     99        } 
     100 
     101        /** Try subscribing to livestream **/ 
     102        private function doSubscribe(id:String):void { 
     103            _connection.call("FCSubscribe", null, id); 
     104        } 
     105 
     106        /** Catch security errors. **/ 
     107        private function errorHandler(evt:ErrorEvent):void { 
     108            stop(); 
     109                        sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_ERROR, {message: evt.text}); 
    68110                } 
    69111 
    70  
    71                 /** Catch security errors. **/ 
    72                 protected function errorHandler(evt:ErrorEvent):void { 
    73                         error(evt.text); 
    74                 } 
    75  
    76  
    77                 /** Extract the correct rtmp syntax from the file string. **/ 
    78                 protected function getID(url:String):String { 
    79                         var ext:String = url.substr(-4); 
    80                         if (ext == '.mp3') { 
    81                                 return 'mp3:' + url.substr(0, url.length - 4); 
    82                         } else if (ext == '.mp4' || ext == '.mov' || ext == '.aac' || ext == '.m4a' || ext == '.f4v' || ext == '.m4v') { 
    83                                 return 'mp4:' + url; 
    84                         } else if (ext == '.flv') { 
    85                                 return url.substr(0, url.length - 4); 
    86                         } else { 
    87                                 return url; 
    88                         } 
    89                 } 
    90  
    91  
    92                 /** Load content. **/ 
    93                 override public function load(itm:PlaylistItem):void { 
    94                         _item = itm; 
    95                         _position = 0; 
     112        /** Bandwidth checking for dynamic streaming. **/ 
     113        private function getBandwidth():void { 
     114            try { 
     115                var bdw:Number = Math.round(_stream.info.maxBytesPerSecond * 8 / 1024); 
     116            } catch (err:Error) { 
     117                clearInterval(_bandwidthInterval); 
     118                return; 
     119            } 
     120            if (bdw < 100 || bdw > 99999) { 
     121                return; 
     122            } else { 
     123                bdw = Math.round(config.bandwidth / 2 + bdw / 2); 
     124            } 
     125            config.bandwidth = bdw; 
     126            Configger.saveCookie('bandwidth', bdw); 
     127            if (item.levels.length > 0 && item.getLevel(config.bandwidth, config.width) != item.currentLevel) { 
     128                                item.setLevel(item.getLevel(config.bandwidth, config.width)); 
     129                swap(item.currentLevel); 
     130            } 
     131        } 
     132 
     133        /** Extract the correct rtmp syntax from the file string. **/ 
     134        private function getID(url:String):String { 
     135            var ext:String = url.substr(-4); 
     136            if (url.indexOf(':') > -1) { 
     137                return url; 
     138            } else if (ext == '.mp3') { 
     139                return 'mp3:' + url.substr(0, url.length - 4); 
     140            } else if (ext == '.mp4' || ext == '.mov' || ext == '.m4v' || ext == '.aac' || ext == '.m4a' || ext == '.f4v') { 
     141                return 'mp4:' + url; 
     142            } else if (ext == '.flv') { 
     143                return url.substr(0, url.length - 4); 
     144            } else { 
     145                return url; 
     146            } 
     147        } 
     148 
     149        /** Load content. **/ 
     150        override public function load(itm:PlaylistItem):void { 
     151            _item = itm; 
     152            _position = 0; 
    96153                        _bufferFull = false; 
    97                         _streamStarted = false; 
    98                         _streamActive = false; 
     154            if (item.levels.length > 0) { 
     155                loadLevelSync(); 
     156            } 
     157            _timeoffset = item.start; 
     158            clearInterval(_positionInterval); 
    99159                        setState(PlayerState.BUFFERING); 
    100160                        sendBufferEvent(0); 
    101                         if (getConfigProperty('loadbalance') as Boolean == true) { 
    102                                 _smil = item.file; 
    103                                 _loader.load(new URLRequest(_smil)); 
    104                         } else { 
     161            if (getConfigProperty('loadbalance')) { 
     162                                if (!item.hasOwnProperty('smil')) { item.smil = []; } 
     163                                item.smilIndex = item.levels.length > 0 ? item.currentLevel : 0;  
     164                item.smil[item.smilIndex] = item.file; 
     165                _xmlLoader.load(item.file, XML); 
     166            } else { 
    105167                                finishLoad(); 
    106                         } 
    107                 } 
    108  
    109  
    110                 /** Get the streamer / file from the loadbalancing XML. **/ 
    111                 private function loaderHandler(evt:Event):void { 
    112                         var xml:XML = XML(evt.currentTarget.data); 
    113                         item.streamer = xml.children()[0].children()[0].@base.toString(); 
    114                         item.file = xml.children()[1].children()[0].@src.toString(); 
    115                         finishLoad(); 
    116                 } 
    117  
     168            } 
     169        } 
    118170 
    119171                /** Finalizes the loading process **/ 
     
    122174                        if (ext == '.mp3'){ 
    123175                                media = null; 
    124                         } else if (!media) { 
     176                        } else { 
    125177                                media = _video; 
    126178                        } 
    127                         _connection.connect(item.streamer); 
    128                         config.mute == true ? setVolume(0) : setVolume(config.volume); 
    129                         sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_LOADED); 
     179                        if (item.streamer != _currentStream || !_isStreaming) { 
     180                                _currentStream = item.streamer; 
     181                                sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_LOADED); 
     182                                _connection.connect(item.streamer); 
     183                        } else { 
     184                                seek(_timeoffset); 
     185                        } 
    130186                } 
    131  
    132  
    133                 /** Get metadata information from netstream class. **/ 
    134                 public function onData(dat:Object):void { 
    135                         if (dat.width) { 
     187                 
     188        /** Make sure the selected level is actually the item.file. **/ 
     189        private function loadLevelSync():void { 
     190            for (var i:Number = 0; i < item.levels.length; i++) { 
     191                if (item.file == (item.levels[i] as PlaylistItemLevel).file) { 
     192                    item.setLevel(i); 
     193                    break; 
     194                } 
     195            } 
     196        } 
     197 
     198        /** Get the streamer / file from the loadbalancing XML. **/ 
     199        private function loaderHandler(evt:Event):void { 
     200            var xml:XML = XML((evt.target as AssetLoader).loadedObject); 
     201            item.streamer = xml.head.meta.@base.toString(); 
     202                        var fileLocation:String = xml.body.video.@src.toString(); 
     203                        if (item.levels.length > 0) { 
     204                                (item.levels[item.smilIndex] as PlaylistItemLevel).file = fileLocation; 
     205                        } else { 
     206                item.file = fileLocation; 
     207                        } 
     208                        finishLoad(); 
     209        } 
     210 
     211        /** Get metadata information from netstream class. **/ 
     212        public function onClientData(dat:Object):void { 
     213            if (dat.type == 'fcsubscribe') { 
     214                if (dat.code == "NetStream.Play.StreamNotFound") { 
     215                                        sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_ERROR,{message: "Subscription failed: " + item.file});  
     216                } else if (dat.code == "NetStream.Play.Start") { 
     217                    setStream(); 
     218                } 
     219                clearInterval(_subscribeInterval); 
     220            } 
     221            if (dat.width) { 
    136222                                _video.width = dat.width; 
    137223                                _video.height = dat.height; 
    138224                                resize(_width, _height); 
    139                         } 
    140                         if (dat.duration && item.duration <= 0) { 
    141                                 item.duration = dat.duration; 
    142                         } 
    143                         if (dat.type == 'complete') { 
     225            } 
     226            if (dat.duration && item.duration <= 0) { 
     227                item.duration = dat.duration; 
     228            } 
     229            if (dat.type == 'complete') { 
     230                clearInterval(_positionInterval); 
    144231                                complete(); 
    145                         } else if (dat.type == 'close') { 
     232            } 
     233            if (dat.type == 'close') { 
     234                stop(); 
     235            } 
     236            if (dat.type == 'bandwidth') { 
     237                config.bandwidth = dat.bandwidth; 
     238                Configger.saveCookie('bandwidth', dat.bandwidth); 
     239                setStream(); 
     240            } 
     241            if (dat.code == 'NetStream.Play.TransitionComplete'|| (dat.code == 'NetStream.Play.Transition' && dat.reason == 'NetStream.Transition.Success')) { 
     242                                if (_transitionLevel >= 0) { 
     243                                        Logger.log("Transition to level " + item.currentLevel + "complete"); 
     244                        _transitionLevel = -1; 
     245                                } 
     246            } 
     247                        sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_META, {metadata: dat}); 
     248        } 
     249 
     250        /** Pause playback. **/ 
     251        override public function pause():void { 
     252                        if (isLivestream()) { 
    146253                                stop(); 
    147                         } 
    148                         if (config.ignoremeta != true) { 
    149                                 sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_META, {metadata: dat}); 
    150                         } 
    151                 } 
    152  
    153                  
    154                 /** Determines if the stream is a live stream **/ 
    155                 private function get livestream():Boolean { 
    156                         // We assume it's a livestream until we hear otherwise. 
    157                         return !(item.duration > 0); 
    158                 } 
    159  
    160                 /** Pause playback. **/ 
    161                 override public function pause():void { 
    162                         _streamActive = false; 
    163                         _stream.pause(); 
     254                                return; 
     255                        } 
     256                         
    164257                        clearInterval(_positionInterval); 
    165                         _positionInterval = undefined; 
    166                         super.pause(); 
    167                         if (livestream) { 
    168                                 stop(); 
    169                         } 
    170                 } 
    171  
    172  
    173                 /** Resume playing. **/ 
    174                 override public function play():void { 
    175                         /*  
    176                         * Livestreams will reset their buffer if _stream.resume is called, 
    177                         * so we suppress them after the intial call 
    178                         */ 
    179                         if (!livestream && !_streamActive) { 
    180                                 _streamActive = true; 
    181                                 _stream.resume(); 
    182                         } 
    183                         if (!_streamStarted) { 
    184                                 _streamStarted = true; 
    185                                 if (!livestream) { 
    186                                         seek(item.start); 
     258                        setState(PlayerState.PAUSED); 
     259            if (_stream) {  
     260                                Logger.log("NetStream.pause()"); 
     261                                _stream.pause();  
     262                        } 
     263        } 
     264 
     265        /** Resume playing. **/ 
     266        override public function play():void { 
     267            if (_stream) { 
     268                                Logger.log("NetStream.resume()"); 
     269                                _stream.resume();                                
     270                        } 
     271                        clearInterval(_positionInterval); 
     272            _positionInterval = setInterval(positionInterval, 100); 
     273                        setState(PlayerState.PLAYING); 
     274        } 
     275 
     276        /** Interval for the position progress. **/ 
     277        private function positionInterval():void { 
     278            var pos:Number = Math.round((_stream.time) * 10) / 10; 
     279                        var bfr:Number = _stream.bufferLength / _stream.bufferTime; 
     280 
     281                        if (bfr < 0.25 && pos < item.duration - 5 && state != PlayerState.BUFFERING) { 
     282                                _bufferFull = false; 
     283                                setState(PlayerState.BUFFERING); 
     284            } else if (bfr > 1 && state != PlayerState.PLAYING) { 
     285                                if (state == PlayerState.BUFFERING && !isLivestream()) { 
     286                                        _bufferFull = true; 
     287                                        sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_BUFFER_FULL, {bufferPercent: bfr}); 
    187288                                } 
    188                         } 
    189                          
    190                         if (!_positionInterval) { 
    191                                 _positionInterval = setInterval(positionInterval, 100); 
    192                         } 
    193                         super.play(); 
    194                 } 
    195  
    196  
    197                 /** Interval for the position progress. **/ 
    198                 protected function positionInterval():void { 
    199                         _position = Math.round(_stream.time * 10) / 10; 
    200  
    201                         var bfr:Number; 
    202                         if (!livestream) { 
    203                                 var bufferTime:Number = _stream.bufferTime < (item.duration - position) ? _stream.bufferTime : (item.duration - position); 
    204                                 bfr = Math.round(_stream.bufferLength / bufferTime * 100); 
    205                         } else if (_stream.bufferLength > 0) { 
    206                                 bfr = Math.round(_stream.bufferLength / _stream.bufferTime * 100); 
    207                         } else if (_streamActive){ 
    208                                 bfr = 100; 
    209                         } 
    210                          
    211                          
    212                         if (bfr < 95 && position < Math.abs(item.duration - _stream.bufferTime - 1)) { 
    213                                 if (state == PlayerState.PLAYING && bfr < 20) { 
    214                                         _bufferFull = false; 
    215                                         _streamActive = false; 
    216                                         _stream.pause(); 
    217                                         setState(PlayerState.BUFFERING); 
    218                                         _stream.bufferTime = config.bufferlength; 
    219                                         sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_META, {metadata: {bufferlength: config.bufferlength}}); 
     289            } 
     290            if (state != PlayerState.PLAYING) { 
     291                return; 
     292            } 
     293            if (pos < item.duration) { 
     294                                _position = pos; 
     295                                sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_TIME, {position: position, duration: item.duration}); 
     296            } else if (position > 0 && item.duration > 0) { 
     297                                Logger.log("NetStream.pause()"); 
     298                _stream.pause(); 
     299                clearInterval(_positionInterval); 
     300                                complete(); 
     301            } 
     302        } 
     303 
     304        /** Check if the level must be switched on resize. **/ 
     305        override public function resize(width:Number, height:Number):void { 
     306            super.resize(width, height); 
     307                        if (state == PlayerState.PLAYING) { 
     308                if (item.levels.length > 0 && item.currentLevel != item.getLevel(config.bandwidth, config.width)) { 
     309                                        item.setLevel(item.getLevel(config.bandwidth, config.width)); 
     310                        if (_dynamic) { 
     311                            swap(item.currentLevel); 
     312                        } else { 
     313                            seek(position); 
     314                        } 
    220315                                } 
    221                         } else if (bfr > 95 && state == PlayerState.BUFFERING) { 
    222                                 //_stream.bufferTime = config.bufferlength * 4; 
    223                                 //sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_META, {metadata: {bufferlength: config.bufferlength * 4}}); 
    224                                 if (!_bufferFull){ 
    225                                         _bufferFull = true; 
    226                                         sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_BUFFER_FULL); 
    227                                 } 
    228                         } 
    229  
    230                         if (state == PlayerState.BUFFERING || state == PlayerState.PAUSED) { 
    231                                 //TODO: This works, but it looks weird, as the bufferTime is changing 
    232                                 /* 
    233                                 if (!_bufferingComplete){ 
    234                                         sendBufferEvent(_stream.bufferLength / _stream.bufferTime * item.duration); 
    235                                 } 
    236                                 */ 
    237                         } else if (position < item.duration) { 
    238                                 if (state == PlayerState.PLAYING && position >= 0) { 
    239                                         //TODO: This works, but it looks weird, as the bufferTime is changing 
    240                                         //sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_TIME, {position: position, duration: item.duration, bufferLength: _stream.bufferLength / _stream.bufferTime * item.duration}); 
    241                                         sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_TIME, {position: position, duration: item.duration}); 
    242                                 } 
    243                         } else if (!isNaN(position) && item.duration > 0) { 
    244                                 complete(); 
    245                         } 
    246                 } 
    247  
    248  
    249                 /** Seek to a new position. **/ 
    250                 override public function seek(pos:Number):void { 
    251                         _position = pos; 
    252                         clearInterval(_positionInterval); 
    253                         _positionInterval = undefined; 
    254                         _stream.seek(position); 
    255                         if (!_positionInterval) { 
    256                                 _positionInterval = setInterval(positionInterval, 100); 
    257                         } 
    258                 } 
    259  
    260  
    261                 /** Start the netstream object. **/ 
    262                 protected function setStream():void { 
     316            } 
     317        } 
     318 
     319        /** Seek to a new position. **/ 
     320        override public function seek(pos:Number):void { 
     321            _timeoffset = pos; 
     322            _transitionLevel = -1; 
     323            clearInterval(_positionInterval); 
     324            clearInterval(_bandwidthInterval); 
     325                        if (item.levels.length > 0 && item.getLevel(config.bandwidth, config.width) != item.currentLevel) { 
     326                item.setLevel(item.getLevel(config.bandwidth, config.width)); 
     327                if (getConfigProperty('loadbalance')) { 
     328                    item.start = pos; 
     329                    load(item); 
     330                    return; 
     331                } 
     332            } 
     333                        if (state != PlayerState.PLAYING) { 
     334                                play(); 
     335                        } 
     336            if (getConfigProperty('subscribe')) { 
     337                                Logger.log("NetStream.play(" + getID(item.file) + ")"); 
     338                _stream.play(getID(item.file)); 
     339            } else { 
     340                if (_currentFile != item.file) { 
     341                    _currentFile = item.file; 
     342                                        Logger.log("NetStream.play(" + getID(item.file) + ")"); 
     343                                        try { 
     344                        _stream.play(getID(item.file)); 
     345                                        } catch(e:Error) {} 
     346                } 
     347                if (_timeoffset >= 0 || state == PlayerState.IDLE) { 
     348                    if (_stream) { 
     349                                                Logger.log("NetStream.seek(" + _timeoffset + ")"); 
     350                                                _stream.seek(_timeoffset); 
     351                                        } 
     352                } 
     353                if (_dynamic) { 
     354                    _bandwidthInterval = setInterval(getBandwidth, 2000); 
     355                } 
     356            } 
     357            _isStreaming = true; 
     358            _positionInterval = setInterval(positionInterval, 100); 
     359        } 
     360 
     361        /** Start the netstream object. **/ 
     362        private function setStream():void { 
    263363                        _stream = new NetStream(_connection); 
    264364                        _stream.checkPolicyFile = true; 
     
    269369                        _stream.client = new NetClient(this); 
    270370                        _video.attachNetStream(_stream); 
    271                         if (!_positionInterval) { 
    272                                 _positionInterval = setInterval(positionInterval, 100); 
    273                         } 
    274                         _stream.play(getID(item.file)); 
    275                 } 
    276  
    277  
    278                 /** Receive NetStream status updates.  
    279                  *  
    280                  * For more info see http://help.adobe.com/en_US/Flex/4.0/langref/flash/events/NetStatusEvent.html#info 
    281                  **/ 
    282                 protected function statusHandler(evt:NetStatusEvent):void { 
    283                         switch (evt.info.code) { 
    284                                 case 'NetConnection.Connect.Success': 
    285                                         if (evt.info.secureToken != undefined) { 
    286                                                 _connection.call("secureTokenResponse", null, TEA.decrypt(evt.info.secureToken, config.token)); 
    287                                         } 
    288                                         setStream(); 
    289                                         var res:Responder = new Responder(streamlengthHandler); 
    290                                         _connection.call("getStreamLength", res, getID(item.file)); 
    291                                         _connection.call("checkBandwidth", null); 
    292                                         break; 
    293                                 case 'NetStream.Play.Start': 
    294                                         break; 
    295                                 case 'NetStream.Seek.Notify': 
    296                                         clearInterval(_positionInterval); 
    297                                         _positionInterval = undefined; 
    298                                         if (!_positionInterval) { 
    299                                                 _positionInterval = setInterval(positionInterval, 100); 
     371                        config.mute == true ? setVolume(0) : setVolume(config.volume); 
     372                        seek(_timeoffset); 
     373        } 
     374 
     375        /** Receive NetStream status updates. **/ 
     376        private function statusHandler(evt:NetStatusEvent):void { 
     377            switch (evt.info.code) { 
     378                case 'NetConnection.Connect.Success': 
     379                    if (evt.info.secureToken != undefined) { 
     380                        _connection.call("secureTokenResponse", null, TEA.decrypt(evt.info.secureToken, 
     381                                                                                 config.token)); 
     382                    } 
     383                    if (evt.info.data) { 
     384                        checkDynamic(evt.info.data.version); 
     385                    } 
     386                    if (getConfigProperty('subscribe')) { 
     387                        _subscribeInterval = setInterval(doSubscribe, 1000, getID(item.file)); 
     388                        return; 
     389                    } else { 
     390                        if (item.levels.length > 0) { 
     391                            if (_dynamic || _bandwidthInterval) { 
     392                                setStream(); 
     393                            } else { 
     394                                                                _bandwidthChecked = true; 
     395                                _connection.call('checkBandwidth', null); 
     396                            } 
     397                        } else { 
     398                            setStream(); 
     399                        } 
     400                        if (item.file.substr(-4) == '.mp3' || item.file.substr(0,4) == 'mp3:') { 
     401                            _connection.call("getStreamLength", new Responder(streamlengthHandler), getID(item.file)); 
     402                        } 
     403                    } 
     404                    break; 
     405                case 'NetStream.Seek.Notify': 
     406                    clearInterval(_positionInterval); 
     407                                        _positionInterval = setInterval(positionInterval, 100); 
     408                    break; 
     409                case 'NetConnection.Connect.Rejected': 
     410                    try { 
     411                        if (evt.info.ex.code == 302) { 
     412                            item.streamer = evt.info.ex.redirect; 
     413                            setTimeout(load, 100, item); 
     414                            return; 
     415                        } 
     416                    } catch (err:Error) { 
     417                        stop(); 
     418                        var msg:String = evt.info.code; 
     419                        if (evt.info['description']) { 
     420                            msg = evt.info['description']; 
     421                        } 
     422                        stop(); 
     423                                                sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_ERROR, {message: msg});  
     424                    } 
     425                    break; 
     426                                case 'NetStream.Failed': 
     427                case 'NetStream.Play.StreamNotFound': 
     428                    if (!_isStreaming) { 
     429                        onClientData({type: 'complete'}); 
     430                    } else { 
     431                        stop(); 
     432                                                sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_ERROR, {message: "Stream not found: " + item.file});  
     433                    } 
     434                    break; 
     435                                case 'NetStream.Seek.Failed': 
     436                                        if (!_isStreaming) { 
     437                                                onClientData({type: 'complete'}); 
     438                                        } else { 
     439                                                stop(); 
     440                                                sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_ERROR, {message: "Could not seek: " + item.file});  
    300441                                        } 
    301442                                        break; 
    302                                 case 'NetConnection.Connect.Rejected': 
    303                                         try { 
    304                                                 if (evt.info.ex.code == 302) { 
    305                                                         item.streamer = evt.info.ex.redirect; 
    306                                                         setTimeout(load, 100, item); 
    307                                                         return; 
    308                                                 } 
    309                                         } catch (err:Error) { 
    310                                                 var msg:String = evt.info.code; 
    311                                                 if (evt.info['description']) { 
    312                                                         msg = evt.info['description']; 
    313                                                 } 
    314                                                 error(msg); 
    315                                         } 
    316                                         break; 
    317                                 case 'NetStream.Failed': 
    318                                 case 'NetStream.Play.StreamNotFound': 
    319                                         if (_unpublished) { 
    320                                                 onData({type: 'complete'}); 
    321                                                 _unpublished = false; 
    322                                         } else { 
    323                                                 error("Stream not found: " + item.file); 
    324                                         } 
    325                                         break; 
    326                                 case 'NetConnection.Connect.Failed': 
    327                                         error("Server not found: " + item.streamer); 
    328                                         break; 
    329                                 case 'NetStream.Play.UnpublishNotify': 
    330                                         _unpublished = true; 
    331                                         break; 
     443                case 'NetConnection.Connect.Failed': 
     444                    stop(); 
     445                                        sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_ERROR, {message: "Server not found: " + item.streamer});  
     446                    break; 
     447                case 'NetStream.Play.UnpublishNotify': 
     448                    stop(); 
     449                    break; 
    332450                                case 'NetStream.Buffer.Full': 
    333451                                        if (!_bufferFull) { 
     
    336454                                        } 
    337455                                        break; 
    338                                 case 'NetStream.Play.Reset': 
     456                                case 'NetStream.Play.Transition': 
     457                                        onClientData(evt.info); 
    339458                                        break; 
    340                         } 
     459            } 
    341460                        sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_META, {metadata: evt.info}); 
     461        } 
     462 
     463        /** Destroy the stream. **/ 
     464        override public function stop():void { 
     465            if (_stream && _stream.time) { 
     466                                Logger.log("NetStream.close()"); 
     467                                _stream.close(); 
     468            } 
     469            _isStreaming = false; 
     470            _currentFile = undefined; 
     471            _connection.close(); 
     472            clearInterval(_positionInterval); 
     473            clearInterval(_bandwidthInterval); 
     474            _position = 0; 
     475            _timeoffset = item.start; 
     476                        super.stop(); 
     477                        if (item.hasOwnProperty('smil')) { 
     478                                /** Replace file values with original redirects **/ 
     479                                if (item.levels.length > 0) { 
     480                                        for (var i:Number = 0; i < item.levels.length; i++) { 
     481                                                if (i < item.smil.length && item.smil[i]) { 
     482                                                        (item.levels[i] as PlaylistItemLevel).file = item.smil[i]; 
     483                                                } 
     484                                        } 
     485                                } else { 
     486                                        item.file = item.smil[0]; 
     487                                } 
     488                        } 
    342489                } 
    343490 
    344  
    345                 /** Destroy the _stream. **/ 
    346                 override public function stop():void { 
    347                         _streamStarted = false; 
    348                         _streamActive = false; 
    349                         if (_stream && _stream.time) { 
    350                                 _stream.close(); 
    351                         } 
    352                         _connection.close(); 
    353                         clearInterval(_positionInterval); 
    354                         _positionInterval = undefined; 
    355                         super.stop(); 
    356                         if (_smil) { 
    357                                 item.file = _smil; 
    358                         } 
     491        /** Get the streamlength returned from the connection. **/ 
     492        private function streamlengthHandler(len:Number):void { 
     493                        Logger.log("duration: " + len); 
     494            if (len && item.duration <= 0) { 
     495                item.duration = len; 
     496            } 
     497        } 
     498 
     499        /** Dynamically switch streams **/ 
     500        private function swap(newLevel:Number):void { 
     501            if (_transitionLevel == newLevel) { 
     502                Logger.log('Already tranisitioning to level ' + item.currentLevel + ' ; transition ignored'); 
     503            } else { 
     504                _transitionLevel = newLevel; 
     505                Logger.log('transition to level ' + item.currentLevel + ' initiated'); 
     506                var nso:NetStreamPlayOptions = new NetStreamPlayOptions(); 
     507                nso.streamName = getID(item.file); 
     508                nso.transition = NetStreamPlayTransitions.SWITCH; 
     509                                Logger.log("NetStream.play2(" + nso + ")"); 
     510                _stream.play2(nso); 
     511            } 
     512        } 
     513 
     514        /** Set the volume level. **/ 
     515        override public function setVolume(vol:Number):void { 
     516            _transformer.volume = vol / 100; 
     517                         
     518            if (_stream) { 
     519                _stream.soundTransform = _transformer; 
     520            } 
     521        } 
     522                 
     523                /** Completes video playback **/ 
     524                override protected function complete():void { 
     525                        stop(); 
     526                        sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_COMPLETE); 
     527                        setState(PlayerState.IDLE); 
    359528                } 
    360  
    361  
    362                 /** Get the streamlength returned from the _connection. **/ 
    363                 private function streamlengthHandler(len:Number):void { 
    364                         if (len > 0) { 
    365                                 onData({type: 'streamlength', duration: len}); 
    366                         } 
     529                 
     530                /** Determines if the stream is a live stream **/ 
     531                private function isLivestream():Boolean { 
     532                        // We assume it's a livestream until we hear otherwise. 
     533                        return (!(item.duration > 0) && _stream && _stream.bufferLength > 0); 
    367534                } 
    368  
    369  
    370                 /** Set the volume level. **/ 
    371                 override public function setVolume(vol:Number):void { 
    372                         _transformer.volume = vol / 100; 
    373                         if (_stream) { 
    374                                 try { 
    375                                         _stream.soundTransform = _transformer; 
    376                                         super.setVolume(vol); 
    377                                 } catch (err:Error) { 
    378  
    379                                 } 
    380                         } 
    381                 } 
    382         } 
     535                 
     536                 
     537    } 
    383538} 
  • trunk/fl5/src/com/longtailvideo/jwplayer/media/VideoMediaProvider.as

    r805 r806  
    105105 
    106106                /** Get metadata information from netstream class. **/ 
    107                 public function onData(dat:Object):void { 
     107                public function onClientData(dat:Object):void { 
    108108                        if (dat.width) { 
    109109                                _video.width = dat.width; 
  • trunk/fl5/src/com/longtailvideo/jwplayer/player/PlayerVersion.as

    r805 r806  
    33         
    44        public class PlayerVersion { 
    5                 protected static var _version:String = "5.1.805"; 
     5                protected static var _version:String = "5.1.806"; 
    66                 
    77                public static function get version():String { 
  • trunk/fl5/src/com/longtailvideo/jwplayer/utils/NetClient.as

    r772 r806  
    2222                                out[i] = dat[i]; 
    2323                        } 
    24                         callback.onData(out); 
     24                        callback.onClientData(out); 
    2525                } 
    2626                 
Note: See TracChangeset for help on using the changeset viewer.