diff --git a/demo/common/asset.js b/demo/common/asset.js index 8205db7918..c0579449f5 100644 --- a/demo/common/asset.js +++ b/demo/common/asset.js @@ -76,6 +76,8 @@ const ShakaDemoAssetInfo = class { /** @type {?string} */ this.imaContentSrcId = null; /** @type {?string} */ + this.imaManifestType = null; + /** @type {?string} */ this.mimeType = null; /** @type {?string} */ this.mediaPlaylistFullMimeType = null; @@ -267,6 +269,19 @@ const ShakaDemoAssetInfo = class { return this; } + /** + * @param {string} type + * @return {!ShakaDemoAssetInfo} + */ + setIMAManifestType(type) { + this.imaManifestType = type; + if (!this.features.includes(shakaAssets.Feature.ADS)) { + this.addFeature(shakaAssets.Feature.ADS); + } + + return this; + } + /** * @param {string} headerName * @param {string} headerValue diff --git a/demo/common/assets.js b/demo/common/assets.js index 861cd2e4fc..9b52e56f33 100644 --- a/demo/common/assets.js +++ b/demo/common/assets.js @@ -540,7 +540,8 @@ shakaAssets.testAssets = [ .addFeature(shakaAssets.Feature.MP4) .addFeature(shakaAssets.Feature.OFFLINE) .setIMAContentSourceId('2528370') - .setIMAVideoId('tears-of-steel'), + .setIMAVideoId('tears-of-steel') + .setIMAManifestType('HLS'), new ShakaDemoAssetInfo( /* name= */ 'Tears of Steel (live, DASH, Server Side ads)', /* iconUri= */ 'https://storage.googleapis.com/shaka-asset-icons/tears_of_steel.png', @@ -550,7 +551,8 @@ shakaAssets.testAssets = [ .addFeature(shakaAssets.Feature.MP4) .addFeature(shakaAssets.Feature.SUBTITLES) .addFeature(shakaAssets.Feature.LIVE) - .setIMAAssetKey('PSzZMzAkSXCmlJOWDmRj8Q'), + .setIMAAssetKey('PSzZMzAkSXCmlJOWDmRj8Q') + .setIMAManifestType('DASH'), new ShakaDemoAssetInfo( /* name= */ 'Tears of Steel (multicodec, surround + stereo)', /* iconUri= */ 'https://storage.googleapis.com/shaka-asset-icons/tears_of_steel.png', diff --git a/demo/common/message_ids.js b/demo/common/message_ids.js index 8aa7dc210a..c938b82673 100644 --- a/demo/common/message_ids.js +++ b/demo/common/message_ids.js @@ -102,6 +102,7 @@ shakaDemo.MessageIds = { ADS_TAB: 'DEMO_ADS_TAB', IMA_ASSET_KEY: 'DEMO_IMA_ASSET_KEY', IMA_CONTENT_SRC_ID: 'DEMO_IMA_CONTENT_SRC_ID', + IMA_MANIFEST_TYPE: 'DEMO_IMA_MANIFEST_TYPE', IMA_VIDEO_ID: 'DEMO_IMA_VIDEO_ID', CANCEL_BUTTON: 'DEMO_CANCEL_BUTTON', CUSTOM_INTRO_ONE: 'DEMO_CUSTOM_INTRO_ONE', diff --git a/demo/custom.js b/demo/custom.js index 0255425207..1267cd8e25 100644 --- a/demo/custom.js +++ b/demo/custom.js @@ -362,6 +362,25 @@ shakaDemo.Custom = class { this.makeField_( container, assetKeyName, assetKeySetup, assetKeyChange); + // Make the manifest type field. + const manifestTypeSetup = (input, container) => { + if (assetInProgress.imaManifestType) { + input.value = assetInProgress.imaManifestType; + } + + this.manifestField_.required = + this.checkManifestRequired_(assetInProgress); + }; + const manifestTypeChange = (input) => { + assetInProgress.imaManifestType = input.value; + this.manifestField_.required = + this.checkManifestRequired_(assetInProgress); + }; + const manifestTypeName = shakaDemoMain.getLocalizedString( + shakaDemo.MessageIds.IMA_MANIFEST_TYPE); + this.makeField_( + container, manifestTypeName, manifestTypeSetup, manifestTypeChange); + return adsDiv; } diff --git a/demo/locales/en.json b/demo/locales/en.json index ad59d5567d..8e529baeab 100644 --- a/demo/locales/en.json +++ b/demo/locales/en.json @@ -107,6 +107,7 @@ "DEMO_IGNORE_HLS_TEXT_FAILURES": "Ignore HLS Text Stream Failures", "DEMO_IMA_ASSET_KEY": "Asset key (for LIVE DAI Content)", "DEMO_IMA_CONTENT_SRC_ID": "Content source ID (for VOD DAI Content)", + "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_MIN_BUFFER_TIME": "Ignore Min Buffer Time", diff --git a/demo/locales/source.json b/demo/locales/source.json index fcfdbcc634..1069b210a5 100644 --- a/demo/locales/source.json +++ b/demo/locales/source.json @@ -435,6 +435,10 @@ "description": "The label on a field that allows users to provide a content source id for a custom asset.", "message": "Asset key (for VOD DAI Content)" }, + "DEMO_IMA_MANIFEST_TYPE": { + "description": "The label on a field that allows users to provide a manifest type for a custom asset.", + "message": "Manifest type (for DAI Content)" + }, "DEMO_IMA_VIDEO_ID": { "description": "The label on a field that allows users to provide a video id for a custom asset.", "message": "Video ID (for VOD DAI Content)" diff --git a/demo/main.js b/demo/main.js index 15f809bf9f..d35830cd1e 100644 --- a/demo/main.js +++ b/demo/main.js @@ -1561,6 +1561,20 @@ shakaDemo.Main = class { request.contentSourceId = asset.imaContentSrcId; request.videoId = asset.imaVideoId; } + switch (asset.imaManifestType) { + case 'DASH': + case 'dash': + case 'MPD': + case 'mpd': + request.format = google.ima.dai.api.StreamRequest.StreamFormat.DASH; + break; + case 'HLS': + case 'hls': + case 'M3U8': + case 'm3u8': + request.format = google.ima.dai.api.StreamRequest.StreamFormat.HLS; + break; + } const uri = await adManager.requestServerSideStream( request, /* backupUri= */ asset.manifestUri); diff --git a/externs/ima.js b/externs/ima.js index 456f5e7628..0b1e755095 100644 --- a/externs/ima.js +++ b/externs/ima.js @@ -513,6 +513,15 @@ google.ima.dai.api.StreamRequest.prototype.streamActivityMonitorId; google.ima.dai.api.StreamRequest.prototype.format; +/** + * @enum {string} + */ +google.ima.dai.api.StreamRequest.StreamFormat = { + DASH: 'dash', + HLS: 'hls', +}; + + /** @const */ google.ima.dai.api.VODStreamRequest = class extends google.ima.dai.api.StreamRequest {};