Changeset 1506


Ignore:
Timestamp:
12/19/10 12:37:20 (2 years ago)
Author:
jeroen
Message:

modified provider to already play a level

Location:
providers/adaptive
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • providers/adaptive/src/com/longtailvideo/jwplayer/media/AdaptiveProvider.as

    r1504 r1506  
    22 
    33 
    4         import com.longtailvideo.jwplayer.events.MediaEvent; 
    5         import com.longtailvideo.jwplayer.media.MediaProvider; 
    6         import com.longtailvideo.jwplayer.model.PlayerConfig; 
    7         import com.longtailvideo.jwplayer.model.PlaylistItem; 
    8         import com.longtailvideo.jwplayer.player.PlayerState; 
    9         import com.longtailvideo.jwplayer.muxing.*; 
    10         import com.longtailvideo.jwplayer.parsing.*; 
    11         import com.longtailvideo.jwplayer.utils.*; 
    12  
    13         import flash.events.*; 
    14         import flash.media.*; 
    15         import flash.net.*; 
    16         import flash.system.*; 
    17         import flash.utils.*; 
    18  
    19  
    20         /** JW Player provider for playback of adaptive streams. **/ 
    21         public class AdaptiveProvider extends MediaProvider { 
    22  
    23  
    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 _transformer:SoundTransform; 
    32                 /** ID for the position interval. **/ 
    33                 private var _positionInterval:Number; 
    34                 /** Whether the buffer has filled **/ 
    35                 private var _bufferFull:Boolean; 
    36                 /** Save the buffer percentage. **/ 
    37                 private var _bufferPercent:Number; 
    38                 /** URLStream that loads the file. **/ 
    39                 private var _urlStream:URLStream; 
    40                 /** URLRequest for loading the stream. **/ 
    41                 private var _urlRequest:URLRequest; 
    42                 /** Reference to the ts. **/ 
    43                 private var _ts:TS; 
    44                 /** Reference to the M3U8 manifest. **/ 
    45                 private var _manifest:Manifest; 
    46  
    47  
    48                 /** Constructor; sets up the connection and display. **/ 
    49                 public function AdaptiveProvider() { 
    50                         super('adaptive'); 
    51                 } 
    52  
    53  
    54                 public override function initializeMediaProvider(cfg:PlayerConfig):void { 
    55                         super.initializeMediaProvider(cfg); 
    56                         _connection = new NetConnection(); 
    57                         _connection.connect(null); 
    58                         _stream = new NetStream(_connection); 
    59                         _stream.addEventListener(IOErrorEvent.IO_ERROR, errorHandler); 
    60                         _stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler); 
    61                         _stream.bufferTime = config.bufferlength; 
    62                         _stream.client = new Object(); 
    63                         _transformer = new SoundTransform(); 
    64                         _urlStream = new URLStream(); 
    65                         _urlStream.addEventListener(Event.COMPLETE, fileLoaded); 
    66                         _video = new Video(320,240); 
    67                         _video.smoothing = config.smoothing; 
    68                         _video.attachNetStream(_stream); 
    69                 } 
    70  
    71  
    72                 /** Catch security errors. **/ 
    73                 protected function errorHandler(evt:ErrorEvent):void { 
    74                         Logger.log(evt.text,provider); 
    75                         error(evt.text); 
    76                 } 
    77  
    78  
    79                 /** Load content. **/ 
    80                 override public function load(itm:PlaylistItem):void { 
    81                         media = _video; 
    82                         _bufferFull = false; 
    83                         _item = itm; 
    84                         super.load(itm); 
    85                         setState(PlayerState.BUFFERING); 
    86                         sendBufferEvent(0); 
    87                         streamVolume(config.mute ? 0 : config.volume); 
    88                         clearInterval(_positionInterval); 
    89                         _positionInterval = setInterval(positionHandler, 200); 
    90                         resize(_width, _height); 
    91                         _manifest = new Manifest(); 
    92                         _manifest.addEventListener(Event.COMPLETE,manifestHandler); 
    93                         _manifest.addEventListener(ErrorEvent.ERROR,errorHandler); 
    94                         _manifest.load(_item.file); 
    95                 }; 
    96  
    97  
    98                 /** Manifest loaded. **/ 
    99                 private function manifestHandler(event:Event):void { 
    100                         _stream.play(null); 
    101                         Logger.log("I'd now like to stream "+_manifest.levels[0].chunks[0].url); 
    102                         _urlStream.load(new URLRequest(_manifest.levels[0].chunks[0].url)); 
    103                 }; 
    104  
    105  
    106                 private function fileLoaded(e:Event):void { 
    107                         var input:ByteArray = new ByteArray(); 
    108                         _urlStream.readBytes(input); 
    109                         _stream.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN); 
    110                         if(item.file.substr(-3) != 'flv') {  
    111                                 _ts = new TS(input); 
    112                                 _stream.appendBytes(_ts.data); 
    113                         } else { 
    114                                 _stream.appendBytes(input); 
    115                         } 
    116                         _bufferPercent = 100; 
    117                         sendBufferEvent(100, 0, {}); 
    118                         _bufferFull = true; 
    119                         sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_BUFFER_FULL); 
    120                 }; 
    121  
    122  
    123                 /** Pause playback. **/ 
    124                 override public function pause():void { 
    125                         _stream.pause(); 
    126                         super.pause(); 
    127                 }; 
    128  
    129  
    130                 /** Resume playing. **/ 
    131                 override public function play():void { 
    132                         if (!_positionInterval) { 
    133                                 _positionInterval = setInterval(positionHandler, 100); 
    134                         } 
    135                         if (_bufferFull) { 
    136                                 _stream.resume(); 
    137                                 super.play(); 
    138                         } else { 
    139                                 setState(PlayerState.BUFFERING); 
    140                         } 
    141                 }; 
    142  
    143  
    144                 /** Interval for the position progress **/ 
    145                 protected function positionHandler():void { 
    146                         var pos:Number = Math.round(_stream.time * 10) / 10; 
    147                         if (state == PlayerState.PLAYING && pos > 0) { 
    148                                 _position = pos; 
    149                                 sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_TIME, {position: position, duration: item.duration}); 
    150                                 if (item.duration > 0 && _position >= item.duration - 0.2) { 
    151                                         stop(); 
    152                                         sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_COMPLETE); 
    153                                 } 
    154                         } 
    155                 }; 
    156  
    157  
    158                 /** Seek to a new position. **/ 
    159                 override public function seek(pos:Number):void { 
    160                         /* Small files; seeking not very useful */ 
    161                 }; 
    162  
    163  
    164                 /** Destroy the video. **/ 
    165                 override public function stop():void { 
    166                         _stream.seek(0); 
    167                         _stream.pause(); 
    168                         _bufferFull = false; 
    169                         _bufferPercent = 0; 
    170                         clearInterval(_positionInterval); 
    171                         super.stop(); 
    172                 }; 
    173  
    174  
    175                 /** Set the volume level. **/ 
    176                 override public function setVolume(vol:Number):void { 
    177                         streamVolume(vol); 
    178                         super.setVolume(vol); 
    179                         var fr:FileReference = new FileReference( ); 
    180                         fr.save(_ts.data,'export.flv'); 
    181                 }; 
    182  
    183  
    184                 /** Set the stream's volume, without sending a volume event **/ 
    185                 protected function streamVolume(level:Number):void { 
    186                         _transformer.volume = level / 100; 
    187                         if (_stream) { 
    188                                 _stream.soundTransform = _transformer; 
    189                         } 
    190                 }; 
    191  
    192  
    193         } 
     4    import com.longtailvideo.jwplayer.events.MediaEvent; 
     5    import com.longtailvideo.jwplayer.media.MediaProvider; 
     6    import com.longtailvideo.jwplayer.model.PlayerConfig; 
     7    import com.longtailvideo.jwplayer.model.PlaylistItem; 
     8    import com.longtailvideo.jwplayer.player.PlayerState; 
     9    import com.longtailvideo.jwplayer.muxing.*; 
     10    import com.longtailvideo.jwplayer.parsing.*; 
     11    import com.longtailvideo.jwplayer.utils.*; 
     12 
     13    import flash.events.*; 
     14    import flash.media.*; 
     15    import flash.net.*; 
     16    import flash.system.*; 
     17    import flash.utils.*; 
     18 
     19 
     20    /** JW Player provider for playback of adaptive streams. **/ 
     21    public class AdaptiveProvider extends MediaProvider { 
     22 
     23 
     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 _transformer:SoundTransform; 
     32        /** ID for the position interval. **/ 
     33        private var _positionInterval:Number; 
     34        /** Whether the buffer has filled **/ 
     35        private var _bufferFull:Boolean; 
     36        /** Save the buffer percentage. **/ 
     37        private var _bufferPercent:Number; 
     38        /** URLStream that loads the file. **/ 
     39        private var _urlStream:URLStream; 
     40        /** URLRequest for loading the stream. **/ 
     41        private var _urlRequest:URLRequest; 
     42        /** Reference to the ts. **/ 
     43        private var _ts:TS; 
     44        /** Reference to the M3U8 manifest. **/ 
     45        private var _manifest:Manifest; 
     46        /** Fragment that was last loaded. **/ 
     47        private var _chunk:Number; 
     48        /** Are we currently loading. **/ 
     49        private var _loading:Boolean; 
     50        /** Currently active bitrate level. **/ 
     51        private var _level:Number; 
     52        /** Appendbytes action. **/ 
     53        private var _action:String; 
     54        /** Seeking offset. **/ 
     55        private var _offset:Number = 0; 
     56 
     57 
     58        /** Constructor; sets up the connection and display. **/ 
     59        public function AdaptiveProvider() { 
     60            super('adaptive'); 
     61        } 
     62 
     63 
     64        public override function initializeMediaProvider(cfg:PlayerConfig):void { 
     65            super.initializeMediaProvider(cfg); 
     66            _connection = new NetConnection(); 
     67            _connection.connect(null); 
     68            _stream = new NetStream(_connection); 
     69            _stream.addEventListener(IOErrorEvent.IO_ERROR, errorHandler); 
     70            _stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler); 
     71            _stream.bufferTime = config.bufferlength; 
     72            _stream.client = new Object(); 
     73            _transformer = new SoundTransform(); 
     74            _urlStream = new URLStream(); 
     75            _urlStream.addEventListener(Event.COMPLETE, fileLoaded); 
     76            _video = new Video(320,240); 
     77            _video.smoothing = config.smoothing; 
     78            _video.attachNetStream(_stream); 
     79        } 
     80 
     81 
     82        /** Catch security errors. **/ 
     83        protected function errorHandler(evt:ErrorEvent):void { 
     84            error(evt.text); 
     85        } 
     86 
     87 
     88        /** Load content. **/ 
     89        override public function load(itm:PlaylistItem):void { 
     90            media = _video; 
     91            _bufferFull = false; 
     92            _item = itm; 
     93            super.load(itm); 
     94            setState(PlayerState.BUFFERING); 
     95            sendBufferEvent(0); 
     96            streamVolume(config.mute ? 0 : config.volume); 
     97            clearInterval(_positionInterval); 
     98            _positionInterval = setInterval(positionHandler, 200); 
     99            _manifest = new Manifest(); 
     100            _manifest.addEventListener(Event.COMPLETE,manifestHandler); 
     101            _manifest.addEventListener(ErrorEvent.ERROR,errorHandler); 
     102            _manifest.load(_item.file); 
     103            _loading = true; 
     104        }; 
     105 
     106 
     107        /** Manifest loaded. **/ 
     108        private function manifestHandler(event:Event):void { 
     109            _item.duration = _manifest.levels[0].duration; 
     110            _video.width = _manifest.levels[0].width; 
     111            _video.height = _manifest.levels[0].height; 
     112            _level = _manifest.levels.length - 1; 
     113            resize(_width, _height); 
     114            _stream.play(null); 
     115            _chunk = 0; 
     116            _action = 'begin'; 
     117            _urlStream.load(new URLRequest(_manifest.levels[_level].chunks[_chunk].url)); 
     118        }; 
     119 
     120 
     121        private function fileLoaded(e:Event):void { 
     122            var input:ByteArray = new ByteArray(); 
     123            _urlStream.readBytes(input); 
     124            if(_action == 'begin' || _action == 'seek') { 
     125                _ts = new TS(input,true); 
     126                _action = 'none'; 
     127            } else {  
     128                _ts = new TS(input); 
     129            } 
     130            _stream.appendBytes(_ts.data); 
     131            _loading = false; 
     132        }; 
     133 
     134 
     135        /** Pause playback. **/ 
     136        override public function pause():void { 
     137            _stream.pause(); 
     138            super.pause(); 
     139        }; 
     140 
     141 
     142        /** Resume playing. **/ 
     143        override public function play():void { 
     144            if (!_positionInterval) { 
     145                _positionInterval = setInterval(positionHandler, 100); 
     146            } 
     147            if (_bufferFull) { 
     148                _stream.resume(); 
     149                super.play(); 
     150            } else { 
     151                setState(PlayerState.BUFFERING); 
     152            } 
     153        }; 
     154 
     155 
     156        /** Interval for the position progress **/ 
     157        protected function positionHandler():void { 
     158            var bfr:Number = _stream.bufferLength; 
     159            if(bfr < 10) { 
     160                if(bfr < 1 && _bufferFull) { 
     161                    _bufferFull = false; 
     162                    setState(PlayerState.BUFFERING); 
     163                } else if(bfr > 3 && !_bufferFull) { 
     164                    _bufferFull = true; 
     165                    setState(PlayerState.PLAYING); 
     166                    sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_BUFFER_FULL); 
     167                } 
     168                if(!_loading) { 
     169                    _loading = true; 
     170                    _chunk++; 
     171                    _urlStream.load(new URLRequest(_manifest.levels[_level].chunks[_chunk].url)); 
     172                } 
     173            } 
     174            var pos:Number = Math.round(_stream.time * 100 + _offset * 100) / 100; 
     175            if (state == PlayerState.PLAYING && pos > 0) { 
     176                _position = pos; 
     177                sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_TIME, {position: position, duration: item.duration}); 
     178                if (item.duration > 0 && _position >= item.duration - 0.2) { 
     179                    stop(); 
     180                    sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_COMPLETE); 
     181                } 
     182            } 
     183        }; 
     184 
     185 
     186        /** Seek to a new position. **/ 
     187        override public function seek(pos:Number):void { 
     188            if(_loading) {  
     189                _urlStream.close(); 
     190            } 
     191            _offset = pos; 
     192            _stream.seek(0); 
     193            _stream.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN); 
     194            _loading = true; 
     195            _action = 'seek'; 
     196            _chunk = _manifest.levels[_level].indexOf(pos); 
     197            _urlStream.load(new URLRequest(_manifest.levels[_level].chunks[_chunk].url)); 
     198        }; 
     199 
     200 
     201        /** Destroy the video. **/ 
     202        override public function stop():void { 
     203            _stream.seek(0); 
     204            _stream.pause(); 
     205            _bufferFull = false; 
     206            _bufferPercent = 0; 
     207            clearInterval(_positionInterval); 
     208            super.stop(); 
     209        }; 
     210 
     211 
     212        /** Set the volume level. **/ 
     213        override public function setVolume(vol:Number):void { 
     214            streamVolume(vol); 
     215            super.setVolume(vol); 
     216        }; 
     217 
     218 
     219        /** Set the stream's volume, without sending a volume event **/ 
     220        protected function streamVolume(level:Number):void { 
     221            _transformer.volume = level / 100; 
     222            if (_stream) { 
     223                _stream.soundTransform = _transformer; 
     224            } 
     225        }; 
     226 
     227 
     228    } 
    194229} 
  • providers/adaptive/src/com/longtailvideo/jwplayer/muxing/FLV.as

    r1484 r1506  
    1313                /** List of FLV tags. **/ 
    1414                private var _tags:Array; 
     15                /** Is this the first video? **/ 
     16                private var _first:Boolean; 
    1517 
    1618 
    1719                /** Transmux the M2TS file into an FLV file. **/ 
    18                 public function FLV() { 
     20                public function FLV(first:Boolean=false) { 
    1921                        _tags = new Array(); 
     22                        _first = first; 
    2023                }; 
    2124 
     
    2427                public function get data():ByteArray { 
    2528                        var flv:ByteArray = new ByteArray(); 
    26                         _writeHeader(flv); 
     29                        if(_first) {  
     30                            _writeHeader(flv); 
     31                    } 
    2732                        // Sort the tags by timestamp; private data first. 
    2833                        _tags.sortOn( 
     
    3035                                [Array.NUMERIC, Array.NUMERIC | Array.DESCENDING] 
    3136                        ); 
    32                         var stt:Number = _tags[0].timestamp; 
     37                        //var stt:Number = _tags[0].timestamp; 
    3338                        // Append all tags 
    3439                        var pos:Number = flv.position; 
    3540                        for(var i:Number=0; i<_tags.length; i++) { 
    3641                                // Set the timestamps zero-indexed. 
    37                                 _tags[i].timestamp -= stt; 
     42                                //_tags[i].timestamp -= stt; 
    3843                                // The Tag itself. 
    39                                 flv.writeBytes(_tags[i].data); 
    40                                 // The PreviousTagSize 
    41                                 flv.writeUnsignedInt(flv.position - pos); 
    42                                 pos = flv.position; 
     44                                //if(_first || !_tags[i].isPrivate) { 
     45                                    flv.writeBytes(_tags[i].data); 
     46                                    flv.writeUnsignedInt(flv.position - pos); 
     47                                    pos = flv.position; 
     48                            //} 
    4349                        } 
    4450                        // Add an end-of-sequence tag. 
    45                         _writeEOSTag(flv); 
     51                        // _writeEOSTag(flv); 
     52                        Logger.log("timestamps from " + _tags[0].timestamp + " to " +_tags[_tags.length-1].timestamp); 
    4653                        return flv; 
    4754                }; 
     
    8289                        flv.writeByte(0x01); 
    8390                        // Audio + Video tags. 
    84                         flv.writeByte(0x04); 
     91                        flv.writeByte(0x05); 
    8592                        // Length of the header. 
    8693                        flv.writeUnsignedInt(0x00000009); 
  • providers/adaptive/src/com/longtailvideo/jwplayer/muxing/TS.as

    r1484 r1506  
    3838 
    3939                /** Transmux the M2TS file into an FLV file. **/ 
    40                 public function TS(dat:ByteArray) { 
    41                         _flv = new FLV(); 
     40                public function TS(dat:ByteArray,fst:Boolean=false) { 
     41                        _flv = new FLV(fst); 
    4242                        while(dat.bytesAvailable) { 
    4343                                _readPacket(dat); 
  • providers/adaptive/src/com/longtailvideo/jwplayer/parsing/Level.as

    r1504 r1506  
    2020 
    2121        /** Create the bitrate level. **/ 
    22         public function Level(bitrate:Number, height:Number, width:Number):void { 
     22        public function Level(bitrate:Number=95, height:Number=180, width:Number=320):void { 
    2323            this.bitrate = bitrate; 
    2424            this.height = height; 
  • providers/adaptive/src/com/longtailvideo/jwplayer/parsing/Manifest.as

    r1504 r1506  
    8787            var i:Number = 0; 
    8888            while (i<lines.length) { 
    89                 Logger.log(lines[i],'manifest'); 
    9089                if(lines[i].indexOf(TAG_LEVEL) == 0) { 
    9190                    _readLevel(lines,i); 
     
    106105        /** Parse a manifest for levels. **/ 
    107106        private function _readLevel(lines:Array,index:Number):void { 
    108             var bitrate:Number; 
    109             var height:Number; 
    110             var width:Number; 
     107            var level:Level = new Level(); 
    111108            var params:Array = lines[index].substr(TAG_LEVEL.length).split(','); 
    112109            for(var j:Number = 0; j<params.length; j++) {  
    113110                if(params[j].indexOf(PARAM_BANDWIDTH) == 0) { 
    114                     bitrate = params[j].split('=')[1]; 
     111                    level.bitrate = params[j].split('=')[1]; 
    115112                } else if (params[j].indexOf(PARAM_RESOLUTION) == 0) { 
    116                     height = params[j].split('=')[1].split('x')[1]; 
    117                     width = params[j].split('=')[1].split('x')[0]; 
     113                    level.height = params[j].split('=')[1].split('x')[1]; 
     114                    level.width = params[j].split('=')[1].split('x')[0]; 
    118115                } 
    119116            } 
    120             var level:Level = new Level(bitrate,height,width); 
    121117            levels.push(level); 
    122118            var playlist:Playlist = new Playlist(level); 
     
    124120            playlist.addEventListener(Event.COMPLETE, _levelHandler); 
    125121            var url:String = _gluePaths(lines[index+1],_url); 
    126             Logger.log(url); 
    127122            playlist.load(url); 
    128123            _toLoad++; 
  • providers/adaptive/src/com/longtailvideo/jwplayer/parsing/Playlist.as

    r1504 r1506  
    7373            while (i<lines.length) { 
    7474                if(lines[i].indexOf(TAG_CHUNK) == 0) { 
    75                     var duration:Number = lines[i].substr(8,lines[i].indexOf(',')-7) as Number; 
     75                    var duration:Number = Number(lines[i].substr(8,lines[i].indexOf(',') - 8)); 
    7676                    i++; 
    7777                    var url:String = _gluePaths(lines[i],_url); 
    78                     Logger.log(url); 
    7978                    _level.push(new Chunk(duration,url)); 
    8079                } 
  • providers/adaptive/test/assets/settings.js

    r1504 r1506  
    1717        examples: { 
    1818                '':{}, 
     19                'Codeshop': { 
     20                        provider: '../adaptive.swf', 
     21                        file: 'http://h264.code-shop.com/demo/smooth_streaming/content/iphone.ssm/iphone.m3u8' 
     22                }, 
    1923                'Bipbop': { 
    2024                        duration: 10, 
     
    2630                        provider:'../adaptive.swf', 
    2731                        file: 'assets/bopbip.ts' 
    28                 }, 
    29                 'Codeshop': { 
    30                         duration: 4, 
    31                         provider: '../adaptive.swf', 
    32                         file: 'assets/codeshop.ts' 
    3332                }, 
    3433                'Stevenote': { 
Note: See TracChangeset for help on using the changeset viewer.