Merge pull request #66 from videojs/feature/tech-seeking
Convert seeking implementation to currentTime
Showing
2 changed files
with
45 additions
and
24 deletions
... | @@ -183,20 +183,36 @@ var | ... | @@ -183,20 +183,36 @@ var |
183 | initSource = function(player, mediaSource, srcUrl) { | 183 | initSource = function(player, mediaSource, srcUrl) { |
184 | var | 184 | var |
185 | segmentParser = new videojs.Hls.SegmentParser(), | 185 | segmentParser = new videojs.Hls.SegmentParser(), |
186 | settings = videojs.util.mergeOptions({}, player.options().hls), | ||
186 | 187 | ||
188 | lastSeekedTime, | ||
187 | segmentXhr, | 189 | segmentXhr, |
188 | settings = videojs.util.mergeOptions({}, player.options().hls), | ||
189 | fillBuffer, | 190 | fillBuffer, |
190 | updateDuration; | 191 | updateDuration; |
191 | 192 | ||
192 | 193 | ||
193 | player.on('seeking', function() { | 194 | player.hls.currentTime = function() { |
194 | var currentTime = player.currentTime(); | 195 | if (lastSeekedTime) { |
195 | player.hls.mediaIndex = getMediaIndexByTime(player.hls.playlists.media(), | 196 | return lastSeekedTime; |
196 | currentTime); | 197 | } |
198 | return this.el().vjs_getProperty('currentTime'); | ||
199 | }; | ||
200 | player.hls.setCurrentTime = function(currentTime) { | ||
201 | if (!(this.playlists && this.playlists.media())) { | ||
202 | // return immediately if the metadata is not ready yet | ||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | // save the seek target so currentTime can report it correctly | ||
207 | // while the seek is pending | ||
208 | lastSeekedTime = currentTime; | ||
209 | |||
210 | // determine the requested segment | ||
211 | this.mediaIndex = | ||
212 | getMediaIndexByTime(this.playlists.media(), currentTime); | ||
197 | 213 | ||
198 | // abort any segments still being decoded | 214 | // abort any segments still being decoded |
199 | player.hls.sourceBuffer.abort(); | 215 | this.sourceBuffer.abort(); |
200 | 216 | ||
201 | // cancel outstanding requests and buffer appends | 217 | // cancel outstanding requests and buffer appends |
202 | if (segmentXhr) { | 218 | if (segmentXhr) { |
... | @@ -205,7 +221,7 @@ var | ... | @@ -205,7 +221,7 @@ var |
205 | 221 | ||
206 | // begin filling the buffer at the new position | 222 | // begin filling the buffer at the new position |
207 | fillBuffer(currentTime * 1000); | 223 | fillBuffer(currentTime * 1000); |
208 | }); | 224 | }; |
209 | 225 | ||
210 | /** | 226 | /** |
211 | * Update the player duration | 227 | * Update the player duration |
... | @@ -324,8 +340,9 @@ var | ... | @@ -324,8 +340,9 @@ var |
324 | bufferedTime = player.buffered().end(0) - player.currentTime(); | 340 | bufferedTime = player.buffered().end(0) - player.currentTime(); |
325 | } | 341 | } |
326 | 342 | ||
327 | // if there is plenty of content in the buffer, relax for awhile | 343 | // if there is plenty of content in the buffer and we're not |
328 | if (bufferedTime >= goalBufferLength) { | 344 | // seeking, relax for awhile |
345 | if (typeof offset !== 'number' && bufferedTime >= goalBufferLength) { | ||
329 | return; | 346 | return; |
330 | } | 347 | } |
331 | 348 | ||
... | @@ -376,11 +393,19 @@ var | ... | @@ -376,11 +393,19 @@ var |
376 | // if we're refilling the buffer after a seek, scan through the muxed | 393 | // if we're refilling the buffer after a seek, scan through the muxed |
377 | // FLV tags until we find the one that is closest to the desired | 394 | // FLV tags until we find the one that is closest to the desired |
378 | // playback time | 395 | // playback time |
379 | if (offset !== undefined && typeof offset === "number") { | 396 | if (typeof offset === 'number') { |
380 | while (segmentParser.getTags()[0].pts < offset) { | 397 | (function() { |
381 | segmentParser.getNextTag(); | 398 | var tag = segmentParser.getTags()[0]; |
399 | |||
400 | for (; tag.pts < offset; tag = segmentParser.getTags()[0]) { | ||
401 | segmentParser.getNextTag(); | ||
402 | } | ||
403 | |||
404 | // tell the SWF where we will be seeking to | ||
405 | player.hls.el().vjs_setProperty('currentTime', tag.pts * 0.001); | ||
406 | lastSeekedTime = null; | ||
407 | })(); | ||
382 | } | 408 | } |
383 | } | ||
384 | 409 | ||
385 | while (segmentParser.tagsAvailable()) { | 410 | while (segmentParser.tagsAvailable()) { |
386 | // queue up the bytes to be appended to the SourceBuffer | 411 | // queue up the bytes to be appended to the SourceBuffer |
... | @@ -467,6 +492,7 @@ videojs.Hls = videojs.Flash.extend({ | ... | @@ -467,6 +492,7 @@ videojs.Hls = videojs.Flash.extend({ |
467 | videojs.Hls.prototype.src = function(src) { | 492 | videojs.Hls.prototype.src = function(src) { |
468 | var | 493 | var |
469 | player = this.player(), | 494 | player = this.player(), |
495 | self = this, | ||
470 | mediaSource, | 496 | mediaSource, |
471 | source; | 497 | source; |
472 | 498 | ||
... | @@ -478,8 +504,8 @@ videojs.Hls.prototype.src = function(src) { | ... | @@ -478,8 +504,8 @@ videojs.Hls.prototype.src = function(src) { |
478 | }; | 504 | }; |
479 | this.mediaSource = mediaSource; | 505 | this.mediaSource = mediaSource; |
480 | initSource(player, mediaSource, src); | 506 | initSource(player, mediaSource, src); |
481 | this.ready(function() { | 507 | this.player().ready(function() { |
482 | this.el().vjs_src(source.src); | 508 | self.el().vjs_src(source.src); |
483 | }); | 509 | }); |
484 | } | 510 | } |
485 | }; | 511 | }; | ... | ... |
... | @@ -49,6 +49,7 @@ var | ... | @@ -49,6 +49,7 @@ var |
49 | 49 | ||
50 | tech = player.el().querySelector('.vjs-tech'); | 50 | tech = player.el().querySelector('.vjs-tech'); |
51 | tech.vjs_getProperty = function() {}; | 51 | tech.vjs_getProperty = function() {}; |
52 | tech.vjs_setProperty = function() {}; | ||
52 | tech.vjs_src = function() {}; | 53 | tech.vjs_src = function() {}; |
53 | videojs.Flash.onReady(tech.id); | 54 | videojs.Flash.onReady(tech.id); |
54 | 55 | ||
... | @@ -754,7 +755,7 @@ test('cancels outstanding XHRs when seeking', function() { | ... | @@ -754,7 +755,7 @@ test('cancels outstanding XHRs when seeking', function() { |
754 | // trigger a segment download request | 755 | // trigger a segment download request |
755 | player.trigger('timeupdate'); | 756 | player.trigger('timeupdate'); |
756 | // attempt to seek while the download is in progress | 757 | // attempt to seek while the download is in progress |
757 | player.trigger('seeking'); | 758 | player.currentTime(7); |
758 | 759 | ||
759 | ok(requests[1].aborted, 'XHR aborted'); | 760 | ok(requests[1].aborted, 'XHR aborted'); |
760 | strictEqual(requests.length, 3, 'opened new XHR'); | 761 | strictEqual(requests.length, 3, 'opened new XHR'); |
... | @@ -830,10 +831,7 @@ test('drops tags before the target timestamp when seeking', function() { | ... | @@ -830,10 +831,7 @@ test('drops tags before the target timestamp when seeking', function() { |
830 | bytes: i | 831 | bytes: i |
831 | }); | 832 | }); |
832 | } | 833 | } |
833 | player.currentTime = function() { | 834 | player.currentTime(7); |
834 | return 7; | ||
835 | }; | ||
836 | player.trigger('seeking'); | ||
837 | standardXHRResponse(requests[2]); | 835 | standardXHRResponse(requests[2]); |
838 | 836 | ||
839 | while (callbacks.length) { | 837 | while (callbacks.length) { |
... | @@ -879,10 +877,7 @@ test('clears pending buffer updates when seeking', function() { | ... | @@ -879,10 +877,7 @@ test('clears pending buffer updates when seeking', function() { |
879 | 877 | ||
880 | // seek to 7s | 878 | // seek to 7s |
881 | tags.push({ pts: 7000, bytes: 7 }); | 879 | tags.push({ pts: 7000, bytes: 7 }); |
882 | player.currentTime = function() { | 880 | player.currentTime(7); |
883 | return 7; | ||
884 | }; | ||
885 | player.trigger('seeking'); | ||
886 | standardXHRResponse(requests[2]); | 881 | standardXHRResponse(requests[2]); |
887 | 882 | ||
888 | while (callbacks.length) { | 883 | while (callbacks.length) { | ... | ... |
-
Please register or sign in to post a comment