Skip to content

Commit

Permalink
feat(HLS): Add HLS config to ignore manifest timestamps when in segme…
Browse files Browse the repository at this point in the history
…nts mode (shaka-project#5103)
  • Loading branch information
swac committed Mar 23, 2023
1 parent 66219bc commit 4d487e4
Show file tree
Hide file tree
Showing 17 changed files with 55 additions and 5 deletions.
1 change: 1 addition & 0 deletions demo/common/message_ids.js
Expand Up @@ -206,6 +206,7 @@ shakaDemo.MessageIds = {
IGNORE_HLS_IMAGE_FAILURES: 'DEMO_IGNORE_HLS_IMAGE_FAILURES',
IGNORE_HLS_TEXT_FAILURES: 'DEMO_IGNORE_HLS_TEXT_FAILURES',
IGNORE_MANIFEST_PROGRAM_DATE_TIME: 'DEMO_IGNORE_MANIFEST_PROGRAM_DATE_TIME',
IGNORE_MANIFEST_TIMESTAMPS_IN_SEGMENTS_MODE: 'DEMO_IGNORE_MANIFEST_TIMESTAMPS_IN_SEGMENTS_MODE',
IGNORE_MIN_BUFFER_TIME: 'DEMO_IGNORE_MIN_BUFFER_TIME',
IGNORE_TEXT_FAILURES: 'DEMO_IGNORE_TEXT_FAILURES',
INACCURATE_MANIFEST_TOLERANCE: 'DEMO_INACCURATE_MANIFEST_TOLERANCE',
Expand Down
2 changes: 2 additions & 0 deletions demo/config.js
Expand Up @@ -226,6 +226,8 @@ shakaDemo.Config = class {
'manifest.hls.liveSegmentsDelay')
.addBoolInput_(MessageIds.HLS_SEQUENCE_MODE,
'manifest.hls.sequenceMode')
.addBoolInput_(MessageIds.IGNORE_MANIFEST_TIMESTAMPS_IN_SEGMENTS_MODE,
'manifest.hls.ignoreManifestTimestampsInSegmentsMode')
.addNumberInput_(MessageIds.AVAILABILITY_WINDOW_OVERRIDE,
'manifest.availabilityWindowOverride',
/* canBeDecimal= */ true,
Expand Down
1 change: 1 addition & 0 deletions demo/locales/en.json
Expand Up @@ -110,6 +110,7 @@
"DEMO_IMA_MANIFEST_TYPE": "Manifest type (for DAI Content)",
"DEMO_IMA_VIDEO_ID": "Video ID (for VOD DAI Content)",
"DEMO_IGNORE_MANIFEST_PROGRAM_DATE_TIME": "Ignore Program Date Time from manifest",
"DEMO_IGNORE_MANIFEST_TIMESTAMPS_IN_SEGMENTS_MODE": "Ignore Manifest Timestamps in Segments Mode",
"DEMO_IGNORE_MIN_BUFFER_TIME": "Ignore Min Buffer Time",
"DEMO_IGNORE_TEXT_FAILURES": "Ignore Text Stream Failures",
"DEMO_INACCURATE_MANIFEST_TOLERANCE": "Inaccurate Manifest Tolerance",
Expand Down
4 changes: 4 additions & 0 deletions demo/locales/source.json
Expand Up @@ -447,6 +447,10 @@
"description": "The name of a configuration value.",
"message": "Ignore Program Date Time from manifest"
},
"DEMO_IGNORE_MANIFEST_TIMESTAMPS_IN_SEGMENTS_MODE": {
"description": "The name of a configuration value.",
"message": "Ignore Manifest Timestamps in Segments Mode"
},
"DEMO_IGNORE_MIN_BUFFER_TIME": {
"description": "The name of a configuration value.",
"message": "Ignore Min Buffer Time"
Expand Down
9 changes: 9 additions & 0 deletions externs/shaka/manifest.js
Expand Up @@ -19,6 +19,7 @@
* offlineSessionIds: !Array.<string>,
* minBufferTime: number,
* sequenceMode: boolean,
* ignoreManifestTimestampsInSegmentsMode: boolean,
* type: string
* }}
*
Expand Down Expand Up @@ -77,6 +78,14 @@
* @property {boolean} sequenceMode
* If true, we will append the media segments using sequence mode; that is to
* say, ignoring any timestamps inside the media files.
* @property {boolean} ignoreManifestTimestampsInSegmentsMode
* If true, don't adjust the timestamp offset to account for manifest
* segment durations being out of sync with segment durations. In other
* words, assume that there are no gaps in the segments when appending
* to the SourceBuffer, even if the manifest and segment times disagree.
* Only applies when sequenceMode is <code>false</code>, and only for HLS
* streams.
* <i>Defaults to <code>false</code>.</i>
* @property {string} type
* Indicates the type of the manifest. It can be <code>'HLS'</code> or
* <code>'DASH'</code>.
Expand Down
10 changes: 9 additions & 1 deletion externs/shaka/player.js
Expand Up @@ -841,7 +841,8 @@ shaka.extern.DashManifestConfiguration;
* mediaPlaylistFullMimeType: string,
* useSafariBehaviorForLive: boolean,
* liveSegmentsDelay: number,
* sequenceMode: boolean
* sequenceMode: boolean,
* ignoreManifestTimestampsInSegmentsMode: boolean
* }}
*
* @property {boolean} ignoreTextStreamFailures
Expand Down Expand Up @@ -887,6 +888,13 @@ shaka.extern.DashManifestConfiguration;
* "sequence mode" (ignoring their internal timestamps).
* Defaults to <code>true</code> except on WebOS 3, Tizen 2,
* Tizen 3 and PlayStation 4 whose default value is <code>false</code>.
* @property {boolean} ignoreManifestTimestampsInSegmentsMode
* If true, don't adjust the timestamp offset to account for manifest
* segment durations being out of sync with segment durations. In other
* words, assume that there are no gaps in the segments when appending
* to the SourceBuffer, even if the manifest and segment times disagree.
* Only applies when sequenceMode is <code>false</code>.
* <i>Defaults to <code>false</code>.</i>
* @exportDoc
*/
shaka.extern.HlsManifestConfiguration;
Expand Down
1 change: 1 addition & 0 deletions lib/dash/dash_parser.js
Expand Up @@ -495,6 +495,7 @@ shaka.dash.DashParser = class {
offlineSessionIds: [],
minBufferTime: minBufferTime || 0,
sequenceMode: this.config_.dash.sequenceMode,
ignoreManifestTimestampsInSegmentsMode: false,
type: shaka.media.ManifestParser.DASH,
};

