Skip to content

Commit

Permalink
feat: Remove streaming.parsePrftBox config (#7358)
Browse files Browse the repository at this point in the history
The site code is changed to use a parser that is always used and thus we
avoid having a configuration that is not necessary.
  • Loading branch information
avelad authored Sep 24, 2024
1 parent 6d57863 commit fc4893d
Show file tree
Hide file tree
Showing 13 changed files with 80 additions and 153 deletions.
2 changes: 0 additions & 2 deletions demo/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -490,8 +490,6 @@ shakaDemo.Config = class {
'streaming.observeQualityChanges')
.addNumberInput_('Max Variant Disabled Time',
'streaming.maxDisabledTime')
.addBoolInput_('Parse PRFT box',
'streaming.parsePrftBox')
.addNumberInput_('Segment Prefetch Limit',
'streaming.segmentPrefetchLimit',
/* canBeDecimal= */ false,
Expand Down
1 change: 1 addition & 0 deletions docs/tutorials/upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ application:
`targetLatencyTolerance`, `maxPlaybackRate`, `minPlaybackRate`, `panicMode`
`panicThreshold`. (deprecated in v4.10.0)
- `useSafariBehaviorForLive` has been removed.
- `parsePrftBox` has been removed.

- Plugin changes:
- `TextDisplayer` plugins must implement the `configure()` method.
Expand Down
9 changes: 0 additions & 9 deletions externs/shaka/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -1556,7 +1556,6 @@ shaka.extern.LiveSyncConfiguration;
* dispatchAllEmsgBoxes: boolean,
* observeQualityChanges: boolean,
* maxDisabledTime: number,
* parsePrftBox: boolean,
* segmentPrefetchLimit: number,
* prefetchAudioLanguages: !Array<string>,
* disableAudioPrefetch: boolean,
Expand Down Expand Up @@ -1744,14 +1743,6 @@ shaka.extern.LiveSyncConfiguration;
* If all variants are disabled this way, NETWORK HTTP_ERROR will be thrown.
* <br>
* Defaults to <code>30</code>.
* @property {boolean} parsePrftBox
* If <code>true</code>, will raise a shaka.extern.ProducerReferenceTime
* player event (event name 'prft').
* The event will be raised only once per playback session as program
* start date will not change, and would save parsing the segment multiple
* times needlessly.
* <br>
* Defaults to <code>false</code>.
* @property {number} segmentPrefetchLimit
* The maximum number of segments for each active stream to be prefetched
* ahead of playhead in parallel.
Expand Down
64 changes: 61 additions & 3 deletions lib/media/media_source_engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ goog.require('shaka.util.BufferUtils');
goog.require('shaka.util.Destroyer');
goog.require('shaka.util.Error');
goog.require('shaka.util.EventManager');
goog.require('shaka.util.FakeEvent');
goog.require('shaka.util.Functional');
goog.require('shaka.util.IDestroyable');
goog.require('shaka.util.Id3Utils');
Expand Down Expand Up @@ -166,6 +167,9 @@ shaka.media.MediaSourceEngine = class {

/** @private {!shaka.util.PublicPromise.<number>} */
this.audioCompensation_ = new shaka.util.PublicPromise();

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

/**
Expand Down Expand Up @@ -498,6 +502,12 @@ shaka.media.MediaSourceEngine = class {
!this.ignoreManifestTimestampsInSegmentsMode_;

this.tsParser_ = null;
this.firstVideoTimestamp_ = null;
this.firstVideoReferenceStartTime_ = null;
this.firstAudioTimestamp_ = null;
this.firstAudioReferenceStartTime_ = null;
this.audioCompensation_ = new shaka.util.PublicPromise();
this.parsedPrftEventRaised_ = false;

for (const contentType of streamsByType.keys()) {
const stream = streamsByType.get(contentType);
Expand Down Expand Up @@ -838,8 +848,11 @@ shaka.media.MediaSourceEngine = class {
const Mp4Parser = shaka.util.Mp4Parser;
let startTime = 0;
let parsedMedia = false;
new Mp4Parser()
.box('moof', Mp4Parser.children)
const parser = new Mp4Parser();
if (!this.parsedPrftEventRaised_) {
parser.fullBox('prft', (box) => this.parsePrft_(timescale, box));
}
parser.box('moof', Mp4Parser.children)
.box('traf', Mp4Parser.children)
.fullBox('tfdt', (box) => {
goog.asserts.assert(
Expand Down Expand Up @@ -876,6 +889,48 @@ shaka.media.MediaSourceEngine = class {
return timestamp;
}

/**
* Parse PRFT box.
* @param {number} timescale
* @param {!shaka.extern.ParsedBox} box
* @private
*/
parsePrft_(timescale, box) {
goog.asserts.assert(
box.version == 0 || box.version == 1,
'PRFT version can only be 0 or 1');
const parsed = shaka.util.Mp4BoxParsers.parsePRFTInaccurate(
box.reader, box.version);

const wallClockTime = this.convertNtp_(parsed.ntpTimestamp);
const programStartDate = new Date(wallClockTime -
(parsed.mediaTime / timescale) * 1000);
const prftInfo = {
wallClockTime,
programStartDate,
};

const eventName = shaka.util.FakeEvent.EventName.Prft;
const data = (new Map()).set('detail', prftInfo);
const event = new shaka.util.FakeEvent(
eventName, data);
this.playerInterface_.onEvent(event);
this.parsedPrftEventRaised_ = true;
}


/**
* Convert Ntp ntpTimeStamp to UTC Time
*
* @param {number} ntpTimeStamp
* @return {number} utcTime
* @private
*/
convertNtp_(ntpTimeStamp) {
const start = new Date(Date.UTC(1900, 0, 1, 0, 0, 0));
return new Date(start.getTime() + ntpTimeStamp).getTime();
}

/**
* Enqueue an operation to append data to the SourceBuffer.
* Start and end times are needed for TextEngine, but not for MediaSource.
Expand Down Expand Up @@ -2234,7 +2289,8 @@ shaka.media.MediaSourceEngine.SourceBufferMode_ = {
/**
* @typedef {{
* getKeySystem: function():?string,
* onMetadata: function(!Array<shaka.extern.ID3Metadata>, number, ?number)
* onMetadata: function(!Array<shaka.extern.ID3Metadata>, number, ?number),
* onEvent: function(!Event)
* }}
*
* @summary Player interface
Expand All @@ -2243,5 +2299,7 @@ shaka.media.MediaSourceEngine.SourceBufferMode_ = {
* @property {function(
* !Array<shaka.extern.ID3Metadata>, number, ?number)} onMetadata
* Callback to use when metadata arrives.
* @property {function(!Event)} onEvent
* Called when an event occurs that should be sent to the app.
*/
shaka.media.MediaSourceEngine.PlayerInterface;
63 changes: 2 additions & 61 deletions lib/media/streaming_engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,6 @@ shaka.media.StreamingEngine = class {
/** @private {number} */
this.textStreamSequenceId_ = 0;

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

/**
* Maps a content type, e.g., 'audio', 'video', or 'text', to a MediaState.
*
Expand Down Expand Up @@ -2254,8 +2251,6 @@ shaka.media.StreamingEngine = class {
const hasEmsg = ((stream.emsgSchemeIdUris != null &&
stream.emsgSchemeIdUris.length > 0) ||
this.config_.dispatchAllEmsgBoxes);
const shouldParsePrftBox =
(this.config_.parsePrftBox && !this.parsedPrftEventRaised_);

const isMP4 = stream.mimeType == 'video/mp4' ||
stream.mimeType == 'audio/mp4';
Expand All @@ -2268,7 +2263,7 @@ shaka.media.StreamingEngine = class {
this.manifest_.type == shaka.media.ManifestParser.DASH &&
this.config_.shouldFixTimestampOffset;

if (hasEmsg || shouldParsePrftBox || shouldFixTimestampOffset) {
if (hasEmsg || shouldFixTimestampOffset) {
parser = new shaka.util.Mp4Parser();
}

Expand All @@ -2280,14 +2275,6 @@ shaka.media.StreamingEngine = class {
reference, stream.emsgSchemeIdUris, box));
}

if (shouldParsePrftBox) {
parser
.fullBox(
'prft',
(box) => this.parsePrft_(
reference, box));
}

if (shouldFixTimestampOffset) {
parser
.box('moof', shaka.util.Mp4Parser.children)
Expand Down Expand Up @@ -2326,7 +2313,7 @@ shaka.media.StreamingEngine = class {
});
}

if (hasEmsg || shouldParsePrftBox || shouldFixTimestampOffset) {
if (hasEmsg || shouldFixTimestampOffset) {
parser.parse(segment, /* partialOkay= */ false, isChunkedData);
}

Expand Down Expand Up @@ -2476,52 +2463,6 @@ shaka.media.StreamingEngine = class {
}
}

/**
* Parse PRFT box.
* @param {!shaka.media.SegmentReference} reference
* @param {!shaka.extern.ParsedBox} box
* @private
*/
parsePrft_(reference, box) {
if (this.parsedPrftEventRaised_ ||
!reference.initSegmentReference.timescale) {
return;
}
goog.asserts.assert(
box.version == 0 || box.version == 1,
'PRFT version can only be 0 or 1');
const parsed = shaka.util.Mp4BoxParsers.parsePRFTInaccurate(
box.reader, box.version);

const timescale = reference.initSegmentReference.timescale;
const wallClockTime = this.convertNtp(parsed.ntpTimestamp);
const programStartDate = new Date(wallClockTime -
(parsed.mediaTime / timescale) * 1000);
const prftInfo = {
wallClockTime,
programStartDate,
};

const eventName = shaka.util.FakeEvent.EventName.Prft;
const data = (new Map()).set('detail', prftInfo);
const event = new shaka.util.FakeEvent(
eventName, data);
this.playerInterface_.onEvent(event);
this.parsedPrftEventRaised_ = true;
}


/**
* Convert Ntp ntpTimeStamp to UTC Time
*
* @param {number} ntpTimeStamp
* @return {number} utcTime
*/
convertNtp(ntpTimeStamp) {
const start = new Date(Date.UTC(1900, 0, 1, 0, 0, 0));
return new Date(start.getTime() + ntpTimeStamp).getTime();
}

/**
* Evicts media to meet the max buffer behind limit.
*
Expand Down
9 changes: 9 additions & 0 deletions lib/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -2398,6 +2398,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
onMetadata: (metadata, offset, endTime) => {
this.processTimedMetadataMediaSrc_(metadata, offset, endTime);
},
onEvent: (event) => this.dispatchEvent(event),
},
this.lcevcDec_);
mediaSourceEngine.configure(this.config_.mediaSource);
Expand Down Expand Up @@ -3945,6 +3946,14 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
delete config['manifest']['hls']['useSafariBehaviorForLive'];
}

// Deprecate 'streaming.parsePrftBox' configuration.
if (config['streaming'] && 'parsePrftBox' in config['streaming']) {
shaka.Deprecate.deprecateFeature(5,
'streaming.parsePrftBox configuration',
'Now fired without needing a configuration.');
delete config['streaming']['parsePrftBox'];
}

// If lowLatencyMode is enabled, and inaccurateManifestTolerance and
// rebufferingGoal and segmentPrefetchLimit and baseDelay and
// autoCorrectDrift and maxDisabledTime are not specified, set
Expand Down
1 change: 0 additions & 1 deletion lib/util/player_configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ shaka.util.PlayerConfiguration = class {
dispatchAllEmsgBoxes: false,
observeQualityChanges: false,
maxDisabledTime: 30,
parsePrftBox: false,
// When low latency streaming is enabled, segmentPrefetchLimit will
// default to 2 if not specified.
segmentPrefetchLimit: 0,
Expand Down
1 change: 1 addition & 0 deletions test/cast/cast_utils_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ describe('CastUtils', () => {
{
getKeySystem: () => null,
onMetadata: () => {},
onEvent: () => {},
});
const config =
shaka.util.PlayerConfiguration.createDefault().mediaSource;
Expand Down
1 change: 1 addition & 0 deletions test/media/drm_engine_integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ describe('DrmEngine', () => {
{
getKeySystem: () => null,
onMetadata: () => {},
onEvent: () => {},
});
const mediaSourceConfig =
shaka.util.PlayerConfiguration.createDefault().mediaSource;
Expand Down
1 change: 1 addition & 0 deletions test/media/media_source_engine_integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ describe('MediaSourceEngine', () => {
{
getKeySystem: () => null,
onMetadata: shaka.test.Util.spyFunc(onMetadata),
onEvent: () => {},
});
const config = shaka.util.PlayerConfiguration.createDefault().mediaSource;
mediaSourceEngine.configure(config);
Expand Down
3 changes: 3 additions & 0 deletions test/media/media_source_engine_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ describe('MediaSourceEngine', () => {
{
getKeySystem: () => null,
onMetadata: () => {},
onEvent: () => {},
});
mediaSourceEngine.getCaptionParser = () => {
return mockClosedCaptionParser;
Expand Down Expand Up @@ -323,6 +324,7 @@ describe('MediaSourceEngine', () => {
{
getKeySystem: () => null,
onMetadata: () => {},
onEvent: () => {},
});

expect(createMediaSourceSpy).toHaveBeenCalled();
Expand All @@ -345,6 +347,7 @@ describe('MediaSourceEngine', () => {
{
getKeySystem: () => null,
onMetadata: () => {},
onEvent: () => {},
});

if (window.ManagedMediaSource) {
Expand Down
1 change: 1 addition & 0 deletions test/media/streaming_engine_integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ describe('StreamingEngine', () => {
{
getKeySystem: () => null,
onMetadata: () => {},
onEvent: () => {},
});
const mediaSourceConfig =
shaka.util.PlayerConfiguration.createDefault().mediaSource;
Expand Down
Loading

0 comments on commit fc4893d

Please sign in to comment.