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. /** */
  346. constructor() {
  347. super();
  348. /** @private {shaka.ads.InterstitialAdManager} */
  349. this.interstitialAdManager_ = null;
  350. /** @private {shaka.ads.ClientSideAdManager} */
  351. this.csAdManager_ = null;
  352. /** @private {shaka.ads.MediaTailorAdManager} */
  353. this.mtAdManager_ = null;
  354. /** @private {shaka.ads.ServerSideAdManager} */
  355. this.ssAdManager_ = null;
  356. /** @private {shaka.ads.AdsStats} */
  357. this.stats_ = new shaka.ads.AdsStats();
  358. /** @private {string} locale */
  359. this.locale_ = navigator.language;
  360. /** @private {?shaka.extern.AdsConfiguration} */
  361. this.config_ = null;
  362. }
  363. /**
  364. * @override
  365. * @export
  366. */
  367. setLocale(locale) {
  368. this.locale_ = locale;
  369. }
  370. /**
  371. * @override
  372. * @export
  373. */
  374. configure(config) {
  375. this.config_ = config;
  376. if (this.interstitialAdManager_) {
  377. this.interstitialAdManager_.configure(this.config_);
  378. }
  379. if (this.csAdManager_) {
  380. this.csAdManager_.configure(this.config_);
  381. }
  382. if (this.ssAdManager_) {
  383. this.ssAdManager_.configure(this.config_);
  384. }
  385. }
  386. /**
  387. * @override
  388. * @export
  389. */
  390. initInterstitial(adContainer, basePlayer, baseVideo) {
  391. if (!adContainer) {
  392. shaka.log.info('Initializing interstitials without ad container');
  393. }
  394. if (this.interstitialAdManager_) {
  395. this.interstitialAdManager_.release();
  396. }
  397. this.interstitialAdManager_ = new shaka.ads.InterstitialAdManager(
  398. adContainer, basePlayer, baseVideo,
  399. (e) => this.processAndDispatchEvent_(e));
  400. goog.asserts.assert(this.config_, 'Config must not be null!');
  401. this.interstitialAdManager_.configure(this.config_);
  402. }
  403. /**
  404. * @override
  405. * @export
  406. */
  407. initClientSide(adContainer, video, adsRenderingSettings) {
  408. // Check that Client Side IMA SDK has been included
  409. // NOTE: (window['google'] && google.ima) check for any
  410. // IMA SDK, including SDK for Server Side ads.
  411. // The 3rd check insures we have the right SDK:
  412. // {google.ima.AdsLoader} is an object that's part of CS IMA SDK
  413. // but not SS SDK.
  414. if (!window['google'] || !google.ima || !google.ima.AdsLoader) {
  415. throw new shaka.util.Error(
  416. shaka.util.Error.Severity.CRITICAL,
  417. shaka.util.Error.Category.ADS,
  418. shaka.util.Error.Code.CS_IMA_SDK_MISSING);
  419. }
  420. if (this.csAdManager_) {
  421. this.csAdManager_.release();
  422. }
  423. this.csAdManager_ = new shaka.ads.ClientSideAdManager(
  424. adContainer, video, this.locale_, adsRenderingSettings,
  425. (e) => this.processAndDispatchEvent_(e));
  426. goog.asserts.assert(this.config_, 'Config must not be null!');
  427. this.csAdManager_.configure(this.config_);
  428. }
  429. /**
  430. * @override
  431. * @export
  432. */
  433. release() {
  434. if (this.interstitialAdManager_) {
  435. this.interstitialAdManager_.release();
  436. this.interstitialAdManager_ = null;
  437. }
  438. if (this.csAdManager_) {
  439. this.csAdManager_.release();
  440. this.csAdManager_ = null;
  441. }
  442. if (this.mtAdManager_) {
  443. this.mtAdManager_.release();
  444. this.mtAdManager_ = null;
  445. }
  446. if (this.ssAdManager_) {
  447. this.ssAdManager_.release();
  448. this.ssAdManager_ = null;
  449. }
  450. super.release();
  451. }
  452. /**
  453. * @override
  454. * @export
  455. */
  456. onAssetUnload() {
  457. if (this.interstitialAdManager_) {
  458. this.interstitialAdManager_.stop();
  459. }
  460. if (this.csAdManager_) {
  461. this.csAdManager_.stop();
  462. }
  463. if (this.mtAdManager_) {
  464. this.mtAdManager_.stop();
  465. }
  466. if (this.ssAdManager_) {
  467. this.ssAdManager_.stop();
  468. }
  469. this.dispatchEvent(
  470. new shaka.util.FakeEvent(shaka.ads.Utils.AD_STOPPED));
  471. this.dispatchEvent(new shaka.util.FakeEvent(
  472. shaka.ads.Utils.AD_CONTENT_ATTACH_REQUESTED));
  473. this.stats_ = new shaka.ads.AdsStats();
  474. }
  475. /**
  476. * @override
  477. * @export
  478. */
  479. requestClientSideAds(imaRequest) {
  480. if (!this.csAdManager_) {
  481. throw new shaka.util.Error(
  482. shaka.util.Error.Severity.RECOVERABLE,
  483. shaka.util.Error.Category.ADS,
  484. shaka.util.Error.Code.CS_AD_MANAGER_NOT_INITIALIZED);
  485. }
  486. this.csAdManager_.requestAds(imaRequest);
  487. }
  488. /**
  489. * @override
  490. * @export
  491. */
  492. updateClientSideAdsRenderingSettings(adsRenderingSettings) {
  493. if (!this.csAdManager_) {
  494. throw new shaka.util.Error(
  495. shaka.util.Error.Severity.RECOVERABLE,
  496. shaka.util.Error.Category.ADS,
  497. shaka.util.Error.Code.CS_AD_MANAGER_NOT_INITIALIZED);
  498. }
  499. this.csAdManager_.updateAdsRenderingSettings(adsRenderingSettings);
  500. }
  501. /**
  502. * @override
  503. * @export
  504. */
  505. initMediaTailor(adContainer, networkingEngine, video) {
  506. if (this.mtAdManager_) {
  507. this.mtAdManager_.release();
  508. }
  509. this.mtAdManager_ = new shaka.ads.MediaTailorAdManager(
  510. adContainer, networkingEngine, video,
  511. (e) => this.processAndDispatchEvent_(e));
  512. }
  513. /**
  514. * @param {string} url
  515. * @param {Object} adsParams
  516. * @param {string=} backupUrl
  517. * @return {!Promise<string>}
  518. * @override
  519. * @export
  520. */
  521. requestMediaTailorStream(url, adsParams, backupUrl = '') {
  522. if (!this.mtAdManager_) {
  523. throw new shaka.util.Error(
  524. shaka.util.Error.Severity.RECOVERABLE,
  525. shaka.util.Error.Category.ADS,
  526. shaka.util.Error.Code.MT_AD_MANAGER_NOT_INITIALIZED);
  527. }
  528. return this.mtAdManager_.streamRequest(url, adsParams, backupUrl);
  529. }
  530. /**
  531. * @param {string} url
  532. * @override
  533. * @export
  534. */
  535. addMediaTailorTrackingUrl(url) {
  536. if (!this.mtAdManager_) {
  537. throw new shaka.util.Error(
  538. shaka.util.Error.Severity.RECOVERABLE,
  539. shaka.util.Error.Category.ADS,
  540. shaka.util.Error.Code.MT_AD_MANAGER_NOT_INITIALIZED);
  541. }
  542. this.mtAdManager_.addTrackingUrl(url);
  543. }
  544. /**
  545. * @override
  546. * @export
  547. */
  548. initServerSide(adContainer, video) {
  549. // Check that Client Side IMA SDK has been included
  550. // NOTE: (window['google'] && google.ima) check for any
  551. // IMA SDK, including SDK for Server Side ads.
  552. // The 3rd check insures we have the right SDK:
  553. // {google.ima.dai} is an object that's part of DAI IMA SDK
  554. // but not SS SDK.
  555. if (!window['google'] || !google.ima || !google.ima.dai) {
  556. throw new shaka.util.Error(
  557. shaka.util.Error.Severity.CRITICAL,
  558. shaka.util.Error.Category.ADS,
  559. shaka.util.Error.Code.SS_IMA_SDK_MISSING);
  560. }
  561. if (this.ssAdManager_) {
  562. this.ssAdManager_.release();
  563. }
  564. this.ssAdManager_ = new shaka.ads.ServerSideAdManager(
  565. adContainer, video, this.locale_,
  566. (e) => this.processAndDispatchEvent_(e));
  567. goog.asserts.assert(this.config_, 'Config must not be null!');
  568. this.ssAdManager_.configure(this.config_);
  569. }
  570. /**
  571. * @param {!google.ima.dai.api.StreamRequest} imaRequest
  572. * @param {string=} backupUrl
  573. * @return {!Promise<string>}
  574. * @override
  575. * @export
  576. */
  577. requestServerSideStream(imaRequest, backupUrl = '') {
  578. if (!this.ssAdManager_) {
  579. throw new shaka.util.Error(
  580. shaka.util.Error.Severity.RECOVERABLE,
  581. shaka.util.Error.Category.ADS,
  582. shaka.util.Error.Code.SS_AD_MANAGER_NOT_INITIALIZED);
  583. }
  584. if (!imaRequest.adTagParameters) {
  585. imaRequest.adTagParameters = {};
  586. }
  587. const adTagParams = imaRequest.adTagParameters;
  588. if (adTagParams['mpt'] || adTagParams['mpv']) {
  589. shaka.log.alwaysWarn('You have attempted to set "mpt" and/or "mpv" ' +
  590. 'parameters of the ad tag. Please note that those parameters are ' +
  591. 'used for Shaka adoption tracking and will be overridden.');
  592. }
  593. // Set player and version parameters for tracking
  594. imaRequest.adTagParameters['mpt'] = 'shaka-player';
  595. imaRequest.adTagParameters['mpv'] = shaka.Player.version;
  596. return this.ssAdManager_.streamRequest(imaRequest, backupUrl);
  597. }
  598. /**
  599. * @override
  600. * @export
  601. */
  602. replaceServerSideAdTagParameters(adTagParameters) {
  603. if (!this.ssAdManager_) {
  604. throw new shaka.util.Error(
  605. shaka.util.Error.Severity.RECOVERABLE,
  606. shaka.util.Error.Category.ADS,
  607. shaka.util.Error.Code.SS_AD_MANAGER_NOT_INITIALIZED);
  608. }
  609. if (adTagParameters['mpt'] || adTagParameters['mpv']) {
  610. shaka.log.alwaysWarn('You have attempted to set "mpt" and/or "mpv" ' +
  611. 'parameters of the ad tag. Please note that those parameters are ' +
  612. 'used for Shaka adoption tracking and will be overridden.');
  613. }
  614. adTagParameters['mpt'] = 'Shaka Player';
  615. adTagParameters['mpv'] = shaka.Player.version;
  616. this.ssAdManager_.replaceAdTagParameters(adTagParameters);
  617. }
  618. /**
  619. * @return {!Array<!shaka.extern.AdCuePoint>}
  620. * @override
  621. * @export
  622. */
  623. getServerSideCuePoints() {
  624. shaka.Deprecate.deprecateFeature(5,
  625. 'AdManager.getServerSideCuePoints',
  626. 'Please use getCuePoints function.');
  627. return this.getCuePoints();
  628. }
  629. /**
  630. * @return {!Array<!shaka.extern.AdCuePoint>}
  631. * @override
  632. * @export
  633. */
  634. getCuePoints() {
  635. let cuepoints = [];
  636. if (this.ssAdManager_) {
  637. cuepoints = cuepoints.concat(this.ssAdManager_.getCuePoints());
  638. }
  639. if (this.mtAdManager_) {
  640. cuepoints = cuepoints.concat(this.mtAdManager_.getCuePoints());
  641. }
  642. return cuepoints;
  643. }
  644. /**
  645. * @return {shaka.extern.AdsStats}
  646. * @override
  647. * @export
  648. */
  649. getStats() {
  650. return this.stats_.getBlob();
  651. }
  652. /**
  653. * @override
  654. * @export
  655. */
  656. onManifestUpdated(isLive) {
  657. if (this.mtAdManager_) {
  658. this.mtAdManager_.onManifestUpdated(isLive);
  659. }
  660. }
  661. /**
  662. * @override
  663. * @export
  664. */
  665. onDashTimedMetadata(region) {
  666. if (this.ssAdManager_ && region.schemeIdUri == 'urn:google:dai:2018') {
  667. const type = region.schemeIdUri;
  668. const data = region.eventNode ?
  669. region.eventNode.attributes['messageData'] : null;
  670. const timestamp = region.startTime;
  671. this.ssAdManager_.onTimedMetadata(type, data, timestamp);
  672. }
  673. }
  674. /**
  675. * @override
  676. * @export
  677. */
  678. onHlsTimedMetadata(metadata, timestamp) {
  679. if (this.ssAdManager_) {
  680. this.ssAdManager_.onTimedMetadata('ID3', metadata['data'], timestamp);
  681. }
  682. }
  683. /**
  684. * @override
  685. * @export
  686. */
  687. onCueMetadataChange(value) {
  688. if (this.ssAdManager_) {
  689. this.ssAdManager_.onCueMetadataChange(value);
  690. }
  691. }
  692. /**
  693. * @override
  694. * @export
  695. */
  696. onHLSInterstitialMetadata(basePlayer, baseVideo, interstitial) {
  697. if (this.config_ && this.config_.disableHLSInterstitial) {
  698. return;
  699. }
  700. if (!this.interstitialAdManager_) {
  701. this.initInterstitial(/* adContainer= */ null, basePlayer, baseVideo);
  702. }
  703. if (this.interstitialAdManager_) {
  704. this.interstitialAdManager_.addMetadata(interstitial);
  705. }
  706. }
  707. /**
  708. * @override
  709. * @export
  710. */
  711. onDASHInterstitialMetadata(basePlayer, baseVideo, region) {
  712. if (this.config_ && this.config_.disableDASHInterstitial) {
  713. return;
  714. }
  715. const schemeIdUri = region.schemeIdUri;
  716. if (schemeIdUri == 'urn:mpeg:dash:event:alternativeMPD:insert:2025' ||
  717. schemeIdUri == 'urn:mpeg:dash:event:alternativeMPD:replace:2025') {
  718. if (!this.interstitialAdManager_) {
  719. this.initInterstitial(/* adContainer= */ null, basePlayer, baseVideo);
  720. }
  721. if (this.interstitialAdManager_) {
  722. this.interstitialAdManager_.addRegion(region);
  723. }
  724. } else if ((schemeIdUri == 'urn:mpeg:dash:event:2012' ||
  725. schemeIdUri == 'urn:scte:dash:scte214-events') &&
  726. region.eventNode &&
  727. shaka.util.TXml.findChild(region.eventNode, 'OverlayEvent')) {
  728. if (!this.interstitialAdManager_) {
  729. this.initInterstitial(/* adContainer= */ null, basePlayer, baseVideo);
  730. }
  731. if (this.interstitialAdManager_) {
  732. this.interstitialAdManager_.addOverlayRegion(region);
  733. }
  734. }
  735. }
  736. /**
  737. * @override
  738. * @export
  739. */
  740. addCustomInterstitial(interstitial) {
  741. if (!this.interstitialAdManager_) {
  742. throw new shaka.util.Error(
  743. shaka.util.Error.Severity.RECOVERABLE,
  744. shaka.util.Error.Category.ADS,
  745. shaka.util.Error.Code.INTERSTITIAL_AD_MANAGER_NOT_INITIALIZED);
  746. }
  747. this.interstitialAdManager_.addInterstitials([interstitial]);
  748. }
  749. /**
  750. * @override
  751. * @export
  752. */
  753. addAdUrlInterstitial(url) {
  754. if (!this.interstitialAdManager_) {
  755. throw new shaka.util.Error(
  756. shaka.util.Error.Severity.RECOVERABLE,
  757. shaka.util.Error.Category.ADS,
  758. shaka.util.Error.Code.INTERSTITIAL_AD_MANAGER_NOT_INITIALIZED);
  759. }
  760. return this.interstitialAdManager_.addAdUrlInterstitial(url);
  761. }
  762. /**
  763. * @override
  764. * @export
  765. */
  766. getInterstitialPlayer() {
  767. if (!this.interstitialAdManager_) {
  768. throw new shaka.util.Error(
  769. shaka.util.Error.Severity.RECOVERABLE,
  770. shaka.util.Error.Category.ADS,
  771. shaka.util.Error.Code.INTERSTITIAL_AD_MANAGER_NOT_INITIALIZED);
  772. }
  773. return this.interstitialAdManager_.getPlayer();
  774. }
  775. /**
  776. * @param {!shaka.util.FakeEvent} event
  777. * @private
  778. */
  779. processAndDispatchEvent_(event) {
  780. if (event && event.type) {
  781. switch (event.type) {
  782. case shaka.ads.Utils.ADS_LOADED: {
  783. const loadTime = (/** @type {!Object} */ (event))['loadTime'];
  784. this.stats_.addLoadTime(loadTime);
  785. break;
  786. }
  787. case shaka.ads.Utils.AD_STARTED: {
  788. this.stats_.incrementStarted();
  789. const ad = (/** @type {!Object} */ (event))['ad'];
  790. if (ad && !ad.isLinear()) {
  791. this.stats_.incrementOverlayAds();
  792. }
  793. break;
  794. }
  795. case shaka.ads.Utils.AD_COMPLETE:
  796. this.stats_.incrementPlayedCompletely();
  797. break;
  798. case shaka.ads.Utils.AD_SKIPPED:
  799. this.stats_.incrementSkipped();
  800. break;
  801. case shaka.ads.Utils.AD_ERROR:
  802. this.stats_.incrementErrors();
  803. break;
  804. }
  805. }
  806. this.dispatchEvent(event);
  807. }
  808. };
  809. /**
  810. * The event name for when a sequence of ads has been loaded.
  811. *
  812. * Deprecated, please use {@link shaka.ads.Utils}
  813. *
  814. * @const {string}
  815. * @export
  816. * @deprecated
  817. */
  818. shaka.ads.AdManager.ADS_LOADED = 'ads-loaded';
  819. /**
  820. * The event name for when an ad has started playing.
  821. *
  822. * Deprecated, please use {@link shaka.ads.Utils}
  823. *
  824. * @const {string}
  825. * @export
  826. * @deprecated
  827. */
  828. shaka.ads.AdManager.AD_STARTED = 'ad-started';
  829. /**
  830. * The event name for when an ad playhead crosses first quartile.
  831. *
  832. * Deprecated, please use {@link shaka.ads.Utils}
  833. *
  834. * @const {string}
  835. * @export
  836. * @deprecated
  837. */
  838. shaka.ads.AdManager.AD_FIRST_QUARTILE = 'ad-first-quartile';
  839. /**
  840. * The event name for when an ad playhead crosses midpoint.
  841. *
  842. * Deprecated, please use {@link shaka.ads.Utils}
  843. *
  844. * @const {string}
  845. * @export
  846. * @deprecated
  847. */
  848. shaka.ads.AdManager.AD_MIDPOINT = 'ad-midpoint';
  849. /**
  850. * The event name for when an ad playhead crosses third quartile.
  851. *
  852. * Deprecated, please use {@link shaka.ads.Utils}
  853. *
  854. * @const {string}
  855. * @export
  856. * @deprecated
  857. */
  858. shaka.ads.AdManager.AD_THIRD_QUARTILE = 'ad-third-quartile';
  859. /**
  860. * The event name for when an ad has completed playing.
  861. *
  862. * Deprecated, please use {@link shaka.ads.Utils}
  863. *
  864. * @const {string}
  865. * @export
  866. * @deprecated
  867. */
  868. shaka.ads.AdManager.AD_COMPLETE = 'ad-complete';
  869. /**
  870. * The event name for when an ad has finished playing
  871. * (played all the way through, was skipped, or was unable to proceed
  872. * due to an error).
  873. *
  874. * Deprecated, please use {@link shaka.ads.Utils}
  875. *
  876. * @const {string}
  877. * @export
  878. * @deprecated
  879. */
  880. shaka.ads.AdManager.AD_STOPPED = 'ad-stopped';
  881. /**
  882. * The event name for when an ad is skipped by the user.
  883. *
  884. * Deprecated, please use {@link shaka.ads.Utils}
  885. *
  886. * @const {string}
  887. * @export
  888. * @deprecated
  889. */
  890. shaka.ads.AdManager.AD_SKIPPED = 'ad-skipped';
  891. /**
  892. * The event name for when the ad volume has changed.
  893. *
  894. * Deprecated, please use {@link shaka.ads.Utils}
  895. *
  896. * @const {string}
  897. * @export
  898. * @deprecated
  899. */
  900. shaka.ads.AdManager.AD_VOLUME_CHANGED = 'ad-volume-changed';
  901. /**
  902. * The event name for when the ad was muted.
  903. *
  904. * Deprecated, please use {@link shaka.ads.Utils}
  905. *
  906. * @const {string}
  907. * @export
  908. * @deprecated
  909. */
  910. shaka.ads.AdManager.AD_MUTED = 'ad-muted';
  911. /**
  912. * The event name for when the ad was paused.
  913. *
  914. * Deprecated, please use {@link shaka.ads.Utils}
  915. *
  916. * @const {string}
  917. * @export
  918. * @deprecated
  919. */
  920. shaka.ads.AdManager.AD_PAUSED = 'ad-paused';
  921. /**
  922. * The event name for when the ad was resumed after a pause.
  923. *
  924. * Deprecated, please use {@link shaka.ads.Utils}
  925. *
  926. * @const {string}
  927. * @export
  928. * @deprecated
  929. */
  930. shaka.ads.AdManager.AD_RESUMED = 'ad-resumed';
  931. /**
  932. * The event name for when the ad's skip status changes
  933. * (usually it becomes skippable when it wasn't before).
  934. *
  935. * Deprecated, please use {@link shaka.ads.Utils}
  936. *
  937. * @const {string}
  938. * @export
  939. * @deprecated
  940. */
  941. shaka.ads.AdManager.AD_SKIP_STATE_CHANGED = 'ad-skip-state-changed';
  942. /**
  943. * The event name for when the ad's cue points (start/end markers)
  944. * have changed.
  945. *
  946. * Deprecated, please use {@link shaka.ads.Utils}
  947. *
  948. * @const {string}
  949. * @export
  950. * @deprecated
  951. */
  952. shaka.ads.AdManager.CUEPOINTS_CHANGED = 'ad-cue-points-changed';
  953. /**
  954. * The event name for when the native IMA ad manager object has
  955. * loaded and become available.
  956. *
  957. * Deprecated, please use {@link shaka.ads.Utils}
  958. *
  959. * @const {string}
  960. * @export
  961. * @deprecated
  962. */
  963. shaka.ads.AdManager.IMA_AD_MANAGER_LOADED = 'ima-ad-manager-loaded';
  964. /**
  965. * The event name for when the native IMA stream manager object has
  966. * loaded and become available.
  967. *
  968. * Deprecated, please use {@link shaka.ads.Utils}
  969. *
  970. * @const {string}
  971. * @export
  972. * @deprecated
  973. */
  974. shaka.ads.AdManager.IMA_STREAM_MANAGER_LOADED = 'ima-stream-manager-loaded';
  975. /**
  976. * The event name for when the ad was clicked.
  977. *
  978. * Deprecated, please use {@link shaka.ads.Utils}
  979. *
  980. * @const {string}
  981. * @export
  982. * @deprecated
  983. */
  984. shaka.ads.AdManager.AD_CLICKED = 'ad-clicked';
  985. /**
  986. * The event name for when there is an update to the current ad's progress.
  987. *
  988. * Deprecated, please use {@link shaka.ads.Utils}
  989. *
  990. * @const {string}
  991. * @export
  992. * @deprecated
  993. */
  994. shaka.ads.AdManager.AD_PROGRESS = 'ad-progress';
  995. /**
  996. * The event name for when the ad is buffering.
  997. *
  998. * Deprecated, please use {@link shaka.ads.Utils}
  999. *
  1000. * @const {string}
  1001. * @export
  1002. * @deprecated
  1003. */
  1004. shaka.ads.AdManager.AD_BUFFERING = 'ad-buffering';
  1005. /**
  1006. * The event name for when the ad's URL was hit.
  1007. *
  1008. * Deprecated, please use {@link shaka.ads.Utils}
  1009. *
  1010. * @const {string}
  1011. * @export
  1012. * @deprecated
  1013. */
  1014. shaka.ads.AdManager.AD_IMPRESSION = 'ad-impression';
  1015. /**
  1016. * The event name for when the ad's duration changed.
  1017. *
  1018. * Deprecated, please use {@link shaka.ads.Utils}
  1019. *
  1020. * @const {string}
  1021. * @export
  1022. * @deprecated
  1023. */
  1024. shaka.ads.AdManager.AD_DURATION_CHANGED = 'ad-duration-changed';
  1025. /**
  1026. * The event name for when the ad was closed by the user.
  1027. *
  1028. * Deprecated, please use {@link shaka.ads.Utils}
  1029. *
  1030. * @const {string}
  1031. * @export
  1032. * @deprecated
  1033. */
  1034. shaka.ads.AdManager.AD_CLOSED = 'ad-closed';
  1035. /**
  1036. * The event name for when the ad data becomes available.
  1037. *
  1038. * Deprecated, please use {@link shaka.ads.Utils}
  1039. *
  1040. * @const {string}
  1041. * @export
  1042. * @deprecated
  1043. */
  1044. shaka.ads.AdManager.AD_LOADED = 'ad-loaded';
  1045. /**
  1046. * The event name for when all the ads were completed.
  1047. *
  1048. * Deprecated, please use {@link shaka.ads.Utils}
  1049. *
  1050. * @const {string}
  1051. * @export
  1052. * @deprecated
  1053. */
  1054. shaka.ads.AdManager.ALL_ADS_COMPLETED = 'all-ads-completed';
  1055. /**
  1056. * The event name for when the ad changes from or to linear.
  1057. *
  1058. * Deprecated, please use {@link shaka.ads.Utils}
  1059. *
  1060. * @const {string}
  1061. * @export
  1062. * @deprecated
  1063. */
  1064. shaka.ads.AdManager.AD_LINEAR_CHANGED = 'ad-linear-changed';
  1065. /**
  1066. * The event name for when the ad's metadata becomes available.
  1067. *
  1068. * Deprecated, please use {@link shaka.ads.Utils}
  1069. *
  1070. * @const {string}
  1071. * @export
  1072. * @deprecated
  1073. */
  1074. shaka.ads.AdManager.AD_METADATA = 'ad-metadata';
  1075. /**
  1076. * The event name for when the ad display encountered a recoverable
  1077. * error.
  1078. *
  1079. * Deprecated, please use {@link shaka.ads.Utils}
  1080. *
  1081. * @const {string}
  1082. * @export
  1083. * @deprecated
  1084. */
  1085. shaka.ads.AdManager.AD_RECOVERABLE_ERROR = 'ad-recoverable-error';
  1086. /**
  1087. * The event name for when the ad manager dispatch errors.
  1088. *
  1089. * Deprecated, please use {@link shaka.ads.Utils}
  1090. *
  1091. * @const {string}
  1092. * @export
  1093. * @deprecated
  1094. */
  1095. shaka.ads.AdManager.AD_ERROR = 'ad-error';
  1096. /**
  1097. * The event name for when the client side SDK signalled its readiness
  1098. * to play a VPAID ad or an ad rule.
  1099. *
  1100. * Deprecated, please use {@link shaka.ads.Utils}
  1101. *
  1102. * @const {string}
  1103. * @export
  1104. * @deprecated
  1105. */
  1106. shaka.ads.AdManager.AD_BREAK_READY = 'ad-break-ready';
  1107. /**
  1108. * The event name for when the interaction callback for the ad was
  1109. * triggered.
  1110. *
  1111. * Deprecated, please use {@link shaka.ads.Utils}
  1112. *
  1113. * @const {string}
  1114. * @export
  1115. * @deprecated
  1116. */
  1117. shaka.ads.AdManager.AD_INTERACTION = 'ad-interaction';
  1118. /**
  1119. * The name of the event for when an ad requires the main content to be paused.
  1120. * Fired when the platform does not support multiple media elements.
  1121. *
  1122. * Deprecated, please use {@link shaka.ads.Utils}
  1123. *
  1124. * @const {string}
  1125. * @export
  1126. * @deprecated
  1127. */
  1128. shaka.ads.AdManager.AD_CONTENT_PAUSE_REQUESTED = 'ad-content-pause-requested';
  1129. /**
  1130. * The name of the event for when an ad requires the main content to be resumed.
  1131. * Fired when the platform does not support multiple media elements.
  1132. *
  1133. * Deprecated, please use {@link shaka.ads.Utils}
  1134. *
  1135. * @const {string}
  1136. * @export
  1137. * @deprecated
  1138. */
  1139. shaka.ads.AdManager.AD_CONTENT_RESUME_REQUESTED = 'ad-content-resume-requested';
  1140. /**
  1141. * The name of the event for when an ad requires the video of the main content
  1142. * to be attached.
  1143. *
  1144. * Deprecated, please use {@link shaka.ads.Utils}
  1145. *
  1146. * @const {string}
  1147. * @export
  1148. * @deprecated
  1149. */
  1150. shaka.ads.AdManager.AD_CONTENT_ATTACH_REQUESTED = 'ad-content-attach-requested';
  1151. /**
  1152. * Set this is a default ad manager for the player.
  1153. * Apps can also set their own ad manager, if they'd like.
  1154. */
  1155. shaka.Player.setAdManagerFactory(() => new shaka.ads.AdManager());