6b05241f by David LaPalomento

Fix seek issue when first playing live streams

When you first called play() on a live stream, the seek wouldn't complete because of a condition in fillBuffer() that prevented buffering until the player had started. Allow fillBuffer() to begin buffering in a live stream at a specified position, which ensures drainBuffer() will clean up the seek correctly.
1 parent 72f9507d
...@@ -317,7 +317,6 @@ videojs.Hls.prototype.setupMetadataCueTranslation_ = function() { ...@@ -317,7 +317,6 @@ videojs.Hls.prototype.setupMetadataCueTranslation_ = function() {
317 * ended. 317 * ended.
318 */ 318 */
319 videojs.Hls.prototype.play = function() { 319 videojs.Hls.prototype.play = function() {
320 var media;
321 if (this.ended()) { 320 if (this.ended()) {
322 this.mediaIndex = 0; 321 this.mediaIndex = 0;
323 } 322 }
...@@ -327,9 +326,7 @@ videojs.Hls.prototype.play = function() { ...@@ -327,9 +326,7 @@ videojs.Hls.prototype.play = function() {
327 if (this.duration() === Infinity && 326 if (this.duration() === Infinity &&
328 this.playlists.media() && 327 this.playlists.media() &&
329 !this.player().hasClass('vjs-has-started')) { 328 !this.player().hasClass('vjs-has-started')) {
330 media = this.playlists.media(); 329 this.setCurrentTime(this.seekable().end(0));
331 this.mediaIndex = videojs.Hls.getMediaIndexForLive_(media);
332 this.setCurrentTime(videojs.Hls.Playlist.seekable(media).end(0));
333 } 330 }
334 331
335 // delegate back to the Flash implementation 332 // delegate back to the Flash implementation
...@@ -645,7 +642,8 @@ videojs.Hls.prototype.fillBuffer = function(offset) { ...@@ -645,7 +642,8 @@ videojs.Hls.prototype.fillBuffer = function(offset) {
645 // being buffering so we don't preload data that will never be 642 // being buffering so we don't preload data that will never be
646 // played 643 // played
647 if (!this.playlists.media().endList && 644 if (!this.playlists.media().endList &&
648 !this.player().hasClass('vjs-has-started')) { 645 !this.player().hasClass('vjs-has-started') &&
646 offset === undefined) {
649 return; 647 return;
650 } 648 }
651 649
......
...@@ -1663,19 +1663,33 @@ test('updates the media index when a playlist reloads', function() { ...@@ -1663,19 +1663,33 @@ test('updates the media index when a playlist reloads', function() {
1663 test('live playlist starts three target durations before live', function() { 1663 test('live playlist starts three target durations before live', function() {
1664 var mediaPlaylist; 1664 var mediaPlaylist;
1665 player.src({ 1665 player.src({
1666 src: 'http://example.com/manifest/liveStart30sBefore.m3u8', 1666 src: 'live.m3u8',
1667 type: 'application/vnd.apple.mpegurl' 1667 type: 'application/vnd.apple.mpegurl'
1668 }); 1668 });
1669 openMediaSource(player); 1669 openMediaSource(player);
1670 standardXHRResponse(requests.shift()); 1670 requests.shift().respond(200, null,
1671 '#EXTM3U\n' +
1672 '#EXT-X-MEDIA-SEQUENCE:101\n' +
1673 '#EXTINF:10,\n' +
1674 '0.ts\n' +
1675 '#EXTINF:10,\n' +
1676 '1.ts\n' +
1677 '#EXTINF:10,\n' +
1678 '2.ts\n' +
1679 '#EXTINF:10,\n' +
1680 '3.ts\n' +
1681 '#EXTINF:10,\n' +
1682 '4.ts\n');
1671 1683
1672 equal(player.hls.mediaIndex, 0, 'waits for the first play to start buffering'); 1684 equal(player.hls.mediaIndex, 0, 'waits for the first play to start buffering');
1673 equal(requests.length, 0, 'no outstanding segment request'); 1685 equal(requests.length, 0, 'no outstanding segment request');
1674 1686
1675 player.play(); 1687 player.play();
1676 mediaPlaylist = player.hls.playlists.media(); 1688 mediaPlaylist = player.hls.playlists.media();
1677 equal(player.hls.mediaIndex, 6, 'mediaIndex is updated at play'); 1689 equal(player.hls.mediaIndex, 1, 'mediaIndex is updated at play');
1678 equal(player.currentTime(), videojs.Hls.Playlist.seekable(mediaPlaylist).end(0)); 1690 equal(player.currentTime(), player.seekable().end(0));
1691
1692 equal(requests.length, 1, 'begins buffering');
1679 }); 1693 });
1680 1694
1681 test('does not reset live currentTime if mediaIndex is one beyond the last available segment', function() { 1695 test('does not reset live currentTime if mediaIndex is one beyond the last available segment', function() {
......