Source: lib/ads/ad_manager.js

  1. /*! @license
  2. * Shaka Player
  3. * Copyright 2016 Google LLC
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. goog.provide('shaka.ads.AdManager');
  7. goog.require('goog.asserts');
  8. goog.require('shaka.Deprecate');
  9. goog.require('shaka.Player');
  10. goog.require('shaka.ads.AdsStats');
  11. goog.require('shaka.ads.ClientSideAdManager');
  12. goog.require('shaka.ads.InterstitialAdManager');
  13. goog.require('shaka.ads.MediaTailorAdManager');
  14. goog.require('shaka.ads.Utils');
  15. goog.require('shaka.ads.ServerSideAdManager');
  16. goog.require('shaka.log');
  17. goog.require('shaka.util.Error');
  18. goog.require('shaka.util.FakeEvent');
  19. goog.require('shaka.util.FakeEventTarget');
  20. goog.require('shaka.util.IReleasable');
  21. goog.require('shaka.util.TXml');
  22. /**
  23. * @event shaka.ads.AdManager.AdsLoadedEvent
  24. * @description Fired when a sequence of ads has been loaded.
  25. * @property {string} type
  26. * 'ads-loaded'
  27. * @property {number} loadTime
  28. * The time it takes to load ads.
  29. * @exportDoc
  30. */
  31. /**
  32. * @event shaka.ads.AdManager.AdStartedEvent
  33. * @description Fired when an ad has started playing.
  34. * @property {string} type
  35. * 'ad-started'
  36. * @property {!shaka.extern.IAd} ad
  37. * The ad that has started playing.
  38. * @property {Object} sdkAdObject
  39. * The ad object in the SDK format, if there is one.
  40. * @property {Object} originalEvent
  41. * The native SDK event, if available.
  42. * @exportDoc
  43. */
  44. /**
  45. * @event shaka.ads.AdManager.AdCompleteEvent
  46. * @description Fired when an ad has played through.
  47. * @property {string} type
  48. * 'ad-complete'
  49. * @property {Object} originalEvent
  50. * The native SDK event, if available.
  51. * @exportDoc
  52. */
  53. /**
  54. * @event shaka.ads.AdManager.AdSkippedEvent
  55. * @description Fired when an ad has been skipped.
  56. * @property {string} type
  57. * 'ad-skipped'
  58. * @property {Object} originalEvent
  59. * The native SDK event, if available.
  60. * @exportDoc
  61. */
  62. /**
  63. * @event shaka.ads.AdManager.AdFirstQuartileEvent
  64. * @description Fired when an ad has played through the first 1/4.
  65. * @property {string} type
  66. * 'ad-first-quartile'
  67. * @property {Object} originalEvent
  68. * The native SDK event, if available.
  69. * @exportDoc
  70. */
  71. /**
  72. * @event shaka.ads.AdManager.AdMidpointEvent
  73. * @description Fired when an ad has played through its midpoint.
  74. * @property {string} type
  75. * 'ad-midpoint'
  76. * @property {Object} originalEvent
  77. * The native SDK event, if available.
  78. * @exportDoc
  79. */
  80. /**
  81. * @event shaka.ads.AdManager.AdThirdQuartileEvent
  82. * @description Fired when an ad has played through the third quartile.
  83. * @property {string} type
  84. * 'ad-third-quartile'
  85. * @property {Object} originalEvent
  86. * The native SDK event, if available.
  87. * @exportDoc
  88. */
  89. /**
  90. * @event shaka.ads.AdManager.AdStoppedEvent
  91. * @description Fired when an ad has stopped playing, was skipped,
  92. * or was unable to proceed due to an error.
  93. * @property {string} type
  94. * 'ad-stopped'
  95. * @property {Object} originalEvent
  96. * The native SDK event, if available.
  97. * @exportDoc
  98. */
  99. /**
  100. * @event shaka.ads.AdManager.AdVolumeChangedEvent
  101. * @description Fired when an ad's volume changed.
  102. * @property {string} type
  103. * 'ad-volume-changed'
  104. * @property {Object} originalEvent
  105. * The native SDK event, if available.
  106. * @exportDoc
  107. */
  108. /**
  109. * @event shaka.ads.AdManager.AdMutedEvent
  110. * @description Fired when an ad was muted.
  111. * @property {string} type
  112. * 'ad-muted'
  113. * @property {Object} originalEvent
  114. * The native SDK event, if available.
  115. * @exportDoc
  116. */
  117. /**
  118. * @event shaka.ads.AdManager.AdPausedEvent
  119. * @description Fired when an ad was paused.
  120. * @property {string} type
  121. * 'ad-paused'
  122. * @property {Object} originalEvent
  123. * The native SDK event, if available.
  124. * @exportDoc
  125. */
  126. /**
  127. * @event shaka.ads.AdManager.AdResumedEvent
  128. * @description Fired when an ad was resumed after a pause.
  129. * @property {string} type
  130. * 'ad-resumed'
  131. * @property {Object} originalEvent
  132. * The native SDK event, if available.
  133. * @exportDoc
  134. */
  135. /**
  136. * @event shaka.ads.AdManager.AdSkipStateChangedEvent
  137. * @description Fired when an ad's skip state changes (for example, when
  138. * it becomes possible to skip the ad).
  139. * @property {string} type
  140. * 'ad-skip-state-changed'
  141. * @property {Object} originalEvent
  142. * The native SDK event, if available.
  143. * @exportDoc
  144. */
  145. /**
  146. * @event shaka.ads.AdManager.AdCuePointsChangedEvent
  147. * @description Fired when the ad cue points change, signalling ad breaks
  148. * change.
  149. * @property {string} type
  150. * 'ad-cue-points-changed'
  151. * @property {!Array<!shaka.extern.AdCuePoint>} cuepoints
  152. * The ad cue points, if available.
  153. * @exportDoc
  154. */
  155. /**
  156. * @event shaka.ads.AdManager.AdProgressEvent
  157. * @description Fired when there is an update to the current ad's progress.
  158. * @property {string} type
  159. * 'ad-progress'
  160. * @property {Object} originalEvent
  161. * The native SDK event, if available.
  162. * @exportDoc
  163. */
  164. /**
  165. * @event shaka.ads.AdManager.AdBufferingEvent
  166. * @description Fired when the ad has stalled playback to buffer.
  167. * @property {string} type
  168. * 'ad-buffering'
  169. * @property {Object} originalEvent
  170. * The native SDK event, if available.
  171. * @exportDoc
  172. */
  173. /**
  174. * @event shaka.ads.AdManager.AdImpressionEvent
  175. * @description Fired when the impression URL has been pinged.
  176. * @property {string} type
  177. * 'ad-impression'
  178. * @property {Object} originalEvent
  179. * The native SDK event, if available.
  180. * @exportDoc
  181. */
  182. /**
  183. * @event shaka.ads.AdManager.AdClickEvent
  184. * @description Fired when the ad was clicked.
  185. * @property {string} type
  186. * 'ad-clicked'
  187. * @property {Object} originalEvent
  188. * The native SDK event, if available.
  189. * @exportDoc
  190. */
  191. /**
  192. * @event shaka.ads.AdManager.AdDurationChangedEvent
  193. * @description Fired when the ad's duration changes.
  194. * @property {string} type
  195. * 'ad-duration-changed'
  196. * @property {Object} originalEvent
  197. * The native SDK event, if available.
  198. * @exportDoc
  199. */
  200. /**
  201. * @event shaka.ads.AdManager.AdClosedEvent
  202. * @description Fired when the ad was closed by the user.
  203. * @property {string} type
  204. * 'ad-closed'
  205. * @property {Object} originalEvent
  206. * The native SDK event, if available.
  207. * @exportDoc
  208. */
  209. /**
  210. * @event shaka.ads.AdManager.AdLoadedEvent
  211. * @description Fired when the ad data becomes available.
  212. * @property {string} type
  213. * 'ad-loaded'
  214. * @property {Object} originalEvent
  215. * The native SDK event, if available.
  216. * @exportDoc
  217. */
  218. /**
  219. * @event shaka.ads.AdManager.AllAdsCompletedEvent
  220. * @description Fired when the ads manager is done playing all the ads.
  221. * @property {string} type
  222. * 'all-ads-completed'
  223. * @property {Object} originalEvent
  224. * The native SDK event, if available.
  225. * @exportDoc
  226. */
  227. /**
  228. * @event shaka.ads.AdManager.AdLinearChangedEvent
  229. * @description Fired when the displayed ad changes from
  230. * linear to nonlinear, or vice versa.
  231. * @property {string} type
  232. * 'ad-linear-changed'
  233. * @property {Object} originalEvent
  234. * The native SDK event, if available.
  235. * @exportDoc
  236. */
  237. /**
  238. * @event shaka.ads.AdManager.AdMetadataEvent
  239. * @description Fired when the ad's metadata becomes available.
  240. * @property {string} type
  241. * 'ad-metadata'
  242. * @property {Object} originalEvent
  243. * The native SDK event, if available.
  244. * @exportDoc
  245. */
  246. /**
  247. * @event shaka.ads.AdManager#AdBreakReadyEvent
  248. * @description Fired when the client-side SDK is ready to play a
  249. * VPAID ad or an ad rule.
  250. * @property {string} type
  251. * 'ad-break-ready'
  252. * @property {Object} originalEvent
  253. * The native SDK event, if available.
  254. * @exportDoc
  255. */
  256. /**
  257. * @event shaka.ads.AdManager.AdRecoverableErrorEvent
  258. * @description Fired when the a non-fatal error was encountered.
  259. * The presentation will continue with the same or next ad playback
  260. * depending on the error situation.
  261. * @property {string} type
  262. * 'ad-recoverable-error'
  263. * @property {Object} originalEvent
  264. * The native SDK event, if available.
  265. * @exportDoc
  266. */
  267. /**
  268. * @event shaka.ads.Utils.AD_ERROR
  269. * @description Fired when a fatal error is encountered.
  270. * @property {string} type
  271. * 'ad-error'
  272. * @property {Object} originalEvent
  273. * The native SDK event, if available.
  274. * @exportDoc
  275. */
  276. /**
  277. * @event shaka.ads.AdManager.AdInteractionEvent
  278. * @description Fired when an ad triggers the interaction callback.
  279. * @property {string} type
  280. * 'ad-interaction'
  281. * @property {Object} originalEvent
  282. * The native SDK event, if available.
  283. * @exportDoc
  284. */
  285. /**
  286. * @event shaka.ads.AdManager#ImaAdManagerLoadedEvent
  287. * @description Fired when the native IMA ad manager becomes available.
  288. * @property {string} type
  289. * 'ima-ad-manager-loaded'
  290. * @property {!Object} imaAdManager
  291. * The native IMA ad manager.
  292. * @exportDoc
  293. */
  294. /**
  295. * @event shaka.ads.AdManager#ImaStreamManagerLoadedEvent
  296. * @description Fired when the native IMA stream manager becomes available.
  297. * @property {string} type
  298. * 'ima-stream-manager-loaded'
  299. * @property {!Object} imaStreamManager
  300. * The native IMA stream manager.
  301. * @exportDoc
  302. */
  303. /**
  304. * @event shaka.ads.AdManager.AdClickedEvent
  305. * @description Fired when the ad was clicked.
  306. * @property {string} type
  307. * 'ad-clicked'
  308. * @exportDoc
  309. */
  310. /**
  311. * @event shaka.ads.AdManager.AdContentPauseRequestedEvent
  312. * @description Fired when the ad requires the main content to be paused.
  313. * Fired when the platform does not support multiple media elements.
  314. * @property {string} type
  315. * 'ad-content-pause-requested'
  316. * @property {?boolean} saveLivePosition
  317. * Indicates whether the live position has to be saved or not.
  318. * @exportDoc
  319. */
  320. /**
  321. * @event shaka.ads.AdManager.AdContentResumeRequestedEvent
  322. * @description Fired when the ad requires the main content to be resumed.
  323. * Fired when the platform does not support multiple media elements.
  324. * @property {string} type
  325. * 'ad-content-resume-requested'
  326. * @property {?number} offset
  327. * Indicates the offset that should be applied to the previously saved time.
  328. * @exportDoc
  329. */
  330. /**
  331. * @event shaka.ads.AdManager.AdContentResumeRequestedEvent
  332. * @description Fired when the ad requires the video of the main content to be
  333. * attached.
  334. * @property {string} type
  335. * 'ad-content-attach-requested'
  336. * @exportDoc
  337. */
  338. /**
  339. * A class responsible for ad-related interactions.
  340. * @implements {shaka.extern.IAdManager}
  341. * @implements {shaka.util.IReleasable}
  342. * @export
  343. */
  344. shaka.ads.AdManager = class extends shaka.util.FakeEventTarget {
  345. constructor() {
  346. super();
  347. /** @private {shaka.ads.InterstitialAdManager} */
  348. this.interstitialAdManager_ = null;
  349. /** @private {shaka.ads.ClientSideAdManager} */
  350. this.csAdManager_ = null;
  351. /** @private {shaka.ads.MediaTailorAdManager} */
  352. this.mtAdManager_ = null;
  353. /** @private {shaka.ads.ServerSideAdManager} */
  354. this.ssAdManager_ = null;
  355. /** @private {shaka.ads.AdsStats} */
  356. this.stats_ = new shaka.ads.AdsStats();
  357. /** @private {string} locale */
  358. this.locale_ = navigator.language;
  359. /** @private {?shaka.extern.AdsConfiguration} */
  360. this.config_ = null;
  361. }
  362. /**
  363. * @override
  364. * @export
  365. */
  366. setLocale(locale) {
  367. this.locale_ = locale;
  368. }
  369. /**
  370. * @override
  371. * @export
  372. */
  373. configure(config) {
  374. this.config_ = config;
  375. if (this.interstitialAdManager_) {
  376. this.interstitialAdManager_.configure(this.config_);
  377. }
  378. if (this.csAdManager_) {
  379. this.csAdManager_.configure(this.config_);
  380. }
  381. if (this.ssAdManager_) {
  382. this.ssAdManager_.configure(this.config_);
  383. }
  384. }
  385. /**
  386. * @override
  387. * @export
  388. */
  389. initInterstitial(adContainer, basePlayer, baseVideo) {
  390. if (!adContainer) {
  391. shaka.log.info('Initializing interstitials without ad container');
  392. }
  393. if (this.interstitialAdManager_) {
  394. this.interstitialAdManager_.release();
  395. }
  396. this.interstitialAdManager_ = new shaka.ads.InterstitialAdManager(
  397. adContainer, basePlayer, baseVideo,
  398. (e) => this.processAndDispatchEvent_(e));
  399. goog.asserts.assert(this.config_, 'Config must not be null!');
  400. this.interstitialAdManager_.configure(this.config_);
  401. }
  402. /**
  403. * @override
  404. * @export
  405. */
  406. initClientSide(adContainer, video, adsRenderingSettings) {
  407. // Check that Client Side IMA SDK has been included
  408. // NOTE: (window['google'] && google.ima) check for any
  409. // IMA SDK, including SDK for Server Side ads.
  410. // The 3rd check insures we have the right SDK:
  411. // {google.ima.AdsLoader} is an object that's part of CS IMA SDK
  412. // but not SS SDK.
  413. if (!window['google'] || !google.ima || !google.ima.AdsLoader) {
  414. throw new shaka.util.Error(
  415. shaka.util.Error.Severity.CRITICAL,
  416. shaka.util.Error.Category.ADS,
  417. shaka.util.Error.Code.CS_IMA_SDK_MISSING);
  418. }
  419. if (this.csAdManager_) {
  420. this.csAdManager_.release();
  421. }
  422. this.csAdManager_ = new shaka.ads.ClientSideAdManager(
  423. adContainer, video, this.locale_, adsRenderingSettings,
  424. (e) => this.processAndDispatchEvent_(e));
  425. goog.asserts.assert(this.config_, 'Config must not be null!');
  426. this.csAdManager_.configure(this.config_);
  427. }
  428. /**
  429. * @override
  430. * @export
  431. */
  432. release() {
  433. if (this.interstitialAdManager_) {
  434. this.interstitialAdManager_.release();
  435. this.interstitialAdManager_ = null;
  436. }
  437. if (this.csAdManager_) {
  438. this.csAdManager_.release();
  439. this.csAdManager_ = null;
  440. }
  441. if (this.mtAdManager_) {
  442. this.mtAdManager_.release();
  443. this.mtAdManager_ = null;
  444. }
  445. if (this.ssAdManager_) {
  446. this.ssAdManager_.release();
  447. this.ssAdManager_ = null;
  448. }
  449. super.release();
  450. }
  451. /**
  452. * @override
  453. * @export
  454. */
  455. onAssetUnload() {
  456. if (this.interstitialAdManager_) {
  457. this.interstitialAdManager_.stop();
  458. }
  459. if (this.csAdManager_) {
  460. this.csAdManager_.stop();
  461. }
  462. if (this.mtAdManager_) {
  463. this.mtAdManager_.stop();
  464. }
  465. if (this.ssAdManager_) {
  466. this.ssAdManager_.stop();
  467. }
  468. this.dispatchEvent(
  469. new shaka.util.FakeEvent(shaka.ads.Utils.AD_STOPPED));
  470. this.dispatchEvent(new shaka.util.FakeEvent(
  471. shaka.ads.Utils.AD_CONTENT_ATTACH_REQUESTED));
  472. this.stats_ = new shaka.ads.AdsStats();
  473. }
  474. /**
  475. * @override
  476. * @export
  477. */
  478. requestClientSideAds(imaRequest) {
  479. if (!this.csAdManager_) {
  480. throw new shaka.util.Error(
  481. shaka.util.Error.Severity.RECOVERABLE,
  482. shaka.util.Error.Category.ADS,
  483. shaka.util.Error.Code.CS_AD_MANAGER_NOT_INITIALIZED);
  484. }
  485. this.csAdManager_.requestAds(imaRequest);
  486. }
  487. /**
  488. * @override
  489. * @export
  490. */
  491. updateClientSideAdsRenderingSettings(adsRenderingSettings) {
  492. if (!this.csAdManager_) {
  493. throw new shaka.util.Error(
  494. shaka.util.Error.Severity.RECOVERABLE,
  495. shaka.util.Error.Category.ADS,
  496. shaka.util.Error.Code.CS_AD_MANAGER_NOT_INITIALIZED);
  497. }
  498. this.csAdManager_.updateAdsRenderingSettings(adsRenderingSettings);
  499. }
  500. /**
  501. * @override
  502. * @export
  503. */
  504. initMediaTailor(adContainer, networkingEngine, video) {
  505. if (this.mtAdManager_) {
  506. this.mtAdManager_.release();
  507. }
  508. this.mtAdManager_ = new shaka.ads.MediaTailorAdManager(
  509. adContainer, networkingEngine, video,
  510. (e) => this.processAndDispatchEvent_(e));
  511. }
  512. /**
  513. * @param {string} url
  514. * @param {Object} adsParams
  515. * @param {string=} backupUrl
  516. * @return {!Promise<string>}
  517. * @override
  518. * @export
  519. */
  520. requestMediaTailorStream(url, adsParams, backupUrl = '') {
  521. if (!this.mtAdManager_) {
  522. throw new shaka.util.Error(
  523. shaka.util.Error.Severity.RECOVERABLE,
  524. shaka.util.Error.Category.ADS,
  525. shaka.util.Error.Code.MT_AD_MANAGER_NOT_INITIALIZED);
  526. }
  527. return this.mtAdManager_.streamRequest(url, adsParams, backupUrl);
  528. }
  529. /**
  530. * @param {string} url
  531. * @override
  532. * @export
  533. */
  534. addMediaTailorTrackingUrl(url) {
  535. if (!this.mtAdManager_) {
  536. throw new shaka.util.Error(
  537. shaka.util.Error.Severity.RECOVERABLE,
  538. shaka.util.Error.Category.ADS,
  539. shaka.util.Error.Code.MT_AD_MANAGER_NOT_INITIALIZED);
  540. }
  541. this.mtAdManager_.addTrackingUrl(url);
  542. }
  543. /**
  544. * @override
  545. * @export
  546. */
  547. initServerSide(adContainer, video) {
  548. // Check that Client Side IMA SDK has been included
  549. // NOTE: (window['google'] && google.ima) check for any
  550. // IMA SDK, including SDK for Server Side ads.
  551. // The 3rd check insures we have the right SDK:
  552. // {google.ima.dai} is an object that's part of DAI IMA SDK
  553. // but not SS SDK.
  554. if (!window['google'] || !google.ima || !google.ima.dai) {
  555. throw new shaka.util.Error(
  556. shaka.util.Error.Severity.CRITICAL,
  557. shaka.util.Error.Category.ADS,
  558. shaka.util.Error.Code.SS_IMA_SDK_MISSING);
  559. }
  560. if (this.ssAdManager_) {
  561. this.ssAdManager_.release();
  562. }
  563. this.ssAdManager_ = new shaka.ads.ServerSideAdManager(
  564. adContainer, video, this.locale_,
  565. (e) => this.processAndDispatchEvent_(e));
  566. goog.asserts.assert(this.config_, 'Config must not be null!');
  567. this.ssAdManager_.configure(this.config_);
  568. }
  569. /**
  570. * @param {!google.ima.dai.api.StreamRequest} imaRequest
  571. * @param {string=} backupUrl
  572. * @return {!Promise<string>}
  573. * @override
  574. * @export
  575. */
  576. requestServerSideStream(imaRequest, backupUrl = '') {
  577. if (!this.ssAdManager_) {
  578. throw new shaka.util.Error(
  579. shaka.util.Error.Severity.RECOVERABLE,
  580. shaka.util.Error.Category.ADS,
  581. shaka.util.Error.Code.SS_AD_MANAGER_NOT_INITIALIZED);
  582. }
  583. if (!imaRequest.adTagParameters) {
  584. imaRequest.adTagParameters = {};
  585. }
  586. const adTagParams = imaRequest.adTagParameters;
  587. if (adTagParams['mpt'] || adTagParams['mpv']) {
  588. shaka.log.alwaysWarn('You have attempted to set "mpt" and/or "mpv" ' +
  589. 'parameters of the ad tag. Please note that those parameters are ' +
  590. 'used for Shaka adoption tracking and will be overridden.');
  591. }
  592. // Set player and version parameters for tracking
  593. imaRequest.adTagParameters['mpt'] = 'shaka-player';
  594. imaRequest.adTagParameters['mpv'] = shaka.Player.version;
  595. return this.ssAdManager_.streamRequest(imaRequest, backupUrl);
  596. }
  597. /**
  598. * @override
  599. * @export
  600. */
  601. replaceServerSideAdTagParameters(adTagParameters) {
  602. if (!this.ssAdManager_) {
  603. throw new shaka.util.Error(
  604. shaka.util.Error.Severity.RECOVERABLE,
  605. shaka.util.Error.Category.ADS,
  606. shaka.util.Error.Code.SS_AD_MANAGER_NOT_INITIALIZED);
  607. }
  608. if (adTagParameters['mpt'] || adTagParameters['mpv']) {
  609. shaka.log.alwaysWarn('You have attempted to set "mpt" and/or "mpv" ' +
  610. 'parameters of the ad tag. Please note that those parameters are ' +
  611. 'used for Shaka adoption tracking and will be overridden.');
  612. }
  613. adTagParameters['mpt'] = 'Shaka Player';
  614. adTagParameters['mpv'] = shaka.Player.version;
  615. this.ssAdManager_.replaceAdTagParameters(adTagParameters);
  616. }
  617. /**
  618. * @return {!Array<!shaka.extern.AdCuePoint>}
  619. * @override
  620. * @export
  621. */
  622. getServerSideCuePoints() {
  623. shaka.Deprecate.deprecateFeature(5,
  624. 'AdManager.getServerSideCuePoints',
  625. 'Please use getCuePoints function.');
  626. return this.getCuePoints();
  627. }
  628. /**
  629. * @return {!Array<!shaka.extern.AdCuePoint>}
  630. * @override
  631. * @export
  632. */
  633. getCuePoints() {
  634. let cuepoints = [];
  635. if (this.ssAdManager_) {
  636. cuepoints = cuepoints.concat(this.ssAdManager_.getCuePoints());
  637. }
  638. if (this.mtAdManager_) {
  639. cuepoints = cuepoints.concat(this.mtAdManager_.getCuePoints());
  640. }
  641. return cuepoints;
  642. }
  643. /**
  644. * @return {shaka.extern.AdsStats}
  645. * @override
  646. * @export
  647. */
  648. getStats() {
  649. return this.stats_.getBlob();
  650. }
  651. /**
  652. * @override
  653. * @export
  654. */
  655. onManifestUpdated(isLive) {
  656. if (this.mtAdManager_) {
  657. this.mtAdManager_.onManifestUpdated(isLive);
  658. }
  659. }
  660. /**
  661. * @override
  662. * @export
  663. */
  664. onDashTimedMetadata(region) {
  665. if (this.ssAdManager_ && region.schemeIdUri == 'urn:google:dai:2018') {
  666. const type = region.schemeIdUri;
  667. const data = region.eventNode ?
  668. region.eventNode.attributes['messageData'] : null;
  669. const timestamp = region.startTime;
  670. this.ssAdManager_.onTimedMetadata(type, data, timestamp);
  671. }
  672. }
  673. /**
  674. * @override
  675. * @export
  676. */
  677. onHlsTimedMetadata(metadata, timestamp) {
  678. if (this.ssAdManager_) {
  679. this.ssAdManager_.onTimedMetadata('ID3', metadata['data'], timestamp);
  680. }
  681. }
  682. /**
  683. * @override
  684. * @export
  685. */
  686. onCueMetadataChange(value) {
  687. if (this.ssAdManager_) {
  688. this.ssAdManager_.onCueMetadataChange(value);
  689. }
  690. }
  691. /**
  692. * @override
  693. * @export
  694. */
  695. onHLSInterstitialMetadata(basePlayer, baseVideo, interstitial) {
  696. if (this.config_ && this.config_.disableHLSInterstitial) {
  697. return;
  698. }
  699. if (!this.interstitialAdManager_) {
  700. this.initInterstitial(/* adContainer= */ null, basePlayer, baseVideo);
  701. }
  702. if (this.interstitialAdManager_) {
  703. this.interstitialAdManager_.addMetadata(interstitial);
  704. }
  705. }
  706. /**
  707. * @override
  708. * @export
  709. */
  710. onDASHInterstitialMetadata(basePlayer, baseVideo, region) {
  711. if (this.config_ && this.config_.disableDASHInterstitial) {
  712. return;
  713. }
  714. const schemeIdUri = region.schemeIdUri;
  715. if (schemeIdUri == 'urn:mpeg:dash:event:alternativeMPD:insert:2025' ||
  716. schemeIdUri == 'urn:mpeg:dash:event:alternativeMPD:replace:2025') {
  717. if (!this.interstitialAdManager_) {
  718. this.initInterstitial(/* adContainer= */ null, basePlayer, baseVideo);
  719. }
  720. if (this.interstitialAdManager_) {
  721. this.interstitialAdManager_.addRegion(region);
  722. }
  723. } else if ((schemeIdUri == 'urn:mpeg:dash:event:2012' ||
  724. schemeIdUri == 'urn:scte:dash:scte214-events') &&
  725. region.eventNode &&
  726. shaka.util.TXml.findChild(region.eventNode, 'OverlayEvent')) {
  727. if (!this.interstitialAdManager_) {
  728. this.initInterstitial(/* adContainer= */ null, basePlayer, baseVideo);
  729. }
  730. if (this.interstitialAdManager_) {
  731. this.interstitialAdManager_.addOverlayRegion(region);
  732. }
  733. }
  734. }
  735. /**
  736. * @override
  737. * @export
  738. */
  739. addCustomInterstitial(interstitial) {
  740. if (!this.interstitialAdManager_) {
  741. throw new shaka.util.Error(
  742. shaka.util.Error.Severity.RECOVERABLE,
  743. shaka.util.Error.Category.ADS,
  744. shaka.util.Error.Code.INTERSTITIAL_AD_MANAGER_NOT_INITIALIZED);
  745. }
  746. this.interstitialAdManager_.addInterstitials([interstitial]);
  747. }
  748. /**
  749. * @override
  750. * @export
  751. */
  752. addAdUrlInterstitial(url) {
  753. if (!this.interstitialAdManager_) {
  754. throw new shaka.util.Error(
  755. shaka.util.Error.Severity.RECOVERABLE,
  756. shaka.util.Error.Category.ADS,
  757. shaka.util.Error.Code.INTERSTITIAL_AD_MANAGER_NOT_INITIALIZED);
  758. }
  759. return this.interstitialAdManager_.addAdUrlInterstitial(url);
  760. }
  761. /**
  762. * @override
  763. * @export
  764. */
  765. getInterstitialPlayer() {
  766. if (!this.interstitialAdManager_) {
  767. throw new shaka.util.Error(
  768. shaka.util.Error.Severity.RECOVERABLE,
  769. shaka.util.Error.Category.ADS,
  770. shaka.util.Error.Code.INTERSTITIAL_AD_MANAGER_NOT_INITIALIZED);
  771. }
  772. return this.interstitialAdManager_.getPlayer();
  773. }
  774. /**
  775. * @param {!shaka.util.FakeEvent} event
  776. * @private
  777. */
  778. processAndDispatchEvent_(event) {
  779. if (event && event.type) {
  780. switch (event.type) {
  781. case shaka.ads.Utils.ADS_LOADED: {
  782. const loadTime = (/** @type {!Object} */ (event))['loadTime'];
  783. this.stats_.addLoadTime(loadTime);
  784. break;
  785. }
  786. case shaka.ads.Utils.AD_STARTED: {
  787. this.stats_.incrementStarted();
  788. const ad = (/** @type {!Object} */ (event))['ad'];
  789. if (ad && !ad.isLinear()) {
  790. this.stats_.incrementOverlayAds();
  791. }
  792. break;
  793. }
  794. case shaka.ads.Utils.AD_COMPLETE:
  795. this.stats_.incrementPlayedCompletely();
  796. break;
  797. case shaka.ads.Utils.AD_SKIPPED:
  798. this.stats_.incrementSkipped();
  799. break;
  800. case shaka.ads.Utils.AD_ERROR:
  801. this.stats_.incrementErrors();
  802. break;
  803. }
  804. }
  805. this.dispatchEvent(event);
  806. }
  807. };
  808. /**
  809. * The event name for when a sequence of ads has been loaded.
  810. *
  811. * Deprecated, please use {@link shaka.ads.Utils}
  812. *
  813. * @const {string}
  814. * @export
  815. * @deprecated
  816. */
  817. shaka.ads.AdManager.ADS_LOADED = 'ads-loaded';
  818. /**
  819. * The event name for when an ad has started playing.
  820. *
  821. * Deprecated, please use {@link shaka.ads.Utils}
  822. *
  823. * @const {string}
  824. * @export
  825. * @deprecated
  826. */
  827. shaka.ads.AdManager.AD_STARTED = 'ad-started';
  828. /**
  829. * The event name for when an ad playhead crosses first quartile.
  830. *
  831. * Deprecated, please use {@link shaka.ads.Utils}
  832. *
  833. * @const {string}
  834. * @export
  835. * @deprecated
  836. */
  837. shaka.ads.AdManager.AD_FIRST_QUARTILE = 'ad-first-quartile';
  838. /**
  839. * The event name for when an ad playhead crosses midpoint.
  840. *
  841. * Deprecated, please use {@link shaka.ads.Utils}
  842. *
  843. * @const {string}
  844. * @export
  845. * @deprecated
  846. */
  847. shaka.ads.AdManager.AD_MIDPOINT = 'ad-midpoint';
  848. /**
  849. * The event name for when an ad playhead crosses third quartile.
  850. *
  851. * Deprecated, please use {@link shaka.ads.Utils}
  852. *
  853. * @const {string}
  854. * @export
  855. * @deprecated
  856. */
  857. shaka.ads.AdManager.AD_THIRD_QUARTILE = 'ad-third-quartile';
  858. /**
  859. * The event name for when an ad has completed playing.
  860. *
  861. * Deprecated, please use {@link shaka.ads.Utils}
  862. *
  863. * @const {string}
  864. * @export
  865. * @deprecated
  866. */
  867. shaka.ads.AdManager.AD_COMPLETE = 'ad-complete';
  868. /**
  869. * The event name for when an ad has finished playing
  870. * (played all the way through, was skipped, or was unable to proceed
  871. * due to an error).
  872. *
  873. * Deprecated, please use {@link shaka.ads.Utils}
  874. *
  875. * @const {string}
  876. * @export
  877. * @deprecated
  878. */
  879. shaka.ads.AdManager.AD_STOPPED = 'ad-stopped';
  880. /**
  881. * The event name for when an ad is skipped by the user.
  882. *
  883. * Deprecated, please use {@link shaka.ads.Utils}
  884. *
  885. * @const {string}
  886. * @export
  887. * @deprecated
  888. */
  889. shaka.ads.AdManager.AD_SKIPPED = 'ad-skipped';
  890. /**
  891. * The event name for when the ad volume has changed.
  892. *
  893. * Deprecated, please use {@link shaka.ads.Utils}
  894. *
  895. * @const {string}
  896. * @export
  897. * @deprecated
  898. */
  899. shaka.ads.AdManager.AD_VOLUME_CHANGED = 'ad-volume-changed';
  900. /**
  901. * The event name for when the ad was muted.
  902. *
  903. * Deprecated, please use {@link shaka.ads.Utils}
  904. *
  905. * @const {string}
  906. * @export
  907. * @deprecated
  908. */
  909. shaka.ads.AdManager.AD_MUTED = 'ad-muted';
  910. /**
  911. * The event name for when the ad was paused.
  912. *
  913. * Deprecated, please use {@link shaka.ads.Utils}
  914. *
  915. * @const {string}
  916. * @export
  917. * @deprecated
  918. */
  919. shaka.ads.AdManager.AD_PAUSED = 'ad-paused';
  920. /**
  921. * The event name for when the ad was resumed after a pause.
  922. *
  923. * Deprecated, please use {@link shaka.ads.Utils}
  924. *
  925. * @const {string}
  926. * @export
  927. * @deprecated
  928. */
  929. shaka.ads.AdManager.AD_RESUMED = 'ad-resumed';
  930. /**
  931. * The event name for when the ad's skip status changes
  932. * (usually it becomes skippable when it wasn't before).
  933. *
  934. * Deprecated, please use {@link shaka.ads.Utils}
  935. *
  936. * @const {string}
  937. * @export
  938. * @deprecated
  939. */
  940. shaka.ads.AdManager.AD_SKIP_STATE_CHANGED = 'ad-skip-state-changed';
  941. /**
  942. * The event name for when the ad's cue points (start/end markers)
  943. * have changed.
  944. *
  945. * Deprecated, please use {@link shaka.ads.Utils}
  946. *
  947. * @const {string}
  948. * @export
  949. * @deprecated
  950. */
  951. shaka.ads.AdManager.CUEPOINTS_CHANGED = 'ad-cue-points-changed';
  952. /**
  953. * The event name for when the native IMA ad manager object has
  954. * loaded and become available.
  955. *
  956. * Deprecated, please use {@link shaka.ads.Utils}
  957. *
  958. * @const {string}
  959. * @export
  960. * @deprecated
  961. */
  962. shaka.ads.AdManager.IMA_AD_MANAGER_LOADED = 'ima-ad-manager-loaded';
  963. /**
  964. * The event name for when the native IMA stream manager object has
  965. * loaded and become available.
  966. *
  967. * Deprecated, please use {@link shaka.ads.Utils}
  968. *
  969. * @const {string}
  970. * @export
  971. * @deprecated
  972. */
  973. shaka.ads.AdManager.IMA_STREAM_MANAGER_LOADED = 'ima-stream-manager-loaded';
  974. /**
  975. * The event name for when the ad was clicked.
  976. *
  977. * Deprecated, please use {@link shaka.ads.Utils}
  978. *
  979. * @const {string}
  980. * @export
  981. * @deprecated
  982. */
  983. shaka.ads.AdManager.AD_CLICKED = 'ad-clicked';
  984. /**
  985. * The event name for when there is an update to the current ad's progress.
  986. *
  987. * Deprecated, please use {@link shaka.ads.Utils}
  988. *
  989. * @const {string}
  990. * @export
  991. * @deprecated
  992. */
  993. shaka.ads.AdManager.AD_PROGRESS = 'ad-progress';
  994. /**
  995. * The event name for when the ad is buffering.
  996. *
  997. * Deprecated, please use {@link shaka.ads.Utils}
  998. *
  999. * @const {string}
  1000. * @export
  1001. * @deprecated
  1002. */
  1003. shaka.ads.AdManager.AD_BUFFERING = 'ad-buffering';
  1004. /**
  1005. * The event name for when the ad's URL was hit.
  1006. *
  1007. * Deprecated, please use {@link shaka.ads.Utils}
  1008. *
  1009. * @const {string}
  1010. * @export
  1011. * @deprecated
  1012. */
  1013. shaka.ads.AdManager.AD_IMPRESSION = 'ad-impression';
  1014. /**
  1015. * The event name for when the ad's duration changed.
  1016. *
  1017. * Deprecated, please use {@link shaka.ads.Utils}
  1018. *
  1019. * @const {string}
  1020. * @export
  1021. * @deprecated
  1022. */
  1023. shaka.ads.AdManager.AD_DURATION_CHANGED = 'ad-duration-changed';
  1024. /**
  1025. * The event name for when the ad was closed by the user.
  1026. *
  1027. * Deprecated, please use {@link shaka.ads.Utils}
  1028. *
  1029. * @const {string}
  1030. * @export
  1031. * @deprecated
  1032. */
  1033. shaka.ads.AdManager.AD_CLOSED = 'ad-closed';
  1034. /**
  1035. * The event name for when the ad data becomes available.
  1036. *
  1037. * Deprecated, please use {@link shaka.ads.Utils}
  1038. *
  1039. * @const {string}
  1040. * @export
  1041. * @deprecated
  1042. */
  1043. shaka.ads.AdManager.AD_LOADED = 'ad-loaded';
  1044. /**
  1045. * The event name for when all the ads were completed.
  1046. *
  1047. * Deprecated, please use {@link shaka.ads.Utils}
  1048. *
  1049. * @const {string}
  1050. * @export
  1051. * @deprecated
  1052. */
  1053. shaka.ads.AdManager.ALL_ADS_COMPLETED = 'all-ads-completed';
  1054. /**
  1055. * The event name for when the ad changes from or to linear.
  1056. *
  1057. * Deprecated, please use {@link shaka.ads.Utils}
  1058. *
  1059. * @const {string}
  1060. * @export
  1061. * @deprecated
  1062. */
  1063. shaka.ads.AdManager.AD_LINEAR_CHANGED = 'ad-linear-changed';
  1064. /**
  1065. * The event name for when the ad's metadata becomes available.
  1066. *
  1067. * Deprecated, please use {@link shaka.ads.Utils}
  1068. *
  1069. * @const {string}
  1070. * @export
  1071. * @deprecated
  1072. */
  1073. shaka.ads.AdManager.AD_METADATA = 'ad-metadata';
  1074. /**
  1075. * The event name for when the ad display encountered a recoverable
  1076. * error.
  1077. *
  1078. * Deprecated, please use {@link shaka.ads.Utils}
  1079. *
  1080. * @const {string}
  1081. * @export
  1082. * @deprecated
  1083. */
  1084. shaka.ads.AdManager.AD_RECOVERABLE_ERROR = 'ad-recoverable-error';
  1085. /**
  1086. * The event name for when the ad manager dispatch errors.
  1087. *
  1088. * Deprecated, please use {@link shaka.ads.Utils}
  1089. *
  1090. * @const {string}
  1091. * @export
  1092. * @deprecated
  1093. */
  1094. shaka.ads.AdManager.AD_ERROR = 'ad-error';
  1095. /**
  1096. * The event name for when the client side SDK signalled its readiness
  1097. * to play a VPAID ad or an ad rule.
  1098. *
  1099. * Deprecated, please use {@link shaka.ads.Utils}
  1100. *
  1101. * @const {string}
  1102. * @export
  1103. * @deprecated
  1104. */
  1105. shaka.ads.AdManager.AD_BREAK_READY = 'ad-break-ready';
  1106. /**
  1107. * The event name for when the interaction callback for the ad was
  1108. * triggered.
  1109. *
  1110. * Deprecated, please use {@link shaka.ads.Utils}
  1111. *
  1112. * @const {string}
  1113. * @export
  1114. * @deprecated
  1115. */
  1116. shaka.ads.AdManager.AD_INTERACTION = 'ad-interaction';
  1117. /**
  1118. * The name of the event for when an ad requires the main content to be paused.
  1119. * Fired when the platform does not support multiple media elements.
  1120. *
  1121. * Deprecated, please use {@link shaka.ads.Utils}
  1122. *
  1123. * @const {string}
  1124. * @export
  1125. * @deprecated
  1126. */
  1127. shaka.ads.AdManager.AD_CONTENT_PAUSE_REQUESTED = 'ad-content-pause-requested';
  1128. /**
  1129. * The name of the event for when an ad requires the main content to be resumed.
  1130. * Fired when the platform does not support multiple media elements.
  1131. *
  1132. * Deprecated, please use {@link shaka.ads.Utils}
  1133. *
  1134. * @const {string}
  1135. * @export
  1136. * @deprecated
  1137. */
  1138. shaka.ads.AdManager.AD_CONTENT_RESUME_REQUESTED = 'ad-content-resume-requested';
  1139. /**
  1140. * The name of the event for when an ad requires the video of the main content
  1141. * to be attached.
  1142. *
  1143. * Deprecated, please use {@link shaka.ads.Utils}
  1144. *
  1145. * @const {string}
  1146. * @export
  1147. * @deprecated
  1148. */
  1149. shaka.ads.AdManager.AD_CONTENT_ATTACH_REQUESTED = 'ad-content-attach-requested';
  1150. /**
  1151. * Set this is a default ad manager for the player.
  1152. * Apps can also set their own ad manager, if they'd like.
  1153. */
  1154. shaka.Player.setAdManagerFactory(() => new shaka.ads.AdManager());