diff --git a/build/types/ads b/build/types/ads index f6a42cd2e..2bd1bfc68 100644 --- a/build/types/ads +++ b/build/types/ads @@ -1,5 +1,6 @@ # Ad Insertion Functionality ++../../lib/ads/abstract_ad.js +../../lib/ads/ad_manager.js +../../lib/ads/ad_utils.js +../../lib/ads/ads_stats.js diff --git a/lib/ads/abstract_ad.js b/lib/ads/abstract_ad.js new file mode 100755 index 000000000..792809eeb --- /dev/null +++ b/lib/ads/abstract_ad.js @@ -0,0 +1,277 @@ +/*! @license + * Shaka Player + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + + +goog.provide('shaka.ads.AbstractAd'); + +/** + * @abstract + * @implements {shaka.extern.IAd} + * @export + */ +shaka.ads.AbstractAd = class { + /** + * @param {HTMLMediaElement=} video + */ + constructor(video = null) { + /** @protected {HTMLMediaElement} */ + this.video = video; + } + + /** + * @override + */ + needsSkipUI() { + return true; + } + + /** + * @override + */ + isClientRendering() { + return true; + } + + /** + * @override + */ + hasCustomClick() { + return false; + } + + /** + * @override + */ + isUsingAnotherMediaElement() { + return false; + } + + /** + * @override + */ + getDuration() { + return -1; + } + + /** + * @override + */ + getMinSuggestedDuration() { + return this.getDuration(); + } + + /** + * @override + */ + getRemainingTime() { + return -1; + } + + /** + * @override + */ + isPaused() { + return this.video ? this.video.paused : false; + } + + /** + * @override + */ + isSkippable() { + return false; + } + + /** + * @override + */ + getTimeUntilSkippable() { + return 0; + } + + /** + * @override + */ + canSkipNow() { + return false; + } + + /** + * @override + */ + skip() { + // Nothing + } + + /** + * @override + */ + pause() { + if (this.video) { + this.video.pause(); + } + } + + /** + * @override + */ + play() { + if (this.video) { + this.video.play(); + } + } + + /** + * @override + */ + getVolume() { + return this.video ? this.video.volume : 1; + } + + /** + * @override + */ + setVolume(volume) { + if (this.video) { + this.video.volume = volume; + } + } + + /** + * @override + */ + isMuted() { + return this.video ? this.video.muted : false; + } + + /** + * @override + */ + isLinear() { + return true; + } + + /** + * @override + */ + resize(width, height) { + // Nothing + } + + /** + * @override + */ + setMuted(muted) { + if (this.video) { + this.video.muted = muted; + } + } + + + /** + * @override + */ + getSequenceLength() { + return 1; + } + + /** + * @override + */ + getPositionInSequence() { + return 1; + } + + /** + * @override + */ + getTitle() { + return ''; + } + + /** + * @override + */ + getDescription() { + return ''; + } + + /** + * @override + */ + getVastMediaBitrate() { + return 0; + } + + /** + * @override + */ + getVastMediaHeight() { + return 0; + } + + /** + * @override + */ + getVastMediaWidth() { + return 0; + } + + /** + * @override + */ + getVastAdId() { + return ''; + } + + /** + * @override + */ + getAdId() { + return ''; + } + + /** + * @override + */ + getCreativeAdId() { + return ''; + } + + /** + * @override + */ + getAdvertiserName() { + return ''; + } + + /** + * @override + */ + getMediaUrl() { + return null; + } + + /** + * @override + */ + getTimeOffset() { + return 0; + } + + /** + * @override + */ + getPodIndex() { + return 0; + } + + /** + * @override + */ + release() { + this.video = null; + } +}; diff --git a/lib/ads/client_side_ad.js b/lib/ads/client_side_ad.js index dc4d60c42..02509d7da 100644 --- a/lib/ads/client_side_ad.js +++ b/lib/ads/client_side_ad.js @@ -7,28 +7,28 @@ goog.provide('shaka.ads.ClientSideAd'); +goog.require('shaka.ads.AbstractAd'); goog.require('shaka.util.EventManager'); /** - * @implements {shaka.extern.IAd} * @export */ -shaka.ads.ClientSideAd = class { +shaka.ads.ClientSideAd = class extends shaka.ads.AbstractAd { /** * @param {!google.ima.Ad} imaAd * @param {!google.ima.AdsManager} imaAdManager * @param {HTMLMediaElement} video */ constructor(imaAd, imaAdManager, video) { + super(video); + /** @private {google.ima.Ad} */ this.ad_ = imaAd; /** @private {google.ima.AdsManager} */ this.manager_ = imaAdManager; - /** @private {HTMLMediaElement} */ - this.video_ = video; /** @private {boolean} */ this.isPaused_ = false; @@ -52,7 +52,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ needsSkipUI() { return false; @@ -60,15 +59,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export - */ - isClientRendering() { - return true; - } - - /** - * @override - * @export */ hasCustomClick() { return true; @@ -76,7 +66,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ isUsingAnotherMediaElement() { return true; @@ -84,7 +73,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getDuration() { return this.ad_.getDuration(); @@ -92,7 +80,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getMinSuggestedDuration() { return this.ad_.getMinSuggestedDuration(); @@ -100,7 +87,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getRemainingTime() { return this.manager_.getRemainingTime(); @@ -108,7 +94,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ isPaused() { return this.isPaused_; @@ -116,7 +101,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ isSkippable() { // IMA returns -1 for non-skippable ads. Any positive number is a genuine @@ -126,7 +110,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getTimeUntilSkippable() { const skipOffset = this.ad_.getSkipTimeOffset(); @@ -136,7 +119,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ canSkipNow() { return this.manager_.getAdSkippableState(); @@ -144,7 +126,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ skip() { return this.manager_.skip(); @@ -159,7 +140,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ pause() { return this.manager_.pause(); @@ -167,7 +147,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ play() { return this.manager_.resume(); @@ -176,7 +155,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getVolume() { return this.manager_.getVolume(); @@ -184,16 +162,14 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ setVolume(volume) { - this.video_.volume = volume; + this.video.volume = volume; return this.manager_.setVolume(volume); } /** * @override - * @export */ isMuted() { return this.manager_.getVolume() == 0; @@ -201,7 +177,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ isLinear() { return this.ad_.isLinear(); @@ -210,7 +185,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ resize(width, height) { this.manager_.resize(width, height); @@ -218,10 +192,9 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ setMuted(muted) { - this.video_.muted = muted; + this.video.muted = muted; // Emulate the "mute" functionality, where current, pre-mute // volume is saved and can be restored on unmute. if (muted) { @@ -244,7 +217,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getSequenceLength() { const podInfo = this.ad_.getAdPodInfo(); @@ -258,7 +230,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getPositionInSequence() { const podInfo = this.ad_.getAdPodInfo(); @@ -272,7 +243,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getTitle() { return this.ad_.getTitle(); @@ -280,7 +250,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getDescription() { return this.ad_.getDescription(); @@ -288,7 +257,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getVastMediaBitrate() { return this.ad_.getVastMediaBitrate(); @@ -296,7 +264,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getVastMediaHeight() { return this.ad_.getVastMediaHeight(); @@ -304,7 +271,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getVastMediaWidth() { return this.ad_.getVastMediaWidth(); @@ -312,15 +278,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export - */ - getVastAdId() { - return ''; - } - - /** - * @override - * @export */ getAdId() { return this.ad_.getAdId(); @@ -328,7 +285,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getCreativeAdId() { return this.ad_.getCreativeAdId(); @@ -336,7 +292,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getAdvertiserName() { return this.ad_.getAdvertiserName(); @@ -344,7 +299,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getMediaUrl() { return this.ad_.getMediaUrl(); @@ -352,7 +306,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getTimeOffset() { const podInfo = this.ad_.getAdPodInfo(); @@ -367,7 +320,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ getPodIndex() { const podInfo = this.ad_.getAdPodInfo(); @@ -382,7 +334,6 @@ shaka.ads.ClientSideAd = class { /** * @override - * @export */ release() { this.ad_ = null; diff --git a/lib/ads/interstitial_ad.js b/lib/ads/interstitial_ad.js index 4fd6a7062..90ea393a0 100755 --- a/lib/ads/interstitial_ad.js +++ b/lib/ads/interstitial_ad.js @@ -7,11 +7,12 @@ goog.provide('shaka.ads.InterstitialAd'); +goog.require('shaka.ads.AbstractAd'); + /** - * @implements {shaka.extern.IAd} * @export */ -shaka.ads.InterstitialAd = class { +shaka.ads.InterstitialAd = class extends shaka.ads.AbstractAd { /** * @param {HTMLMediaElement} video * @param {shaka.extern.AdInterstitial} interstitial @@ -22,8 +23,7 @@ shaka.ads.InterstitialAd = class { */ constructor(video, interstitial, onSkip, sequenceLength, adPosition, isUsingAnotherMediaElement) { - /** @private {HTMLMediaElement} */ - this.video_ = video; + super(video); /** @private {shaka.extern.AdInterstitial} */ this.interstitial_ = interstitial; @@ -56,23 +56,6 @@ shaka.ads.InterstitialAd = class { /** * @override - * @export - */ - needsSkipUI() { - return true; - } - - /** - * @override - * @export - */ - isClientRendering() { - return true; - } - - /** - * @override - * @export */ hasCustomClick() { return this.interstitial_.clickThroughUrl != null; @@ -80,7 +63,6 @@ shaka.ads.InterstitialAd = class { /** * @override - * @export */ isUsingAnotherMediaElement() { return this.isUsingAnotherMediaElement_; @@ -88,10 +70,9 @@ shaka.ads.InterstitialAd = class { /** * @override - * @export */ getDuration() { - const duration = this.video_.duration; + const duration = this.video.duration; if (isNaN(duration)) { return -1; } @@ -100,35 +81,17 @@ shaka.ads.InterstitialAd = class { /** * @override - * @export - */ - getMinSuggestedDuration() { - return this.getDuration(); - } - - /** - * @override - * @export */ getRemainingTime() { - const duration = this.video_.duration; + const duration = this.video.duration; if (isNaN(duration)) { return -1; } - return duration - this.video_.currentTime; + return duration - this.video.currentTime; } /** * @override - * @export - */ - isPaused() { - return this.video_.paused; - } - - /** - * @override - * @export */ isSkippable() { if (this.isSkippable_ && this.skipFor_ != null) { @@ -141,7 +104,6 @@ shaka.ads.InterstitialAd = class { /** * @override - * @export */ getTimeUntilSkippable() { if (this.isSkippable()) { @@ -154,7 +116,6 @@ shaka.ads.InterstitialAd = class { /** * @override - * @export */ canSkipNow() { return this.isSkippable_ && this.getTimeUntilSkippable() == 0; @@ -162,7 +123,6 @@ shaka.ads.InterstitialAd = class { /** * @override - * @export */ skip() { if (this.canSkipNow()) { @@ -172,73 +132,14 @@ shaka.ads.InterstitialAd = class { /** * @override - * @export - */ - pause() { - return this.video_.pause(); - } - - /** - * @override - * @export - */ - play() { - return this.video_.play(); - } - - - /** - * @override - * @export - */ - getVolume() { - return this.video_.volume; - } - - /** - * @override - * @export - */ - setVolume(volume) { - this.video_.volume = volume; - } - - /** - * @override - * @export - */ - isMuted() { - return this.video_.muted; - } - - /** - * @override - * @export */ isLinear() { return this.overlay_ == null; } - /** - * @override - * @export - */ - resize(width, height) { - // Nothing - } /** * @override - * @export - */ - setMuted(muted) { - this.video_.muted = muted; - } - - - /** - * @override - * @export */ getSequenceLength() { return this.sequenceLength_; @@ -246,7 +147,6 @@ shaka.ads.InterstitialAd = class { /** * @override - * @export */ getPositionInSequence() { return this.adPosition_; @@ -254,55 +154,6 @@ shaka.ads.InterstitialAd = class { /** * @override - * @export - */ - getTitle() { - return ''; - } - - /** - * @override - * @export - */ - getDescription() { - return ''; - } - - /** - * @override - * @export - */ - getVastMediaBitrate() { - return 0; - } - - /** - * @override - * @export - */ - getVastMediaHeight() { - return 0; - } - - /** - * @override - * @export - */ - getVastMediaWidth() { - return 0; - } - - /** - * @override - * @export - */ - getVastAdId() { - return ''; - } - - /** - * @override - * @export */ getAdId() { return this.interstitial_.id || ''; @@ -310,23 +161,6 @@ shaka.ads.InterstitialAd = class { /** * @override - * @export - */ - getCreativeAdId() { - return ''; - } - - /** - * @override - * @export - */ - getAdvertiserName() { - return ''; - } - - /** - * @override - * @export */ getMediaUrl() { return this.interstitial_.uri; @@ -334,7 +168,6 @@ shaka.ads.InterstitialAd = class { /** * @override - * @export */ getTimeOffset() { if (this.interstitial_.pre) { @@ -344,20 +177,4 @@ shaka.ads.InterstitialAd = class { } return this.interstitial_.startTime; } - - /** - * @override - * @export - */ - getPodIndex() { - return 0; - } - - /** - * @override - * @export - */ - release() { - this.video_ = null; - } }; diff --git a/lib/ads/interstitial_static_ad.js b/lib/ads/interstitial_static_ad.js index 7f519d872..93ab1b84f 100644 --- a/lib/ads/interstitial_static_ad.js +++ b/lib/ads/interstitial_static_ad.js @@ -7,17 +7,20 @@ goog.provide('shaka.ads.InterstitialStaticAd'); +goog.require('shaka.ads.AbstractAd'); + /** - * @implements {shaka.extern.IAd} * @export */ -shaka.ads.InterstitialStaticAd = class { +shaka.ads.InterstitialStaticAd = class extends shaka.ads.AbstractAd { /** * @param {shaka.extern.AdInterstitial} interstitial * @param {number} sequenceLength * @param {number} adPosition */ constructor(interstitial, sequenceLength, adPosition) { + super(); + /** @private {shaka.extern.AdInterstitial} */ this.interstitial_ = interstitial; @@ -33,23 +36,6 @@ shaka.ads.InterstitialStaticAd = class { /** * @override - * @export - */ - needsSkipUI() { - return true; - } - - /** - * @override - * @export - */ - isClientRendering() { - return true; - } - - /** - * @override - * @export */ hasCustomClick() { return this.interstitial_.clickThroughUrl != null; @@ -57,145 +43,14 @@ shaka.ads.InterstitialStaticAd = class { /** * @override - * @export - */ - isUsingAnotherMediaElement() { - return false; - } - - /** - * @override - * @export - */ - getDuration() { - return -1; - } - - /** - * @override - * @export - */ - getMinSuggestedDuration() { - return this.getDuration(); - } - - /** - * @override - * @export - */ - getRemainingTime() { - return -1; - } - - /** - * @override - * @export - */ - isPaused() { - return false; - } - - /** - * @override - * @export - */ - isSkippable() { - return false; - } - - /** - * @override - * @export - */ - getTimeUntilSkippable() { - return 0; - } - - /** - * @override - * @export - */ - canSkipNow() { - return false; - } - - /** - * @override - * @export - */ - skip() { - // Nothing - } - - /** - * @override - * @export - */ - pause() { - // Nothing - } - - /** - * @override - * @export - */ - play() { - // Nothing - } - - - /** - * @override - * @export - */ - getVolume() { - return 1; - } - - /** - * @override - * @export - */ - setVolume(volume) { - // Nothing - } - - /** - * @override - * @export - */ - isMuted() { - return false; - } - - /** - * @override - * @export */ isLinear() { return this.isLinear_; } - /** - * @override - * @export - */ - resize(width, height) { - // Nothing - } /** * @override - * @export - */ - setMuted(muted) { - // Nothing - } - - - /** - * @override - * @export */ getSequenceLength() { return this.sequenceLength_; @@ -203,7 +58,6 @@ shaka.ads.InterstitialStaticAd = class { /** * @override - * @export */ getPositionInSequence() { return this.adPosition_; @@ -211,55 +65,6 @@ shaka.ads.InterstitialStaticAd = class { /** * @override - * @export - */ - getTitle() { - return ''; - } - - /** - * @override - * @export - */ - getDescription() { - return ''; - } - - /** - * @override - * @export - */ - getVastMediaBitrate() { - return 0; - } - - /** - * @override - * @export - */ - getVastMediaHeight() { - return 0; - } - - /** - * @override - * @export - */ - getVastMediaWidth() { - return 0; - } - - /** - * @override - * @export - */ - getVastAdId() { - return ''; - } - - /** - * @override - * @export */ getAdId() { return this.interstitial_.id || ''; @@ -267,23 +72,6 @@ shaka.ads.InterstitialStaticAd = class { /** * @override - * @export - */ - getCreativeAdId() { - return ''; - } - - /** - * @override - * @export - */ - getAdvertiserName() { - return ''; - } - - /** - * @override - * @export */ getMediaUrl() { return this.interstitial_.uri; @@ -291,7 +79,6 @@ shaka.ads.InterstitialStaticAd = class { /** * @override - * @export */ getTimeOffset() { if (this.interstitial_.pre) { @@ -301,20 +88,4 @@ shaka.ads.InterstitialStaticAd = class { } return this.interstitial_.startTime; } - - /** - * @override - * @export - */ - getPodIndex() { - return 0; - } - - /** - * @override - * @export - */ - release() { - // Nothing - } }; diff --git a/lib/ads/media_tailor_ad.js b/lib/ads/media_tailor_ad.js index 87234e632..36c67d853 100755 --- a/lib/ads/media_tailor_ad.js +++ b/lib/ads/media_tailor_ad.js @@ -7,13 +7,13 @@ goog.provide('shaka.ads.MediaTailorAd'); +goog.require('shaka.ads.AbstractAd'); goog.require('shaka.util.TextParser'); /** - * @implements {shaka.extern.IAd} * @export */ -shaka.ads.MediaTailorAd = class { +shaka.ads.MediaTailorAd = class extends shaka.ads.AbstractAd { /** * @param {mediaTailor.Ad} mediaTailorAd * @param {number} adPosition @@ -22,15 +22,14 @@ shaka.ads.MediaTailorAd = class { * @param {HTMLMediaElement} video */ constructor(mediaTailorAd, adPosition, totalAds, isLinear, video) { + super(video); + /** @private {?mediaTailor.Ad} */ this.ad_ = mediaTailorAd; /** @private {?number} */ this.skipOffset_ = shaka.util.TextParser.parseTime(this.ad_.skipOffset); - /** @private {HTMLMediaElement} */ - this.video_ = video; - /** @private {?number} */ this.adPosition_ = adPosition; @@ -46,15 +45,6 @@ shaka.ads.MediaTailorAd = class { /** * @override - * @export - */ - needsSkipUI() { - return true; - } - - /** - * @override - * @export */ isClientRendering() { return false; @@ -62,23 +52,6 @@ shaka.ads.MediaTailorAd = class { /** * @override - * @export - */ - hasCustomClick() { - return false; - } - - /** - * @override - * @export - */ - isUsingAnotherMediaElement() { - return false; - } - - /** - * @override - * @export */ getDuration() { return this.ad_.durationInSeconds; @@ -86,32 +59,14 @@ shaka.ads.MediaTailorAd = class { /** * @override - * @export - */ - getMinSuggestedDuration() { - return this.getDuration(); - } - - /** - * @override - * @export */ getRemainingTime() { const endTime = this.ad_.startTimeInSeconds + this.ad_.durationInSeconds; - return endTime - this.video_.currentTime; + return endTime - this.video.currentTime; } /** * @override - * @export - */ - isPaused() { - return this.video_.paused; - } - - /** - * @override - * @export */ isSkippable() { if (typeof this.skipOffset_ == 'number') { @@ -122,7 +77,6 @@ shaka.ads.MediaTailorAd = class { /** * @override - * @export */ getTimeUntilSkippable() { if (typeof this.skipOffset_ != 'number') { @@ -135,7 +89,6 @@ shaka.ads.MediaTailorAd = class { /** * @override - * @export */ canSkipNow() { return this.getTimeUntilSkippable() == 0; @@ -143,82 +96,22 @@ shaka.ads.MediaTailorAd = class { /** * @override - * @export */ skip() { this.isSkipped_ = true; - this.video_.currentTime += this.getRemainingTime(); + this.video.currentTime += this.getRemainingTime(); } /** * @override - * @export - */ - pause() { - return this.video_.pause(); - } - - /** - * @override - * @export - */ - play() { - return this.video_.play(); - } - - - /** - * @override - * @export - */ - getVolume() { - return this.video_.volume; - } - - /** - * @override - * @export - */ - setVolume(volume) { - this.video_.volume = volume; - } - - /** - * @override - * @export - */ - isMuted() { - return this.video_.muted; - } - - /** - * @override - * @export */ isLinear() { return this.isLinear_; } - /** - * @override - * @export - */ - resize(width, height) { - // Nothing - } /** * @override - * @export - */ - setMuted(muted) { - this.video_.muted = muted; - } - - - /** - * @override - * @export */ getSequenceLength() { if (!this.totalAds_) { @@ -229,7 +122,6 @@ shaka.ads.MediaTailorAd = class { /** * @override - * @export */ getPositionInSequence() { if (!this.adPosition_) { @@ -240,7 +132,6 @@ shaka.ads.MediaTailorAd = class { /** * @override - * @export */ getTitle() { return this.ad_.adTitle; @@ -248,39 +139,6 @@ shaka.ads.MediaTailorAd = class { /** * @override - * @export - */ - getDescription() { - return ''; - } - - /** - * @override - * @export - */ - getVastMediaBitrate() { - return 0; - } - - /** - * @override - * @export - */ - getVastMediaHeight() { - return 0; - } - - /** - * @override - * @export - */ - getVastMediaWidth() { - return 0; - } - - /** - * @override - * @export */ getVastAdId() { return this.ad_.vastAdId || ''; @@ -288,7 +146,6 @@ shaka.ads.MediaTailorAd = class { /** * @override - * @export */ getAdId() { return this.ad_.adId; @@ -296,7 +153,6 @@ shaka.ads.MediaTailorAd = class { /** * @override - * @export */ getCreativeAdId() { return this.ad_.creativeId; @@ -304,43 +160,16 @@ shaka.ads.MediaTailorAd = class { /** * @override - * @export - */ - getAdvertiserName() { - return ''; - } - - /** - * @override - * @export - */ - getMediaUrl() { - return null; - } - - /** - * @override - * @export */ getTimeOffset() { - return 0; + return this.ad_.startTimeInSeconds; } /** * @override - * @export - */ - getPodIndex() { - return 0; - } - - /** - * @override - * @export */ release() { this.ad_ = null; - this.video_ = null; this.adPosition_ = null; this.totalAds_ = null; } diff --git a/lib/ads/server_side_ad.js b/lib/ads/server_side_ad.js index 001206852..5032612fa 100644 --- a/lib/ads/server_side_ad.js +++ b/lib/ads/server_side_ad.js @@ -7,24 +7,24 @@ goog.provide('shaka.ads.ServerSideAd'); +goog.require('shaka.ads.AbstractAd'); + /** - * @implements {shaka.extern.IAd} * @export */ -shaka.ads.ServerSideAd = class { +shaka.ads.ServerSideAd = class extends shaka.ads.AbstractAd { /** * @param {google.ima.dai.api.Ad} imaAd * @param {HTMLMediaElement} video */ constructor(imaAd, video) { + super(video); + /** @private {google.ima.dai.api.Ad} */ this.ad_ = imaAd; /** @private {?google.ima.dai.api.AdProgressData} */ this.adProgressData_ = null; - - /** @private {HTMLMediaElement} */ - this.video_ = video; } @@ -37,15 +37,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export - */ - needsSkipUI() { - return true; - } - - /** - * @override - * @export */ isClientRendering() { return false; @@ -53,7 +44,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export */ hasCustomClick() { return true; @@ -61,15 +51,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export - */ - isUsingAnotherMediaElement() { - return false; - } - - /** - * @override - * @export */ getDuration() { if (!this.adProgressData_) { @@ -81,15 +62,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export - */ - getMinSuggestedDuration() { - return this.getDuration(); - } - - /** - * @override - * @export */ getRemainingTime() { if (!this.adProgressData_) { @@ -102,15 +74,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export - */ - isPaused() { - return this.video_.paused; - } - - /** - * @override - * @export */ isSkippable() { return this.ad_.isSkippable(); @@ -118,7 +81,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export */ getTimeUntilSkippable() { const skipOffset = this.ad_.getSkipTimeOffset(); @@ -128,7 +90,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export */ canSkipNow() { return this.getTimeUntilSkippable() == 0; @@ -136,81 +97,14 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export */ skip() { - this.video_.currentTime += this.getRemainingTime(); - } - - /** - * @override - * @export - */ - pause() { - return this.video_.pause(); - } - - /** - * @override - * @export - */ - play() { - return this.video_.play(); + this.video.currentTime += this.getRemainingTime(); } /** * @override - * @export - */ - getVolume() { - return this.video_.volume; - } - - /** - * @override - * @export - */ - setVolume(volume) { - this.video_.volume = volume; - } - - /** - * @override - * @export - */ - isMuted() { - return this.video_.muted; - } - - /** - * @override - * @export - */ - isLinear() { - return true; - } - - /** - * @override - * @export - */ - resize(width, height) { - // Nothing - } - - /** - * @override - * @export - */ - setMuted(muted) { - this.video_.muted = muted; - } - - - /** - * @override - * @export */ getSequenceLength() { const podInfo = this.ad_.getAdPodInfo(); @@ -224,7 +118,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export */ getPositionInSequence() { const podInfo = this.ad_.getAdPodInfo(); @@ -238,7 +131,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export */ getTitle() { return this.ad_.getTitle(); @@ -246,7 +138,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export */ getDescription() { return this.ad_.getDescription(); @@ -254,15 +145,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export - */ - getVastMediaBitrate() { - return 0; - } - - /** - * @override - * @export */ getVastMediaHeight() { return this.ad_.getVastMediaHeight(); @@ -270,7 +152,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export */ getVastMediaWidth() { return this.ad_.getVastMediaWidth(); @@ -278,15 +159,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export - */ - getVastAdId() { - return ''; - } - - /** - * @override - * @export */ getAdId() { return this.ad_.getAdId(); @@ -294,7 +166,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export */ getCreativeAdId() { return this.ad_.getCreativeAdId(); @@ -302,7 +173,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export */ getAdvertiserName() { return this.ad_.getAdvertiserName(); @@ -310,15 +180,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export - */ - getMediaUrl() { - return null; - } - - /** - * @override - * @export */ getTimeOffset() { const podInfo = this.ad_.getAdPodInfo(); @@ -333,7 +194,6 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export */ getPodIndex() { const podInfo = this.ad_.getAdPodInfo(); @@ -348,11 +208,9 @@ shaka.ads.ServerSideAd = class { /** * @override - * @export */ release() { this.ad_ = null; this.adProgressData_ = null; - this.video_ = null; } }; diff --git a/lib/ads/svta_ad.js b/lib/ads/svta_ad.js index 134d0946d..60d2ff4d0 100644 --- a/lib/ads/svta_ad.js +++ b/lib/ads/svta_ad.js @@ -7,35 +7,25 @@ goog.provide('shaka.ads.SvtaAd'); -goog.require('goog.asserts'); +goog.require('shaka.ads.AbstractAd'); /** - * @implements {shaka.extern.IAd} * @export */ -shaka.ads.SvtaAd = class { +shaka.ads.SvtaAd = class extends shaka.ads.AbstractAd { /** * @param {HTMLMediaElement} video * @param {shaka.extern.AdTrackingInfo} info */ constructor(video, info) { - /** @private {HTMLMediaElement} */ - this.video_ = video; + super(video); + /** @private {shaka.extern.AdTrackingInfo} */ this.info_ = info; } /** * @override - * @export - */ - needsSkipUI() { - return true; - } - - /** - * @override - * @export */ isClientRendering() { return false; @@ -43,155 +33,26 @@ shaka.ads.SvtaAd = class { /** * @override - * @export - */ - hasCustomClick() { - return false; - } - - /** - * @override - * @export - */ - isUsingAnotherMediaElement() { - return false; - } - - /** - * @override - * @export */ getDuration() { - goog.asserts.assert(this.info_.endTime, 'endTime must not be null!'); + if (!this.info_.endTime) { + return -1; + } return this.info_.endTime - this.info_.startTime; } /** * @override - * @export - */ - getMinSuggestedDuration() { - return this.getDuration(); - } - - /** - * @override - * @export */ getRemainingTime() { - goog.asserts.assert(this.info_.endTime, 'endTime must not be null!'); - return this.info_.endTime - this.video_.currentTime; + if (!this.info_.endTime) { + return -1; + } + return this.info_.endTime - this.video.currentTime; } /** * @override - * @export - */ - isPaused() { - return this.video_.paused; - } - - /** - * @override - * @export - */ - isSkippable() { - return false; - } - - /** - * @override - * @export - */ - getTimeUntilSkippable() { - return 0; - } - - /** - * @override - * @export - */ - canSkipNow() { - return false; - } - - /** - * @override - * @export - */ - skip() { - // Nothing - } - - /** - * @override - * @export - */ - pause() { - return this.video_.pause(); - } - - /** - * @override - * @export - */ - play() { - return this.video_.play(); - } - - - /** - * @override - * @export - */ - getVolume() { - return this.video_.volume; - } - - /** - * @override - * @export - */ - setVolume(volume) { - this.video_.volume = volume; - } - - /** - * @override - * @export - */ - isMuted() { - return this.video_.muted; - } - - /** - * @override - * @export - */ - isLinear() { - return true; - } - - /** - * @override - * @export - */ - resize(width, height) { - // Nothing - } - - /** - * @override - * @export - */ - setMuted(muted) { - this.video_.muted = muted; - } - - - /** - * @override - * @export */ getSequenceLength() { return this.info_.sequenceLength; @@ -199,7 +60,6 @@ shaka.ads.SvtaAd = class { /** * @override - * @export */ getPositionInSequence() { return this.info_.position; @@ -207,105 +67,8 @@ shaka.ads.SvtaAd = class { /** * @override - * @export - */ - getTitle() { - return ''; - } - - /** - * @override - * @export - */ - getDescription() { - return ''; - } - - /** - * @override - * @export - */ - getVastMediaBitrate() { - return 0; - } - - /** - * @override - * @export - */ - getVastMediaHeight() { - return 0; - } - - /** - * @override - * @export - */ - getVastMediaWidth() { - return 0; - } - - /** - * @override - * @export - */ - getVastAdId() { - return ''; - } - - /** - * @override - * @export - */ - getAdId() { - return ''; - } - - /** - * @override - * @export - */ - getCreativeAdId() { - return ''; - } - - /** - * @override - * @export - */ - getAdvertiserName() { - return ''; - } - - /** - * @override - * @export - */ - getMediaUrl() { - return ''; - } - - /** - * @override - * @export */ getTimeOffset() { return this.info_.startTime; } - - /** - * @override - * @export - */ - getPodIndex() { - return 0; - } - - /** - * @override - * @export - */ - release() { - // Nothing - } };