41e190ce by David LaPalomento

Consolidate PTS scanning

Loop through flv tags while intra-segment seeking in one pass. Rely on the SWF to track the seek destination in currentTime instead of manually pushing it through ExternalInterface.
1 parent 19317e79
...@@ -154,20 +154,6 @@ var ...@@ -154,20 +154,6 @@ var
154 return 1; // HAVE_METADATA 154 return 1; // HAVE_METADATA
155 }; 155 };
156 156
157 player.hls.getPtsByTime = function(segmentParser, time) {
158 var index = 0;
159
160 for (index; index<segmentParser.getTags().length; index++) {
161 if(index === segmentParser.getTags().length-1) {
162 return segmentParser.getTags()[index].pts;
163 } else {
164 if (segmentParser.getTags()[index].pts <= time && segmentParser.getTags()[index+1].pts > time) {
165 return segmentParser.getTags()[index].pts;
166 }
167 }
168 }
169 };
170
171 player.on('seeking', function() { 157 player.on('seeking', function() {
172 var currentTime = player.currentTime(); 158 var currentTime = player.currentTime();
173 player.hls.mediaIndex = getMediaIndexByTime(player.hls.media, currentTime); 159 player.hls.mediaIndex = getMediaIndexByTime(player.hls.media, currentTime);
...@@ -177,18 +163,6 @@ var ...@@ -177,18 +163,6 @@ var
177 fillBuffer(currentTime * 1000); 163 fillBuffer(currentTime * 1000);
178 }); 164 });
179 165
180 player.on('hls-missing-segment', function() {
181 //console.log('Missing Segment Triggered');
182 });
183
184 player.on('hls-missing-playlist', function() {
185 //console.log('Missing Playlist Triggered');
186 });
187
188 player.on('error', function() {
189
190 });
191
192 /** 166 /**
193 * Chooses the appropriate media playlist based on the current 167 * Chooses the appropriate media playlist based on the current
194 * bandwidth estimate and the player size. 168 * bandwidth estimate and the player size.
...@@ -337,8 +311,7 @@ var ...@@ -337,8 +311,7 @@ var
337 bufferedTime = 0, 311 bufferedTime = 0,
338 segment = player.hls.media.segments[player.hls.mediaIndex], 312 segment = player.hls.media.segments[player.hls.mediaIndex],
339 segmentUri, 313 segmentUri,
340 startTime, 314 startTime;
341 tagIndex;
342 315
343 // if there is a request already in flight, do nothing 316 // if there is a request already in flight, do nothing
344 if (segmentXhr) { 317 if (segmentXhr) {
...@@ -401,13 +374,11 @@ var ...@@ -401,13 +374,11 @@ var
401 // transmux the segment data from MP2T to FLV 374 // transmux the segment data from MP2T to FLV
402 segmentParser.parseSegmentBinaryData(new Uint8Array(this.response)); 375 segmentParser.parseSegmentBinaryData(new Uint8Array(this.response));
403 376
404 // handle intra-segment seeking, if requested // 377 // if we're refilling the buffer after a seek, scan through the muxed
378 // FLV tags until we find the one that is closest to the desired
379 // playback time
405 if (offset !== undefined && typeof offset === "number") { 380 if (offset !== undefined && typeof offset === "number") {
406 player.el().querySelector('.vjs-tech').vjs_setProperty('lastSeekedTime', player.hls.getPtsByTime(segmentParser,offset)/1000); 381 while (segmentParser.getTags()[0].pts < offset) {
407 for (tagIndex = 0; tagIndex < segmentParser.getTags().length; tagIndex++) {
408 if (segmentParser.getTags()[tagIndex].pts > offset) {
409 break;
410 }
411 // we're seeking past this tag, so ignore it 382 // we're seeking past this tag, so ignore it
412 segmentParser.getNextTag(); 383 segmentParser.getNextTag();
413 } 384 }
......
...@@ -186,9 +186,10 @@ ...@@ -186,9 +186,10 @@
186 186
187 test('the flv tags are well-formed', function() { 187 test('the flv tags are well-formed', function() {
188 var 188 var
189 tag,
190 byte, 189 byte,
190 tag,
191 type, 191 type,
192 currentPts = 0,
192 lastTime = 0; 193 lastTime = 0;
193 parser.parseSegmentBinaryData(window.bcSegment); 194 parser.parseSegmentBinaryData(window.bcSegment);
194 195
...@@ -196,6 +197,9 @@ ...@@ -196,6 +197,9 @@
196 tag = parser.getNextTag(); 197 tag = parser.getNextTag();
197 type = tag.bytes[0]; 198 type = tag.bytes[0];
198 199
200 ok(tag.pts >= currentPts, 'presentation time stamps are increasing');
201 currentPts = tag.pts;
202
199 // generic flv headers 203 // generic flv headers
200 ok(type === 8 || type === 9 || type === 18, 204 ok(type === 8 || type === 9 || type === 18,
201 'the type field specifies audio, video or script'); 205 'the type field specifies audio, video or script');
......
...@@ -514,39 +514,6 @@ test('cancels outstanding XHRs when seeking', function() { ...@@ -514,39 +514,6 @@ test('cancels outstanding XHRs when seeking', function() {
514 strictEqual(1, opened, 'opened new XHR'); 514 strictEqual(1, opened, 'opened new XHR');
515 }); 515 });
516 516
517 test('gets the correct PTS on seek', function() {
518 var
519 ptsByTime = -1,
520 seekTime = 5.123,
521 segmentParser = new window.videojs.hls.SegmentParser();
522 segmentParser.getTags = function() {
523 return [
524 {pts:1},
525 {pts:2},
526 {pts:3},
527 {pts:4},
528 {pts:5},
529 {pts:6}
530 ];
531 };
532
533 player.hls('manifest/media.m3u8');
534
535 videojs.mediaSources[player.currentSrc()].trigger({
536 type: 'sourceopen'
537 });
538
539 player.on('seeked', function() {
540 ptsByTime = player.hls.getPtsByTime(segmentParser,seekTime);
541 });
542
543 player.trigger('seeked');
544
545 notEqual(ptsByTime, -1, 'PTS Should be set on seek');
546 strictEqual(ptsByTime, 5, 'PTS should be closest');
547 ok(ptsByTime<=seekTime, 'PTS should be less than or equal to seek time');
548 });
549
550 test('playlist 404 should trigger MEDIA_ERR_NETWORK', function() { 517 test('playlist 404 should trigger MEDIA_ERR_NETWORK', function() {
551 var errorTriggered = false; 518 var errorTriggered = false;
552 519
......