Skip to content

Commit

Permalink
Add option to disable drift fixing.
Browse files Browse the repository at this point in the history
The drift fixing allows us to play content that has drift by starting
to play at the last segment in the manifest.  But some live content
specifies content in the future, so we can't just start playing at the
last segment in the manifest.

Fixes #1729

Change-Id: I3095a2d28b34ed93346933f561d77335361f1fae
  • Loading branch information
TheModMaker committed Feb 15, 2019
1 parent 5d04243 commit 2d99929
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 8 deletions.
8 changes: 7 additions & 1 deletion externs/shaka/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,8 @@ shaka.extern.DrmConfiguration;
* ignoreDrmInfo: boolean,
* xlinkFailGracefully: boolean,
* defaultPresentationDelay: number,
* ignoreMinBufferTime: boolean
* ignoreMinBufferTime: boolean,
* autoCorrectDrift: boolean
* }}
*
* @property {shaka.extern.DashContentProtectionCallback} customScheme
Expand All @@ -541,6 +542,11 @@ shaka.extern.DrmConfiguration;
* If true will cause DASH parser to ignore minBufferTime from manifest.
* It allows player config to take precedence over manifest for
* rebufferingGoal. Defaults to false if not provided.
* @property {boolean} autoCorrectDrift
* If true, ignore the availabilityStartTime in the manifest and instead use
* the segments to determine the live edge. This allows us to play streams
* that have a lot of drift. If false, we can't play content where the
* manifest specifies segments in the future. Defaults to true.
*
* @exportDoc
*/
Expand Down
3 changes: 2 additions & 1 deletion lib/dash/dash_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,8 @@ shaka.dash.DashParser.prototype.processManifest_ =
let presentationDelay = suggestedPresentationDelay != null ?
suggestedPresentationDelay : defaultPresentationDelay;
presentationTimeline = new shaka.media.PresentationTimeline(
presentationStartTime, presentationDelay);
presentationStartTime, presentationDelay,
this.config_.dash.autoCorrectDrift);
}

/** @type {shaka.dash.DashParser.Context} */
Expand Down
9 changes: 7 additions & 2 deletions lib/media/presentation_timeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ goog.require('shaka.media.SegmentReference');
* when the presentation started or will start. Only required for live.
* @param {number} presentationDelay The delay to give the presentation, in
* seconds. Only required for live.
* @param {boolean=} autoCorrectDrift Whether to account for drift when
* determining the availability window.
*
* @see {shaka.extern.Manifest}
* @see {@tutorial architecture}
Expand All @@ -38,7 +40,7 @@ goog.require('shaka.media.SegmentReference');
* @export
*/
shaka.media.PresentationTimeline = function(
presentationStartTime, presentationDelay) {
presentationStartTime, presentationDelay, autoCorrectDrift = true) {
/** @private {?number} */
this.presentationStartTime_ = presentationStartTime;

Expand Down Expand Up @@ -90,6 +92,9 @@ shaka.media.PresentationTimeline = function(

/** @private {number} */
this.userSeekStart_ = 0;

/** @private {boolean} */
this.autoCorrectDrift_ = autoCorrectDrift;
};


Expand Down Expand Up @@ -232,7 +237,7 @@ shaka.media.PresentationTimeline.prototype.notifySegments = function(
this.maxSegmentEndTime_ =
Math.max(this.maxSegmentEndTime_, lastReferenceEndTime);

if (this.presentationStartTime_ != null) {
if (this.presentationStartTime_ != null && this.autoCorrectDrift_) {
// Since we have explicit segment end times, calculate a presentation start
// based on them. This start time accounts for drift.
// Date.now() is in milliseconds, from which we compute "now" in seconds.
Expand Down
1 change: 1 addition & 0 deletions lib/util/player_configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ shaka.util.PlayerConfiguration = class {
xlinkFailGracefully: false,
defaultPresentationDelay: 10,
ignoreMinBufferTime: false,
autoCorrectDrift: true,
},
};

Expand Down
29 changes: 25 additions & 4 deletions test/media/presentation_timeline_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ describe('PresentationTimeline', function() {
* @param {number} maxSegmentDuration
* @param {number} clockOffset
* @param {number} presentationDelay
* @param {boolean=} autoCorrectDrift
*
* @return {shaka.media.PresentationTimeline}
*/
Expand All @@ -56,9 +57,10 @@ describe('PresentationTimeline', function() {
segmentAvailabilityDuration,
maxSegmentDuration,
clockOffset,
presentationDelay) {
presentationDelay,
autoCorrectDrift = true) {
let timeline = new shaka.media.PresentationTimeline(
presentationStartTime, presentationDelay);
presentationStartTime, presentationDelay, autoCorrectDrift);
timeline.setStatic(isStatic);
timeline.setDuration(duration || Infinity);
timeline.setSegmentAvailabilityDuration(segmentAvailabilityDuration);
Expand Down Expand Up @@ -107,14 +109,15 @@ describe('PresentationTimeline', function() {
*
* @param {number} availability
* @param {number=} delay
* @param {boolean=} autoCorrectDrift
* @return {shaka.media.PresentationTimeline}
*/
function makeLiveTimeline(availability, delay) {
function makeLiveTimeline(availability, delay, autoCorrectDrift = true) {
let now = Date.now() / 1000;
let timeline = makePresentationTimeline(
/* static */ false, /* duration */ Infinity, /* start time */ now,
availability, /* max seg dur */ 10,
/* clock offset */ 0, delay || 0);
/* clock offset */ 0, delay || 0, autoCorrectDrift);
expect(timeline.isLive()).toBe(true);
expect(timeline.isInProgress()).toBe(false);
return timeline;
Expand Down Expand Up @@ -212,6 +215,24 @@ describe('PresentationTimeline', function() {
// last segment time (50) - availability (20)
expect(timeline.getSegmentAvailabilityStart()).toBe(30);
});

it('ignores segment times when configured to', () => {
const timeline = makeLiveTimeline(
/* availability */ 20, /* drift */ 0, /* autoCorrectDrift */ false);

const ref1 = makeSegmentReference(0, 10);
const ref2 = makeSegmentReference(10, 20);
const ref3 = makeSegmentReference(20, 30);
const ref4 = makeSegmentReference(30, 40);
const ref5 = makeSegmentReference(40, 50);

setElapsed(100);
timeline.notifySegments([ref1, ref2, ref3, ref4, ref5],
/* periodStart */ 0);

// now (100) - max segment duration (10) - availability start time (0)
expect(timeline.getSegmentAvailabilityEnd()).toBe(90);
});
});

describe('getSegmentAvailabilityEnd', function() {
Expand Down

0 comments on commit 2d99929

Please sign in to comment.