Expand Down
2 changes: 2 additions & 0 deletions lib/hls/hls_parser.js
Expand Up @@ -761,6 +761,8 @@ shaka.hls.HlsParser = class {
offlineSessionIds: [],
minBufferTime: 0,
sequenceMode: this.config_.hls.sequenceMode,
ignoreManifestTimestampsInSegmentsMode:
this.config_.hls.ignoreManifestTimestampsInSegmentsMode,
type: shaka.media.ManifestParser.HLS,
};
this.playerInterface_.makeTextStreamsForClosedCaptions(this.manifest_);
Expand Down
16 changes: 14 additions & 2 deletions lib/media/media_source_engine.js
Expand Up @@ -127,6 +127,9 @@ shaka.media.MediaSourceEngine = class {
/** @private {string} */
this.manifestType_ = shaka.media.ManifestParser.UNKNOWN;

/** @private {boolean} */
this.ignoreManifestTimestampsInSegmentsMode_ = false;

/** @private {!shaka.util.PublicPromise.<number>} */
this.textSequenceModeOffset_ = new shaka.util.PublicPromise();
}
Expand Down Expand Up @@ -351,17 +354,25 @@ shaka.media.MediaSourceEngine = class {
* sequence.
* @param {string=} manifestType
* Indicates the type of the manifest.
* @param {boolean=} ignoreManifestTimestampsInSegmentsMode
* If true, don't adjust the timestamp offset to account for manifest
* segment durations being out of sync with segment durations. In other
* words, assume that there are no gaps in the segments when appending
* to the SourceBuffer, even if the manifest and segment times disagree.
*
* @return {!Promise}
*/
async init(streamsByType, sequenceMode=false,
manifestType=shaka.media.ManifestParser.UNKNOWN) {
manifestType=shaka.media.ManifestParser.UNKNOWN,
ignoreManifestTimestampsInSegmentsMode=false) {
const ContentType = shaka.util.ManifestParserUtils.ContentType;

await this.mediaSourceOpen_;

this.sequenceMode_ = sequenceMode;
this.manifestType_ = manifestType;
this.ignoreManifestTimestampsInSegmentsMode_ =
ignoreManifestTimestampsInSegmentsMode;

for (const contentType of streamsByType.keys()) {
const stream = streamsByType.get(contentType);
Expand Down Expand Up @@ -614,7 +625,8 @@ shaka.media.MediaSourceEngine = class {
}

const attemptTimestampOffsetCalculation = !this.sequenceMode_ &&
this.manifestType_ == shaka.media.ManifestParser.HLS;
this.manifestType_ == shaka.media.ManifestParser.HLS &&
!this.ignoreManifestTimestampsInSegmentsMode_;

let timestampOffset = this.sourceBuffers_[contentType].timestampOffset;

Expand Down
4 changes: 3 additions & 1 deletion lib/media/streaming_engine.js
Expand Up @@ -812,7 +812,9 @@ shaka.media.StreamingEngine = class {

await mediaSourceEngine.init(streamsByType,
this.manifest_.sequenceMode,
this.manifest_.type);
this.manifest_.type,
this.manifest_.ignoreManifestTimestampsInSegmentsMode,
);
this.destroyer_.ensureNotDestroyed();

this.updateDuration();
Expand Down
1 change: 1 addition & 0 deletions lib/offline/manifest_converter.js
Expand Up @@ -89,6 +89,7 @@ shaka.offline.ManifestConverter = class {
textStreams: textStreams,
imageStreams: imageStreams,
sequenceMode: manifestDB.sequenceMode || false,
ignoreManifestTimestampsInSegmentsMode: false,
type: manifestDB.type || shaka.media.ManifestParser.UNKNOWN,
};
}
Expand Down
1 change: 1 addition & 0 deletions lib/util/player_configuration.js
Expand Up @@ -150,6 +150,7 @@ shaka.util.PlayerConfiguration = class {
useSafariBehaviorForLive: true,
liveSegmentsDelay: 3,
sequenceMode: supportsSequenceMode,
ignoreManifestTimestampsInSegmentsMode: false,
},
};

Expand Down
1 change: 1 addition & 0 deletions test/media/playhead_unit.js
Expand Up @@ -134,6 +134,7 @@ describe('Playhead', () => {
minBufferTime: 10,
offlineSessionIds: [],
sequenceMode: false,
ignoreManifestTimestampsInSegmentsMode: false,
type: 'UNKNOWN',
};

Expand Down
1 change: 1 addition & 0 deletions test/media/streaming_engine_integration.js
Expand Up @@ -594,6 +594,7 @@ describe('StreamingEngine', () => {
textStreams: [],
imageStreams: [],
sequenceMode: false,
ignoreManifestTimestampsInSegmentsMode: false,
type: 'UNKNOWN',
variants: [{
id: 1,
Expand Down
3 changes: 2 additions & 1 deletion test/media/streaming_engine_unit.js
Expand Up @@ -520,7 +520,8 @@ describe('StreamingEngine', () => {
expectedMseInit.set(ContentType.TEXT, textStream);

expect(mediaSourceEngine.init).toHaveBeenCalledWith(expectedMseInit,
/** sequenceMode= */ false, /** manifestType= */ 'UNKNOWN');
/** sequenceMode= */ false, /** manifestType= */ 'UNKNOWN',
/** ignoreManifestTimestampsInSegmentsMode= */ false);
expect(mediaSourceEngine.init).toHaveBeenCalledTimes(1);

expect(mediaSourceEngine.setDuration).toHaveBeenCalledTimes(1);
Expand Down
2 changes: 2 additions & 0 deletions test/test/util/manifest_generator.js
Expand Up @@ -97,6 +97,8 @@ shaka.test.ManifestGenerator.Manifest = class {
this.minBufferTime = 0;
/** @type {boolean} */
this.sequenceMode = false;
/** @type {boolean} */
this.ignoreManifestTimestampsInSegmentsMode = false;
/** @type {string} */
this.type = 'UNKNOWN';

Expand Down
1 change: 1 addition & 0 deletions test/test/util/streaming_engine_util.js
Expand Up @@ -284,6 +284,7 @@ shaka.test.StreamingEngineUtil = class {
textStreams: [],
imageStreams: [],
sequenceMode: false,
ignoreManifestTimestampsInSegmentsMode: false,
type: 'UNKNOWN',
};

Expand Down

0 comments on commit 4d487e4

Please sign in to comment.