Skip to content

Commit

Permalink
feat: Add callback for apps to pre-process DASH manifests (shaka-proj…
Browse files Browse the repository at this point in the history
…ect#3480)

Added support for efficient preprocessing of DASH manifest after they have been parsed into an XMLDocument

This is configured with the new manifest.dash.manifestPreprocessor setting.

This is need to efficiently repair manifests that are not compatible with Shaka Player.

Closes shaka-project#3339
  • Loading branch information
caridley committed Jun 22, 2021
1 parent 160e36b commit 9afa4eb
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 1 deletion.
7 changes: 6 additions & 1 deletion externs/shaka/player.js
Expand Up @@ -634,7 +634,8 @@ shaka.extern.DrmConfiguration;
* ignoreSuggestedPresentationDelay: boolean,
* ignoreEmptyAdaptationSet: boolean,
* ignoreMaxSegmentDuration: boolean,
* keySystemsByURI: !Object.<string, string>
* keySystemsByURI: !Object.<string, string>,
* manifestPreprocessor: function(!Element)
* }}
*
* @property {string} clockSyncUri
Expand Down Expand Up @@ -684,6 +685,10 @@ shaka.extern.DrmConfiguration;
* @property {Object.<string, string>} keySystemsByURI
* A map of scheme URI to key system name. Defaults to default key systems
* mapping handled by Shaka.
* @property {function(!Element)} manifestPreprocessor
* Called immediately after the DASH manifest has been parsed into an
* XMLDocument. Provides a way for applications to perform efficient
* preprocessing of the manifest.
* @exportDoc
*/
shaka.extern.DashManifestConfiguration;
Expand Down
5 changes: 5 additions & 0 deletions lib/dash/dash_parser.js
Expand Up @@ -289,6 +289,11 @@ shaka.dash.DashParser = class {
const Functional = shaka.util.Functional;
const XmlUtils = shaka.util.XmlUtils;

const manifestPreprocessor = this.config_.dash.manifestPreprocessor;
if (manifestPreprocessor) {
manifestPreprocessor(mpd);
}

// Get any Location elements. This will update the manifest location and
// the base URI.
/** @type {!Array.<string>} */
Expand Down
6 changes: 6 additions & 0 deletions lib/util/player_configuration.js
Expand Up @@ -109,6 +109,12 @@ shaka.util.PlayerConfiguration = class {
'urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb':
'com.adobe.primetime',
},
// Need some operation in the callback or else closure may remove calls
// to the function as it would be a no-op. The operation can't just be
// a log message, because those are stripped in the compiled build.
manifestPreprocessor: (element) => {
return element;
},
},
hls: {
ignoreTextStreamFailures: false,
Expand Down
42 changes: 42 additions & 0 deletions test/dash/dash_parser_manifest_unit.js
Expand Up @@ -1790,6 +1790,48 @@ describe('DashParser Manifest', () => {
expect(manifest.presentationTimeline).toBeTruthy();
});

it('Invokes manifestPreprocessor in config', async () => {
const manifestText = [
'<MPD minBufferTime="PT75S">',
' <Period id="1" duration="PT30S">',
' <AdaptationSet id="2" mimeType="video/mp4">',
' <Representation id="video-sd" width="640" height="480">',
' <BaseURL>v-sd.mp4</BaseURL>',
' <SegmentBase indexRange="100-200" />',
' </Representation>',
' </AdaptationSet>',
' <AdaptationSet id="3" mimeType="audio/mp4">',
' <Representation id="audio-en">',
' <BaseURL>a-en.mp4</BaseURL>',
' <SegmentBase indexRange="100-200" />',
' </Representation>',
' </AdaptationSet>',
' <AdaptationSet mimeType="text/vtt" lang="de">',
' <Representation>',
' <BaseURL>http://example.com/de.vtt</BaseURL>',
' </Representation>',
' </AdaptationSet>',
' </Period>',
'</MPD>',
].join('\n');

fakeNetEngine.setResponseText('dummy://foo', manifestText);
const config = shaka.util.PlayerConfiguration.createDefault().manifest;
config.dash.manifestPreprocessor = (mpd) => {
const selector = 'AdaptationSet[mimeType="text/vtt"';
const vttElements = mpd.querySelectorAll(selector);
for (const element of vttElements) {
element.parentNode.removeChild(element);
}
};
parser.configure(config);

/** @type {shaka.extern.Manifest} */
const manifest = await parser.start('dummy://foo', playerInterface);
const stream = manifest.textStreams[0];
expect(stream).toBeUndefined();
});

it('converts Accessibility element to "kind"', async () => {
const manifestText = [
'<MPD minBufferTime="PT75S">',
Expand Down

0 comments on commit 9afa4eb

Please sign in to comment.