diff --git a/demo/common/assets.js b/demo/common/assets.js index 743e7ca245..f758c191df 100644 --- a/demo/common/assets.js +++ b/demo/common/assets.js @@ -58,6 +58,10 @@ shakaAssets.AdTag = { 'single_ad_samples&ciu_szs=300x250&impl=s&gdfp_req=1&env=vp&output=vast&' + 'unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ct%' + '3Dlinear&correlator=', + SINGLE_NON_LINEAR_AD: 'https://pubads.g.doubleclick.net/gampad/ads?' + + 'sz=480x70&iu=/124319096/external/single_ad_samples&ciu_szs=300x250 ' + + '&impl=s&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1' + + '&cust_params=deployment%3Ddevsite%26sample_ct%3Dnonlinear&correlator=', SINGLE_SKIPPABLE_AD: 'https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/' + '124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&' + 'gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&cust_params=' + @@ -315,6 +319,20 @@ shakaAssets.testAssets = [ .addFeature(shakaAssets.Feature.SURROUND) .addFeature(shakaAssets.Feature.OFFLINE) .addLicenseServer('com.widevine.alpha', 'https://cwip-shaka-proxy.appspot.com/no_auth'), + new ShakaDemoAssetInfo( + /* name= */ 'Angel One (HLS, MP4, multilingual, Widevine, single non-linear ad)', + /* iconUri= */ 'https://storage.googleapis.com/shaka-asset-icons/angel_one.png', + /* manifestUri= */ 'https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine-hls/hls.m3u8', + /* source= */ shakaAssets.Source.SHAKA) + .addKeySystem(shakaAssets.KeySystem.WIDEVINE) + .setAdTagUri(shakaAssets.AdTag.SINGLE_NON_LINEAR_AD) + .addFeature(shakaAssets.Feature.HLS) + .addFeature(shakaAssets.Feature.MP4) + .addFeature(shakaAssets.Feature.MULTIPLE_LANGUAGES) + .addFeature(shakaAssets.Feature.SUBTITLES) + .addFeature(shakaAssets.Feature.SURROUND) + .addFeature(shakaAssets.Feature.OFFLINE) + .addLicenseServer('com.widevine.alpha', 'https://cwip-shaka-proxy.appspot.com/no_auth'), new ShakaDemoAssetInfo( /* name= */ 'Sintel 4k (multicodec)', /* iconUri= */ 'https://storage.googleapis.com/shaka-asset-icons/sintel.png', diff --git a/externs/ima.js b/externs/ima.js index 2ac3c5c57c..fa71e52d00 100644 --- a/externs/ima.js +++ b/externs/ima.js @@ -164,6 +164,9 @@ google.ima.Ad = class { /** @return {string} */ getAdvertiserName() {} + + /** @return {boolean} */ + isLinear() {} }; diff --git a/externs/shaka/ads.js b/externs/shaka/ads.js index e10940a7f9..079d8cd0cc 100644 --- a/externs/shaka/ads.js +++ b/externs/shaka/ads.js @@ -207,6 +207,11 @@ shaka.extern.IAd = class { */ setMuted(muted) {} + /** + * @return {boolean} + */ + isLinear() {} + /** * @param {number} width * @param {number} height diff --git a/lib/ads/client_side_ad.js b/lib/ads/client_side_ad.js index 66344ea48d..79e6e90692 100644 --- a/lib/ads/client_side_ad.js +++ b/lib/ads/client_side_ad.js @@ -162,6 +162,14 @@ shaka.ads.ClientSideAd = class { return this.manager_.getVolume() == 0; } + /** + * @override + * @export + */ + isLinear() { + return this.ad_.isLinear(); + } + /** * @override diff --git a/lib/ads/client_side_ad_manager.js b/lib/ads/client_side_ad_manager.js index dba2bd7f11..36deb84017 100644 --- a/lib/ads/client_side_ad_manager.js +++ b/lib/ads/client_side_ad_manager.js @@ -436,8 +436,10 @@ shaka.ads.ClientSideAdManager = class { 'sdkAdObject': imaAd, 'originalEvent': e, })); - this.adContainer_.setAttribute('ad-active', 'true'); - this.video_.pause(); + if (this.ad_.isLinear()) { + this.adContainer_.setAttribute('ad-active', 'true'); + this.video_.pause(); + } } /** @@ -447,7 +449,9 @@ shaka.ads.ClientSideAdManager = class { onAdComplete_(e) { this.onEvent_(new shaka.util.FakeEvent(shaka.ads.AdManager.AD_STOPPED, {'originalEvent': e})); - this.adContainer_.removeAttribute('ad-active'); - this.video_.play(); + if (this.ad_.isLinear()) { + this.adContainer_.removeAttribute('ad-active'); + this.video_.play(); + } } }; diff --git a/lib/ads/server_side_ad.js b/lib/ads/server_side_ad.js index 338489ad11..4935f852d0 100644 --- a/lib/ads/server_side_ad.js +++ b/lib/ads/server_side_ad.js @@ -152,6 +152,13 @@ shaka.ads.ServerSideAd = class { return this.video_.muted; } + /** + * @override + * @export + */ + isLinear() { + return true; + } /** * @override diff --git a/test/test/util/fake_ad.js b/test/test/util/fake_ad.js index 661b5c761c..6f42dfa0b9 100644 --- a/test/test/util/fake_ad.js +++ b/test/test/util/fake_ad.js @@ -154,6 +154,13 @@ shaka.test.FakeAd = class { } + /** + * @override + */ + isLinear() { + return true; + } + /** * @override */ diff --git a/ui/controls.js b/ui/controls.js index ae8cc9c12b..0b2c83f693 100644 --- a/ui/controls.js +++ b/ui/controls.js @@ -740,7 +740,8 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget { /** @private {!HTMLElement} */ this.adPanel_ = shaka.util.Dom.createHTMLElement('div'); this.adPanel_.classList.add('shaka-ad-controls'); - shaka.ui.Utils.setDisplay(this.adPanel_, this.ad_ != null); + const showAdPanel = this.ad_ != null && this.ad_.isLinear(); + shaka.ui.Utils.setDisplay(this.adPanel_, showAdPanel); this.bottomControls_.appendChild(this.adPanel_); const adPosition = new shaka.ui.AdPosition(this.adPanel_, this); @@ -884,7 +885,7 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget { /** - * Adds a container for server side ad UI with IMA SDK. + * Adds a container for client side ad UI with IMA SDK. * * @private */ @@ -893,6 +894,9 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget { this.clientAdContainer_ = shaka.util.Dom.createHTMLElement('div'); this.clientAdContainer_.classList.add('shaka-client-side-ad-container'); shaka.ui.Utils.setDisplay(this.clientAdContainer_, false); + this.eventManager_.listen(this.clientAdContainer_, 'click', () => { + this.onContainerClick_(); + }); this.videoContainer_.appendChild(this.clientAdContainer_); } @@ -1131,7 +1135,7 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget { // recent mouse movement, we're in keyboard navigation, or one of a special // class of elements is hovered. if (adIsPaused || - (!this.ad_ && videoIsPaused) || + ((!this.ad_ || !this.ad_.isLinear()) && videoIsPaused) || this.recentMouseMovement_ || keyboardNavigationMode || this.isHovered_()) { @@ -1182,7 +1186,7 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget { /** @private */ onPlayPauseClick_() { - if (this.ad_) { + if (this.ad_ && this.ad_.isLinear()) { this.playPauseAd(); } else { this.playPausePresentation(); diff --git a/ui/mute_button.js b/ui/mute_button.js index e84cc64303..ea85b3f978 100644 --- a/ui/mute_button.js +++ b/ui/mute_button.js @@ -49,7 +49,7 @@ shaka.ui.MuteButton = class extends shaka.ui.Element { }); this.eventManager.listen(this.button_, 'click', () => { - if (this.ad) { + if (this.ad && this.ad.isLinear()) { this.ad.setMuted(!this.ad.isMuted()); } else { this.video.muted = !this.video.muted; diff --git a/ui/overflow_menu.js b/ui/overflow_menu.js index df79ab1cb2..e0d2a41574 100644 --- a/ui/overflow_menu.js +++ b/ui/overflow_menu.js @@ -60,7 +60,9 @@ shaka.ui.OverflowMenu = class extends shaka.ui.Element { this.eventManager.listen( this.adManager, shaka.ads.AdManager.AD_STARTED, () => { - shaka.ui.Utils.setDisplay(this.overflowMenuButton_, false); + if (this.ad && this.ad.isLinear()) { + shaka.ui.Utils.setDisplay(this.overflowMenuButton_, false); + } }); this.eventManager.listen( @@ -89,7 +91,7 @@ shaka.ui.OverflowMenu = class extends shaka.ui.Element { this.updateAriaLabel_(); - if (this.ad) { + if (this.ad && this.ad.isLinear()) { // There was already an ad. shaka.ui.Utils.setDisplay(this.overflowMenuButton_, false); } diff --git a/ui/play_button.js b/ui/play_button.js index 2fa913b0c0..80778464d7 100644 --- a/ui/play_button.js +++ b/ui/play_button.js @@ -73,7 +73,7 @@ shaka.ui.PlayButton = class extends shaka.ui.Element { }); this.eventManager.listen(this.button, 'click', () => { - if (this.ad) { + if (this.ad && this.ad.isLinear()) { this.controls.playPauseAd(); } else { this.controls.playPausePresentation(); @@ -92,7 +92,7 @@ shaka.ui.PlayButton = class extends shaka.ui.Element { * @protected */ isPaused() { - if (this.ad) { + if (this.ad && this.ad.isLinear()) { return this.ad.isPaused(); } diff --git a/ui/seek_bar.js b/ui/seek_bar.js index c59a8e5499..1c35bd9b0c 100644 --- a/ui/seek_bar.js +++ b/ui/seek_bar.js @@ -95,7 +95,9 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement { this.eventManager.listen( this.adManager, shaka.ads.AdManager.AD_STARTED, () => { - shaka.ui.Utils.setDisplay(this.container, false); + if (!this.shouldBeDisplayed_()) { + shaka.ui.Utils.setDisplay(this.container, false); + } }); this.eventManager.listen( @@ -366,7 +368,7 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement { return false; } - return this.ad == null; + return this.ad == null || !this.ad.isLinear(); } /** @private */ diff --git a/ui/volume_bar.js b/ui/volume_bar.js index e73cb314ba..2cdf9fcd81 100644 --- a/ui/volume_bar.js +++ b/ui/volume_bar.js @@ -73,7 +73,7 @@ shaka.ui.VolumeBar = class extends shaka.ui.RangeElement { * @override */ onChange() { - if (this.ad) { + if (this.ad && this.ad.isLinear()) { this.ad.setVolume(this.getValue()); } else { this.video.volume = this.getValue();