Browse Source

Merge pull request #184 from bc-bbay/master

Setting start position on a live stream
pull/6/head
David LaPalomento 11 years ago
parent
commit
dc135fdf32
  1. 33
      src/videojs-hls.js
  2. 43
      test/manifest/liveStart30sBefore.json
  3. 22
      test/manifest/liveStart30sBefore.m3u8
  4. 14
      test/videojs-hls_test.js

33
src/videojs-hls.js

@ -89,6 +89,18 @@ videojs.Hls.prototype.src = function(src) {
}); });
}; };
videojs.Hls.setMediaIndexForLive = function(selectedPlaylist) {
var tailIterator = selectedPlaylist.segments.length,
tailDuration = 0;
while (tailDuration < 30 && tailIterator > 0) {
tailDuration += selectedPlaylist.segments[tailIterator - 1].duration;
tailIterator--;
}
return tailIterator;
};
videojs.Hls.prototype.handleSourceOpen = function() { videojs.Hls.prototype.handleSourceOpen = function() {
// construct the video data buffer and set the appropriate MIME type // construct the video data buffer and set the appropriate MIME type
var var
@ -142,6 +154,11 @@ videojs.Hls.prototype.handleSourceOpen = function() {
segmentDlTime = Infinity; segmentDlTime = Infinity;
} }
// start live playlists 30 seconds before the current time
if (this.duration() === Infinity && this.mediaIndex === 0 && selectedPlaylist.segments) {
this.mediaIndex = videojs.Hls.setMediaIndexForLive(selectedPlaylist);
}
// this threshold is to account for having a high latency on the manifest // this threshold is to account for having a high latency on the manifest
// request which is a somewhat small file. // request which is a somewhat small file.
threshold = 10; threshold = 10;
@ -781,14 +798,15 @@ videojs.Hls.getPlaylistTotalDuration = function(playlist) {
* playlist * playlist
*/ */
videojs.Hls.translateMediaIndex = function(mediaIndex, original, update) { videojs.Hls.translateMediaIndex = function(mediaIndex, original, update) {
var
i,
originalSegment;
var i,
originalSegment,
translatedMediaIndex;
// no segments have been loaded from the original playlist // no segments have been loaded from the original playlist
if (mediaIndex === 0) { if (mediaIndex === 0) {
return 0; return 0;
} }
if (!(update && update.segments)) { if (!(update && update.segments)) {
// let the media index be zero when there are no segments defined // let the media index be zero when there are no segments defined
return 0; return 0;
@ -803,8 +821,15 @@ videojs.Hls.translateMediaIndex = function(mediaIndex, original, update) {
} }
} }
translatedMediaIndex = (mediaIndex + (original.mediaSequence - update.mediaSequence));
if (translatedMediaIndex >= update.segments.length || translatedMediaIndex < 0) {
// recalculate the live point if the streams are too far out of sync
return videojs.Hls.setMediaIndexForLive(update) + 1;
}
// sync on media sequence // sync on media sequence
return (original.mediaSequence + mediaIndex) - update.mediaSequence;
return translatedMediaIndex;
}; };
/** /**

43
test/manifest/liveStart30sBefore.json

@ -0,0 +1,43 @@
{
"allowCache": true,
"mediaSequence": 0,
"segments": [
{
"duration": 10,
"uri": "001.ts"
},
{
"duration": 19,
"uri": "002.ts"
},
{
"duration": 10,
"uri": "003.ts"
},
{
"duration": 11,
"uri": "004.ts"
},
{
"duration": 10,
"uri": "005.ts"
},
{
"duration": 10,
"uri": "006.ts"
},
{
"duration": 10,
"uri": "007.ts"
},
{
"duration": 10,
"uri": "008.ts"
},
{
"duration": 16,
"uri": "009.ts"
}
],
"targetDuration": 19
}

22
test/manifest/liveStart30sBefore.m3u8

@ -0,0 +1,22 @@
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:19
#EXTINF:10,0
001.ts
#EXTINF:19,0
002.ts
#EXTINF:10,0
003.ts
#EXTINF:11,0
004.ts
#EXTINF:10,0
005.ts
#EXTINF:10,0
006.ts
#EXTINF:10,0
007.ts
#EXTINF:10,0
008.ts
#EXTINF:16,0
009.ts

14
test/videojs-hls_test.js

@ -1054,6 +1054,20 @@ test('updates the media index when a playlist reloads', function() {
strictEqual(player.hls.mediaIndex, 2, 'mediaIndex is updated after the reload'); strictEqual(player.hls.mediaIndex, 2, 'mediaIndex is updated after the reload');
}); });
test('live playlist starts 30s before live', function() {
player.src({
src: 'http://example.com/manifest/liveStart30sBefore.m3u8',
type: 'application/vnd.apple.mpegurl'
});
openMediaSource(player);
standardXHRResponse(requests[0]);
player.hls.playlists.trigger('loadedmetadata');
strictEqual(player.hls.mediaIndex, 6, 'mediaIndex is updated after the reload');
});
test('mediaIndex is zero before the first segment loads', function() { test('mediaIndex is zero before the first segment loads', function() {
window.manifests['first-seg-load'] = window.manifests['first-seg-load'] =
'#EXTM3U\n' + '#EXTM3U\n' +

Loading…
Cancel
Save