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. 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. break;
  789. case shaka.ads.Utils.AD_COMPLETE:
  790. this.stats_.incrementPlayedCompletely();
  791. break;
  792. case shaka.ads.Utils.AD_SKIPPED:
  793. this.stats_.incrementSkipped();
  794. break;
  795. case shaka.ads.Utils.AD_ERROR:
  796. this.stats_.incrementErrors();
  797. break;
  798. }
  799. }
  800. this.dispatchEvent(event);
  801. }
  802. };
  803. /**
  804. * The event name for when a sequence of ads has been loaded.
  805. *
  806. * Deprecated, please use {@link shaka.ads.Utils}
  807. *
  808. * @const {string}
  809. * @export
  810. * @deprecated
  811. */
  812. shaka.ads.AdManager.ADS_LOADED = 'ads-loaded';
  813. /**
  814. * The event name for when an ad has started playing.
  815. *
  816. * Deprecated, please use {@link shaka.ads.Utils}
  817. *
  818. * @const {string}
  819. * @export
  820. * @deprecated
  821. */
  822. shaka.ads.AdManager.AD_STARTED = 'ad-started';
  823. /**
  824. * The event name for when an ad playhead crosses first quartile.
  825. *
  826. * Deprecated, please use {@link shaka.ads.Utils}
  827. *
  828. * @const {string}
  829. * @export
  830. * @deprecated
  831. */
  832. shaka.ads.AdManager.AD_FIRST_QUARTILE = 'ad-first-quartile';
  833. /**
  834. * The event name for when an ad playhead crosses midpoint.
  835. *
  836. * Deprecated, please use {@link shaka.ads.Utils}
  837. *
  838. * @const {string}
  839. * @export
  840. * @deprecated
  841. */
  842. shaka.ads.AdManager.AD_MIDPOINT = 'ad-midpoint';
  843. /**
  844. * The event name for when an ad playhead crosses third quartile.
  845. *
  846. * Deprecated, please use {@link shaka.ads.Utils}
  847. *
  848. * @const {string}
  849. * @export
  850. * @deprecated
  851. */
  852. shaka.ads.AdManager.AD_THIRD_QUARTILE = 'ad-third-quartile';
  853. /**
  854. * The event name for when an ad has completed playing.
  855. *
  856. * Deprecated, please use {@link shaka.ads.Utils}
  857. *
  858. * @const {string}
  859. * @export
  860. * @deprecated
  861. */
  862. shaka.ads.AdManager.AD_COMPLETE = 'ad-complete';
  863. /**
  864. * The event name for when an ad has finished playing
  865. * (played all the way through, was skipped, or was unable to proceed
  866. * due to an error).
  867. *
  868. * Deprecated, please use {@link shaka.ads.Utils}
  869. *
  870. * @const {string}
  871. * @export
  872. * @deprecated
  873. */
  874. shaka.ads.AdManager.AD_STOPPED = 'ad-stopped';
  875. /**
  876. * The event name for when an ad is skipped by the user.
  877. *
  878. * Deprecated, please use {@link shaka.ads.Utils}
  879. *
  880. * @const {string}
  881. * @export
  882. * @deprecated
  883. */
  884. shaka.ads.AdManager.AD_SKIPPED = 'ad-skipped';
  885. /**
  886. * The event name for when the ad volume has changed.
  887. *
  888. * Deprecated, please use {@link shaka.ads.Utils}
  889. *
  890. * @const {string}
  891. * @export
  892. * @deprecated
  893. */
  894. shaka.ads.AdManager.AD_VOLUME_CHANGED = 'ad-volume-changed';
  895. /**
  896. * The event name for when the ad was muted.
  897. *
  898. * Deprecated, please use {@link shaka.ads.Utils}
  899. *
  900. * @const {string}
  901. * @export
  902. * @deprecated
  903. */
  904. shaka.ads.AdManager.AD_MUTED = 'ad-muted';
  905. /**
  906. * The event name for when the ad was paused.
  907. *
  908. * Deprecated, please use {@link shaka.ads.Utils}
  909. *
  910. * @const {string}
  911. * @export
  912. * @deprecated
  913. */
  914. shaka.ads.AdManager.AD_PAUSED = 'ad-paused';
  915. /**
  916. * The event name for when the ad was resumed after a pause.
  917. *
  918. * Deprecated, please use {@link shaka.ads.Utils}
  919. *
  920. * @const {string}
  921. * @export
  922. * @deprecated
  923. */
  924. shaka.ads.AdManager.AD_RESUMED = 'ad-resumed';
  925. /**
  926. * The event name for when the ad's skip status changes
  927. * (usually it becomes skippable when it wasn't before).
  928. *
  929. * Deprecated, please use {@link shaka.ads.Utils}
  930. *
  931. * @const {string}
  932. * @export
  933. * @deprecated
  934. */
  935. shaka.ads.AdManager.AD_SKIP_STATE_CHANGED = 'ad-skip-state-changed';
  936. /**
  937. * The event name for when the ad's cue points (start/end markers)
  938. * have changed.
  939. *
  940. * Deprecated, please use {@link shaka.ads.Utils}
  941. *
  942. * @const {string}
  943. * @export
  944. * @deprecated
  945. */
  946. shaka.ads.AdManager.CUEPOINTS_CHANGED = 'ad-cue-points-changed';
  947. /**
  948. * The event name for when the native IMA ad manager object has
  949. * loaded and become available.
  950. *
  951. * Deprecated, please use {@link shaka.ads.Utils}
  952. *
  953. * @const {string}
  954. * @export
  955. * @deprecated
  956. */
  957. shaka.ads.AdManager.IMA_AD_MANAGER_LOADED = 'ima-ad-manager-loaded';
  958. /**
  959. * The event name for when the native IMA stream manager object has
  960. * loaded and become available.
  961. *
  962. * Deprecated, please use {@link shaka.ads.Utils}
  963. *
  964. * @const {string}
  965. * @export
  966. * @deprecated
  967. */
  968. shaka.ads.AdManager.IMA_STREAM_MANAGER_LOADED = 'ima-stream-manager-loaded';
  969. /**
  970. * The event name for when the ad was clicked.
  971. *
  972. * Deprecated, please use {@link shaka.ads.Utils}
  973. *
  974. * @const {string}
  975. * @export
  976. * @deprecated
  977. */
  978. shaka.ads.AdManager.AD_CLICKED = 'ad-clicked';
  979. /**
  980. * The event name for when there is an update to the current ad's progress.
  981. *
  982. * Deprecated, please use {@link shaka.ads.Utils}
  983. *
  984. * @const {string}
  985. * @export
  986. * @deprecated
  987. */
  988. shaka.ads.AdManager.AD_PROGRESS = 'ad-progress';
  989. /**
  990. * The event name for when the ad is buffering.
  991. *
  992. * Deprecated, please use {@link shaka.ads.Utils}
  993. *
  994. * @const {string}
  995. * @export
  996. * @deprecated
  997. */
  998. shaka.ads.AdManager.AD_BUFFERING = 'ad-buffering';
  999. /**
  1000. * The event name for when the ad's URL was hit.
  1001. *
  1002. * Deprecated, please use {@link shaka.ads.Utils}
  1003. *
  1004. * @const {string}
  1005. * @export
  1006. * @deprecated
  1007. */
  1008. shaka.ads.AdManager.AD_IMPRESSION = 'ad-impression';
  1009. /**
  1010. * The event name for when the ad's duration changed.
  1011. *
  1012. * Deprecated, please use {@link shaka.ads.Utils}
  1013. *
  1014. * @const {string}
  1015. * @export
  1016. * @deprecated
  1017. */
  1018. shaka.ads.AdManager.AD_DURATION_CHANGED = 'ad-duration-changed';
  1019. /**
  1020. * The event name for when the ad was closed by the user.
  1021. *
  1022. * Deprecated, please use {@link shaka.ads.Utils}
  1023. *
  1024. * @const {string}
  1025. * @export
  1026. * @deprecated
  1027. */
  1028. shaka.ads.AdManager.AD_CLOSED = 'ad-closed';
  1029. /**
  1030. * The event name for when the ad data becomes available.
  1031. *
  1032. * Deprecated, please use {@link shaka.ads.Utils}
  1033. *
  1034. * @const {string}
  1035. * @export
  1036. * @deprecated
  1037. */
  1038. shaka.ads.AdManager.AD_LOADED = 'ad-loaded';
  1039. /**
  1040. * The event name for when all the ads were completed.
  1041. *
  1042. * Deprecated, please use {@link shaka.ads.Utils}
  1043. *
  1044. * @const {string}
  1045. * @export
  1046. * @deprecated
  1047. */
  1048. shaka.ads.AdManager.ALL_ADS_COMPLETED = 'all-ads-completed';
  1049. /**
  1050. * The event name for when the ad changes from or to linear.
  1051. *
  1052. * Deprecated, please use {@link shaka.ads.Utils}
  1053. *
  1054. * @const {string}
  1055. * @export
  1056. * @deprecated
  1057. */
  1058. shaka.ads.AdManager.AD_LINEAR_CHANGED = 'ad-linear-changed';
  1059. /**
  1060. * The event name for when the ad's metadata becomes available.
  1061. *
  1062. * Deprecated, please use {@link shaka.ads.Utils}
  1063. *
  1064. * @const {string}
  1065. * @export
  1066. * @deprecated
  1067. */
  1068. shaka.ads.AdManager.AD_METADATA = 'ad-metadata';
  1069. /**
  1070. * The event name for when the ad display encountered a recoverable
  1071. * error.
  1072. *
  1073. * Deprecated, please use {@link shaka.ads.Utils}
  1074. *
  1075. * @const {string}
  1076. * @export
  1077. * @deprecated
  1078. */
  1079. shaka.ads.AdManager.AD_RECOVERABLE_ERROR = 'ad-recoverable-error';
  1080. /**
  1081. * The event name for when the ad manager dispatch errors.
  1082. *
  1083. * Deprecated, please use {@link shaka.ads.Utils}
  1084. *
  1085. * @const {string}
  1086. * @export
  1087. * @deprecated
  1088. */
  1089. shaka.ads.AdManager.AD_ERROR = 'ad-error';
  1090. /**
  1091. * The event name for when the client side SDK signalled its readiness
  1092. * to play a VPAID ad or an ad rule.
  1093. *
  1094. * Deprecated, please use {@link shaka.ads.Utils}
  1095. *
  1096. * @const {string}
  1097. * @export
  1098. * @deprecated
  1099. */
  1100. shaka.ads.AdManager.AD_BREAK_READY = 'ad-break-ready';
  1101. /**
  1102. * The event name for when the interaction callback for the ad was
  1103. * triggered.
  1104. *
  1105. * Deprecated, please use {@link shaka.ads.Utils}
  1106. *
  1107. * @const {string}
  1108. * @export
  1109. * @deprecated
  1110. */
  1111. shaka.ads.AdManager.AD_INTERACTION = 'ad-interaction';
  1112. /**
  1113. * The name of the event for when an ad requires the main content to be paused.
  1114. * Fired when the platform does not support multiple media elements.
  1115. *
  1116. * Deprecated, please use {@link shaka.ads.Utils}
  1117. *
  1118. * @const {string}
  1119. * @export
  1120. * @deprecated
  1121. */
  1122. shaka.ads.AdManager.AD_CONTENT_PAUSE_REQUESTED = 'ad-content-pause-requested';
  1123. /**
  1124. * The name of the event for when an ad requires the main content to be resumed.
  1125. * Fired when the platform does not support multiple media elements.
  1126. *
  1127. * Deprecated, please use {@link shaka.ads.Utils}
  1128. *
  1129. * @const {string}
  1130. * @export
  1131. * @deprecated
  1132. */
  1133. shaka.ads.AdManager.AD_CONTENT_RESUME_REQUESTED = 'ad-content-resume-requested';
  1134. /**
  1135. * The name of the event for when an ad requires the video of the main content
  1136. * to be attached.
  1137. *
  1138. * Deprecated, please use {@link shaka.ads.Utils}
  1139. *
  1140. * @const {string}
  1141. * @export
  1142. * @deprecated
  1143. */
  1144. shaka.ads.AdManager.AD_CONTENT_ATTACH_REQUESTED = 'ad-content-attach-requested';
  1145. /**
  1146. * Set this is a default ad manager for the player.
  1147. * Apps can also set their own ad manager, if they'd like.
  1148. */
  1149. shaka.Player.setAdManagerFactory(() => new shaka.ads.AdManager());