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

Revision 1248, 5.3 KB checked in by jeroen, 3 years ago (diff)

implemented framedrop detection / switching, for both RTMP and HTTP. Updated qualitymonitor plugin to display framedrops

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                public var provider:String              = "";
19               
20                protected var _file:String                      = "";
21                protected var _streamer:String          = "";
22                protected var _duration:Number          = -1;
23                protected var _start:Number                     = 0;
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'] && (level['bitrate'] || level['width'])) {
35                                                        addLevel(
36                                                                new PlaylistItemLevel(level['file'],
37                                                                        Number(level['bitrate']),
38                                                                        Number(level['width']),
39                                                                        level['streamer']));
40                                                }
41                                        }
42                                } else {
43                                        this[itm] = obj[itm];
44                                }
45                        }
46                }
47
48                /** File property is now a getter, to take levels into account **/
49                public function get file():String {
50                        if (_levels.length > 0 && _currentLevel > -1 && _currentLevel < _levels.length) {
51                                var level:PlaylistItemLevel = _levels[_currentLevel] as PlaylistItemLevel;
52                                return level.file ? level.file : _file;
53                        } else {
54                                return _file;
55                        }
56                }
57               
58                /** File setter.  Note, if levels are defined, this will be ignored. **/
59                public function set file(f:String):void {
60                        _file = f;
61                }
62               
63                /** Streamer property is now a getter, to take levels into account **/
64                public function get streamer():String {
65                        if (_levels.length > 0 && _currentLevel > -1 && _currentLevel < _levels.length) {
66                                var level:PlaylistItemLevel = _levels[_currentLevel] as PlaylistItemLevel;
67                                return level.streamer ? level.streamer : _streamer;
68                        } else {
69                                return _streamer;
70                        }
71                }
72               
73                /** Streamer setter.  Note, if levels are defined, this will be ignored. **/
74                public function set streamer(s:String):void {
75                        _streamer = s;
76                }
77               
78                /** The quality levels associated with this playlist item **/
79                public function get levels():Array {
80                        return _levels;
81                }
82               
83                /** Insert an additional bitrate level, keeping the array sorted from highest to lowest. **/
84                public function addLevel(newLevel:PlaylistItemLevel):void {
85                        if (validExtension(newLevel.file)) {
86
87                                if (_currentLevel < 0) _currentLevel = 0;
88                                for (var i:Number = 0; i < _levels.length; i++) {
89                                        var level:PlaylistItemLevel = _levels[i] as PlaylistItemLevel;
90                                        if (newLevel.bitrate > level.bitrate) {
91                                                _levels.splice(i, 0, newLevel);
92                                                return;
93                                        } else if (newLevel.bitrate == level.bitrate && newLevel.width > level.width) {
94                                                _levels.splice(i, 0, newLevel);
95                                                return;
96                                        }
97                                }
98                                _levels.push(newLevel);
99                        }
100                }
101
102
103                /** Blacklist a level from usage (e.g. if it cannot be played or drops too many frames). **/
104                public function blacklistLevel(level:Number):void {
105                        if(levels[level]) {
106                                levels[level].blacklisted = true;
107                        }
108                };
109
110                /**
111                 * Determines whether this file extension can be played in the Flash player.  If not, ignore the level.
112                 * This is useful for unified HTML5 / Flash failover setups.
113                 **/
114                protected function validExtension(filename:String):Boolean {
115                        var foo:String = Strings.extension(filename);
116                        switch(Strings.extension(filename)) {
117                                case "ogv":
118                                case "ogg":
119                                case "webm":
120                                        return false;
121                                default:
122                                        return true;
123                        }
124                }
125
126                public function get currentLevel():Number {
127                        return _currentLevel;
128                }
129               
130                public function getLevel(bitrate:Number, width:Number):Number {
131                        for (var i:Number=0; i < _levels.length; i++) {
132                                var level:PlaylistItemLevel = _levels[i] as PlaylistItemLevel;
133                                if (bitrate >= level.bitrate * 1.2 && width >= level.width * 0.8 && !level.blacklisted) {
134                                        return i;
135                                }
136                        }
137                        return _levels.length - 1;
138                }
139               
140                /** Set this PlaylistItem's level to match the given bitrate and height. **/
141                public function setLevel(newLevel:Number):void {
142                        if (newLevel >= 0 && newLevel < _levels.length) {
143                                _currentLevel = newLevel;
144                        } else {
145                                throw(new Error("Level index out of bounds"));
146                        }
147                }
148               
149                public function toString():String {
150                        return "[PlaylistItem" +
151                                (this.file ? " file=" + this.file : "") +
152                                (this.streamer ? " streamer=" + this.streamer : "") +
153                                (this.provider ? " provider=" + this.provider : "") +
154                                (this.levels.length ? " level=" + this.currentLevel.toString() : "") +
155                                "]";
156                       
157                }
158               
159               
160                public function get start():Number { return _start; }
161                public function set start(s:*):void { _start = Strings.seconds(String(s)); }
162
163                public function get duration():Number { return _duration; }
164                public function set duration(d:*):void {
165                        _duration = Strings.seconds(String(d));
166//                      if (_duration == 0) { _duration = -1; }
167                }
168               
169                // For backwards compatibility
170                public function get type():String { return provider; }
171                public function set type(t:String):void { provider = t; }
172               
173        }
174}
Note: See TracBrowser for help on using the repository browser.