Skip to content

Commit

Permalink
feat(HLS): Add ignoreManifestProgramDateTimeForTypes (#6372)
Browse files Browse the repository at this point in the history
This new configuration value allows the HLS parser to selectively ignore EXT-X-PROGRAM-DATE-TIME tags on some streams while honoring him for other streams.
  • Loading branch information
theodab committed Mar 28, 2024
1 parent b51e661 commit 03bb463
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 6 deletions.
9 changes: 9 additions & 0 deletions externs/shaka/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,7 @@ shaka.extern.DashManifestConfiguration;
* defaultAudioCodec: string,
* defaultVideoCodec: string,
* ignoreManifestProgramDateTime: boolean,
* ignoreManifestProgramDateTimeForTypes: !Array<string>,
* mediaPlaylistFullMimeType: string,
* useSafariBehaviorForLive: boolean,
* liveSegmentsDelay: number,
Expand Down Expand Up @@ -1010,6 +1011,14 @@ shaka.extern.DashManifestConfiguration;
* Meant for streams where <code>EXT-X-PROGRAM-DATE-TIME</code> is incorrect
* or malformed.
* <i>Defaults to <code>false</code>.</i>
* @property {!Array.<string>} ignoreManifestProgramDateTimeForTypes
* An array of strings representing types for which
* <code>EXT-X-PROGRAM-DATE-TIME</code> should be ignored. Only used if the
* the main ignoreManifestProgramDateTime is set to false.
* For example, setting this to ['text', 'video'] will cause the PDT values
* text and video streams to be ignored, while still using the PDT values for
* audio.
* <i>Defaults to an empty array.</i>
* @property {string} mediaPlaylistFullMimeType
* A string containing a full mime type, including both the basic mime type
* and also the codecs. Used when the HLS parser parses a media playlist
Expand Down
38 changes: 32 additions & 6 deletions lib/hls/hls_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ shaka.hls.HlsParser = class {

const {segments, bandwidth} = this.createSegments_(
playlist, stream, mediaSequenceToStartTime, mediaVariables,
streamInfo.getUris);
streamInfo.getUris, streamInfo.type);
if (bandwidth) {
stream.bandwidth = bandwidth;
}
Expand Down Expand Up @@ -593,6 +593,9 @@ shaka.hls.HlsParser = class {
this.minSequenceNumber_);

for (const streamInfo of streamInfos) {
if (!this.ignoreManifestProgramDateTimeFor_(streamInfo.type)) {
continue;
}
const segmentIndex = streamInfo.stream.segmentIndex;
if (segmentIndex) {
// Drop any earlier references.
Expand Down Expand Up @@ -647,6 +650,9 @@ shaka.hls.HlsParser = class {
shaka.log.debug('Syncing HLS streams against base time:', lowestSyncTime);

for (const streamInfo of this.uriToStreamInfosMap_.values()) {
if (this.ignoreManifestProgramDateTimeFor_(streamInfo.type)) {
continue;
}
const segmentIndex = streamInfo.stream.segmentIndex;
if (segmentIndex != null) {
// A segment's startTime should be based on its syncTime vs the lowest
Expand Down Expand Up @@ -2421,9 +2427,25 @@ shaka.hls.HlsParser = class {
this.syncStreamsWithSequenceNumber_(streamInfos);
} else {
this.syncStreamsWithProgramDateTime_(streamInfos);
if (this.config_.hls.ignoreManifestProgramDateTimeForTypes.length > 0) {
this.syncStreamsWithSequenceNumber_(streamInfos);
}
}
}

/**
* @param {string} type
* @return {boolean}
* @private
*/
ignoreManifestProgramDateTimeFor_(type) {
if (this.config_.hls.ignoreManifestProgramDateTime) {
return true;
}
const forTypes = this.config_.hls.ignoreManifestProgramDateTimeForTypes;
return forTypes.includes(type);
}

/**
* There are some values on streams that can only be set once we know about
* both the video and audio content, if present.
Expand Down Expand Up @@ -2532,7 +2554,8 @@ shaka.hls.HlsParser = class {
this.mediaSequenceToStartTimeByType_.get(type) : new Map();

const {segments, bandwidth} = this.createSegments_(
playlist, stream, mediaSequenceToStartTime, mediaVariables, getUris);
playlist, stream, mediaSequenceToStartTime, mediaVariables, getUris,
type);
if (bandwidth) {
stream.bandwidth = bandwidth;
}
Expand Down Expand Up @@ -3480,12 +3503,13 @@ shaka.hls.HlsParser = class {
* @param {!Map.<number, number>} mediaSequenceToStartTime
* @param {!Map.<string, string>} variables
* @param {function():!Array.<string>} getUris
* @param {string} type
* @return {{segments: !Array.<!shaka.media.SegmentReference>,
* bandwidth: (number|undefined)}}
* @private
*/
createSegments_(playlist, stream, mediaSequenceToStartTime, variables,
getUris) {
getUris, type) {
/** @type {Array.<!shaka.hls.Segment>} */
const hlsSegments = playlist.segments;
goog.asserts.assert(hlsSegments.length, 'Playlist should have segments!');
Expand Down Expand Up @@ -3599,7 +3623,7 @@ shaka.hls.HlsParser = class {
previousReference = reference;
reference.discontinuitySequence = discontinuitySequence;

if (this.config_.hls.ignoreManifestProgramDateTime &&
if (this.ignoreManifestProgramDateTimeFor_(type) &&
this.minSequenceNumber_ != null &&
position < this.minSequenceNumber_) {
// This segment is ignored as part of our fallback synchronization
Expand Down Expand Up @@ -3700,8 +3724,10 @@ shaka.hls.HlsParser = class {
// skip this step, and wait until we have sync time across stream types.
const lowestSyncTime = this.lowestSyncTime_;
if (someSyncTime && lowestSyncTime != Infinity) {
for (const reference of references) {
reference.syncAgainst(lowestSyncTime);
if (!this.ignoreManifestProgramDateTimeFor_(type)) {
for (const reference of references) {
reference.syncAgainst(lowestSyncTime);
}
}
}

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 @@ -150,6 +150,7 @@ shaka.util.PlayerConfiguration = class {
defaultAudioCodec: 'mp4a.40.2',
defaultVideoCodec: 'avc1.42E01E',
ignoreManifestProgramDateTime: false,
ignoreManifestProgramDateTimeForTypes: [],
mediaPlaylistFullMimeType:
'video/mp2t; codecs="avc1.42E01E, mp4a.40.2"',
useSafariBehaviorForLive: true,
Expand Down
1 change: 1 addition & 0 deletions test/demo/demo_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ describe('Demo', () => {
.add('playRangeStart')
.add('playRangeEnd')
.add('manifest.dash.keySystemsByURI')
.add('manifest.hls.ignoreManifestProgramDateTimeForTypes')
.add('manifest.mss.keySystemsBySystemId')
.add('drm.keySystemsMapping')
.add('manifest.raiseFatalErrorOnManifestUpdateRequestFailure')
Expand Down

0 comments on commit 03bb463

Please sign in to comment.