9628b848 by David LaPalomento

Add "parser" support for more m3u8 tags

Regexes and tests for m3u8 tags that are likely to be relevant to playback. High-level m3u8 tests are still failing because their is still no "interpretation" of the incoming parse stream.
1 parent 98b95881
1 (function(parseInt, undefined) { 1 (function(parseInt, undefined) {
2 var Stream, Tokenizer, Parser; 2 var
3 parseAttributes = function(attributes) {
4 var
5 attrs = attributes.split(','),
6 i = attrs.length,
7 result = {},
8 attr;
9 while (i--) {
10 attr = attrs[i].split('=');
11 result[attr[0]] = attr[1];
12 }
13 return result;
14 },
15 Stream,
16 Tokenizer,
17 Parser;
3 18
4 Stream = function() { 19 Stream = function() {
5 var listeners = {}; 20 var listeners = {};
...@@ -107,6 +122,122 @@ ...@@ -107,6 +122,122 @@
107 this.trigger('data', event); 122 this.trigger('data', event);
108 return; 123 return;
109 } 124 }
125 match = (/^#EXT-X-TARGETDURATION:?([0-9.]*)?/).exec(line);
126 if (match) {
127 event = {
128 type: 'tag',
129 tagType: 'targetduration'
130 };
131 if (match[1]) {
132 event.duration = parseInt(match[1], 10);
133 }
134 this.trigger('data', event);
135 return;
136 }
137 match = (/^#EXT-X-VERSION:?([0-9.]*)?/).exec(line);
138 if (match) {
139 event = {
140 type: 'tag',
141 tagType: 'version'
142 };
143 if (match[1]) {
144 event.version = parseInt(match[1], 10);
145 }
146 this.trigger('data', event);
147 return;
148 }
149 match = (/^#EXT-X-MEDIA-SEQUENCE:?([0-9.]*)?/).exec(line);
150 if (match) {
151 event = {
152 type: 'tag',
153 tagType: 'media-sequence'
154 };
155 if (match[1]) {
156 event.number = parseInt(match[1], 10);
157 }
158 this.trigger('data', event);
159 return;
160 }
161 match = (/^#EXT-X-PLAYLIST-TYPE:?(.*)?$/).exec(line);
162 if (match) {
163 event = {
164 type: 'tag',
165 tagType: 'playlist-type'
166 };
167 if (match[1]) {
168 event.playlistType = match[1];
169 }
170 this.trigger('data', event);
171 return;
172 }
173 match = (/^#EXT-X-BYTERANGE:?([0-9.]*)?@?([0-9.]*)?/).exec(line);
174 if (match) {
175 event = {
176 type: 'tag',
177 tagType: 'byterange'
178 };
179 if (match[1]) {
180 event.length = parseInt(match[1], 10);
181 }
182 if (match[2]) {
183 event.offset = parseInt(match[2], 10);
184 }
185 this.trigger('data', event);
186 return;
187 }
188 match = (/^#EXT-X-ALLOW-CACHE:?(YES|NO)?/).exec(line);
189 if (match) {
190 event = {
191 type: 'tag',
192 tagType: 'allow-cache'
193 };
194 if (match[1]) {
195 event.allowed = !(/NO/).test(match[1]);
196 }
197 this.trigger('data', event);
198 return;
199 }
200 match = (/^#EXT-X-STREAM-INF:?(.*)$/).exec(line);
201 if (match) {
202 event = {
203 type: 'tag',
204 tagType: 'stream-inf'
205 };
206 if (match[1]) {
207 event.attributes = parseAttributes(match[1]);
208
209 if (event.attributes.RESOLUTION) {
210 (function() {
211 var
212 split = event.attributes.RESOLUTION.split('x'),
213 resolution = {};
214 if (split[0]) {
215 resolution.width = parseInt(split[0], 10);
216 }
217 if (split[1]) {
218 resolution.height = parseInt(split[1], 10);
219 }
220 event.attributes.RESOLUTION = resolution;
221 })();
222 }
223 if (event.attributes.BANDWIDTH) {
224 event.attributes.BANDWIDTH = parseInt(event.attributes.BANDWIDTH, 10);
225 }
226 if (event.attributes['PROGRAM-ID']) {
227 event.attributes['PROGRAM-ID'] = parseInt(event.attributes['PROGRAM-ID'], 10);
228 }
229 }
230 this.trigger('data', event);
231 return;
232 }
233 match = (/^#EXT-X-ENDLIST/).exec(line);
234 if (match) {
235 this.trigger('data', {
236 type: 'tag',
237 tagType: 'endlist'
238 });
239 return;
240 }
110 241
111 // unknown tag type 242 // unknown tag type
112 this.trigger('data', { 243 this.trigger('data', {
......