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.
Showing
3 changed files
with
10 additions
and
68 deletions
... | @@ -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 | ... | ... |
-
Please register or sign in to post a comment