source: trunk/fl5/src/com/longtailvideo/jwplayer/model/PlaylistItem.as @ 1990

Revision 1990, 6.0 KB checked in by jeroen, 21 months ago (diff)

three small changes to prevent downswitching b/c of unreliable maxBW stats - #1455

Line 
1package com.longtailvideo.jwplayer.model {
2        import com.longtailvideo.jwplayer.utils.Strings;
3
4        /**
5         * Playlist item data.  The class is dynamic; any items parsed from the jwplayer XML namespace are added to the item.
6         * 
7         * @author Pablo Schklowsky
8         */
9        public dynamic class PlaylistItem {
10                public var author:String                = "";
11                public var date:String                  = "";
12                public var description:String   = "";
13                public var image:String                 = "";
14                public var link:String                  = "";
15                public var mediaid:String               = "";
16                public var tags:String                  = "";
17                public var title:String                 = "";
18               
19                protected var _duration:Number          = -1;
20                protected var _file:String                      = "";
21                protected var _provider:String          = "";
22                protected var _start:Number                     = 0;
23                protected var _streamer:String          = "";
24               
25                protected var _currentLevel:Number      = -1;
26                protected var _levels:Array                     = [];
27               
28               
29                public function PlaylistItem(obj:Object = null) {
30                        for (var itm:String in obj) {
31                                if (itm == "levels" && obj[itm] is Array) {
32                                        var levels:Array = obj[itm] as Array;
33                                        for each (var level:Object in levels) {
34                                                if (level['file']) {
35                                                        var newLevel:PlaylistItemLevel = new PlaylistItemLevel(level['file'],
36                                                                Number(level['bitrate']),
37                                                                Number(level['width']),
38                                                                level['streamer']);
39                                                        for (var otherProp:String in level) {
40                                                                switch(otherProp) {
41                                                                        case "file":
42                                                                        case "bitrate":
43                                                                        case "width":
44                                                                        case "streamer":
45                                                                                break;
46                                                                        default:
47                                                                                newLevel[otherProp] = level[otherProp];
48                                                                                break;
49                                                                }
50                                                        }
51                                                        addLevel(newLevel);
52                                                }
53                                        }
54                                } else {
55                                        this[itm] = obj[itm];
56                                }
57                        }
58                }
59               
60
61                /** File property is now a getter, to take levels into account **/
62                public function get file():String {
63                        if (_levels.length > 0 && _currentLevel > -1 && _currentLevel < _levels.length) {
64                                var level:PlaylistItemLevel = _levels[_currentLevel] as PlaylistItemLevel;
65                                return level.file ? level.file : _file;
66                        } else {
67                                return _file;
68                        }
69                }
70               
71                /** File setter.  Note, if levels are defined, this will be ignored. **/
72                public function set file(f:String):void {
73                        _file = f;
74                }
75               
76                /** Streamer property is now a getter, to take levels into account **/
77                public function get streamer():String {
78                        if (_levels.length > 0 && _currentLevel > -1 && _currentLevel < _levels.length) {
79                                var level:PlaylistItemLevel = _levels[_currentLevel] as PlaylistItemLevel;
80                                return level.streamer ? level.streamer : _streamer;
81                        } else {
82                                return _streamer;
83                        }
84                }
85               
86                /** Streamer setter.  Note, if levels are defined, this will be ignored. **/
87                public function set streamer(s:String):void {
88                        _streamer = s;
89                }
90               
91                /** The quality levels associated with this playlist item **/
92                public function get levels():Array {
93                        return _levels;
94                }
95               
96                /** Insert an additional bitrate level, keeping the array sorted from highest to lowest. **/
97                public function addLevel(newLevel:PlaylistItemLevel):void {
98                        if (validExtension(newLevel.file)) {
99                                if (_currentLevel < 0) _currentLevel = 0;
100                                for (var i:Number = 0; i < _levels.length; i++) {
101                                        var level:PlaylistItemLevel = _levels[i] as PlaylistItemLevel;
102                                        if (newLevel.bitrate > level.bitrate) {
103                                                _levels.splice(i, 0, newLevel);
104                                                return;
105                                        } else if ( (isNaN(newLevel.bitrate) || newLevel.bitrate == level.bitrate) && newLevel.width > level.width) {
106                                                _levels.splice(i, 0, newLevel);
107                                                return;
108                                        }
109                                }
110                                _levels.push(newLevel);
111                        }
112                }
113
114
115        /** Levels need to be cleared e.g. for reloading a multibitrate SMIL. **/
116        public function clearLevels():void {
117            _levels = new Array();
118        };
119
120
121                /** Blacklist a level from usage (e.g. if it cannot be played or drops too many frames). **/
122                public function blacklistLevel(level:Number,state:Boolean=true):void {
123                        if(levels[level]) {
124                                levels[level].blacklisted = state;
125                        }
126                };
127
128
129                /**
130                 * Determines whether this file extension can be played in the Flash player.  If not, ignore the level.
131                 * This is useful for unified HTML5 / Flash failover setups.
132                 **/
133                protected function validExtension(filename:String):Boolean {
134                        switch(Strings.extension(filename)) {
135                                case "ogv":
136                                case "ogg":
137                                case "webm":
138                                        return false;
139                                default:
140                                        return true;
141                        }
142                }
143
144                public function get currentLevel():Number {
145                        return _currentLevel;
146                }
147               
148                public function getLevel(bitrate:Number, width:Number):Number {
149                        for (var i:Number=0; i < _levels.length; i++) {
150                                var level:PlaylistItemLevel = _levels[i] as PlaylistItemLevel;
151                                if ((isNaN(level.bitrate) || bitrate >= level.bitrate * 1.5) && (isNaN(level.width) || width >= level.width * 0.67) && !level.blacklisted) {
152                                        return i;
153                                }
154                        }
155                        return _levels.length - 1;
156                }
157               
158                /** Set this PlaylistItem's level to match the given bitrate and height. **/
159                public function setLevel(newLevel:Number):void {
160                        if (newLevel >= 0 && newLevel < _levels.length) {
161                                _currentLevel = newLevel;
162                        } else {
163                                throw(new Error("Level index out of bounds"));
164                        }
165                }
166               
167                public function toString():String {
168                        return "[PlaylistItem" +
169                                (this.file ? " file=" + this.file : "") +
170                                (this.streamer ? " streamer=" + this.streamer : "") +
171                                (this.provider ? " provider=" + this.provider : "") +
172                                (this.levels.length ? " level=" + this.currentLevel.toString() : "") +
173                                "]";
174                       
175                }
176               
177               
178                public function get start():Number { return _start; }
179                public function set start(s:*):void {
180                        _start = Strings.seconds(String(s));
181                        if (_start > _duration && _duration > 0) {
182                                _duration += _start;
183                        }
184                }
185
186                public function get duration():Number { return _duration; }
187                public function set duration(d:*):void {
188                        _duration = Strings.seconds(String(d));
189                        if (_start > _duration && _duration > 0) {
190                                _duration += _start;
191                        }
192                }
193
194                public function get provider():String { return _provider; }
195                public function set provider(p:*):void {
196                        _provider = (p == "audio") ? "sound" : p;
197                }
198               
199                // For backwards compatibility
200                public function get type():String { return _provider; }
201                public function set type(t:String):void { provider = t; }
202               
203        }
204}
Note: See TracBrowser for help on using the repository browser.