Source: lib/ads/server_side_ad.js

  1. /*! @license
  2. * Shaka Player
  3. * Copyright 2016 Google LLC
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. goog.provide('shaka.ads.ServerSideAd');
  7. /**
  8. * @implements {shaka.extern.IAd}
  9. * @export
  10. */
  11. shaka.ads.ServerSideAd = class {
  12. /**
  13. * @param {google.ima.dai.api.Ad} imaAd
  14. * @param {HTMLMediaElement} video
  15. */
  16. constructor(imaAd, video) {
  17. /** @private {google.ima.dai.api.Ad} */
  18. this.ad_ = imaAd;
  19. /** @private {?google.ima.dai.api.AdProgressData} */
  20. this.adProgressData_ = null;
  21. /** @private {HTMLMediaElement} */
  22. this.video_ = video;
  23. }
  24. /**
  25. * @param {google.ima.dai.api.AdProgressData} data
  26. */
  27. setProgressData(data) {
  28. this.adProgressData_ = data;
  29. }
  30. /**
  31. * @override
  32. * @export
  33. */
  34. needsSkipUI() {
  35. return true;
  36. }
  37. /**
  38. * @override
  39. * @export
  40. */
  41. isClientRendering() {
  42. return false;
  43. }
  44. /**
  45. * @override
  46. * @export
  47. */
  48. hasCustomClick() {
  49. return true;
  50. }
  51. /**
  52. * @override
  53. * @export
  54. */
  55. isUsingAnotherMediaElement() {
  56. return false;
  57. }
  58. /**
  59. * @override
  60. * @export
  61. */
  62. getDuration() {
  63. if (!this.adProgressData_) {
  64. // Unknown yet
  65. return -1;
  66. }
  67. return this.adProgressData_.duration;
  68. }
  69. /**
  70. * @override
  71. * @export
  72. */
  73. getMinSuggestedDuration() {
  74. return this.getDuration();
  75. }
  76. /**
  77. * @override
  78. * @export
  79. */
  80. getRemainingTime() {
  81. if (!this.adProgressData_) {
  82. // Unknown yet
  83. return -1;
  84. }
  85. return this.adProgressData_.duration - this.adProgressData_.currentTime;
  86. }
  87. /**
  88. * @override
  89. * @export
  90. */
  91. isPaused() {
  92. return this.video_.paused;
  93. }
  94. /**
  95. * @override
  96. * @export
  97. */
  98. isSkippable() {
  99. return this.ad_.isSkippable();
  100. }
  101. /**
  102. * @override
  103. * @export
  104. */
  105. getTimeUntilSkippable() {
  106. const skipOffset = this.ad_.getSkipTimeOffset();
  107. const canSkipIn = this.getRemainingTime() - skipOffset;
  108. return Math.max(canSkipIn, 0);
  109. }
  110. /**
  111. * @override
  112. * @export
  113. */
  114. canSkipNow() {
  115. return this.getTimeUntilSkippable() == 0;
  116. }
  117. /**
  118. * @override
  119. * @export
  120. */
  121. skip() {
  122. this.video_.currentTime += this.getRemainingTime();
  123. }
  124. /**
  125. * @override
  126. * @export
  127. */
  128. pause() {
  129. return this.video_.pause();
  130. }
  131. /**
  132. * @override
  133. * @export
  134. */
  135. play() {
  136. return this.video_.play();
  137. }
  138. /**
  139. * @override
  140. * @export
  141. */
  142. getVolume() {
  143. return this.video_.volume;
  144. }
  145. /**
  146. * @override
  147. * @export
  148. */
  149. setVolume(volume) {
  150. this.video_.volume = volume;
  151. }
  152. /**
  153. * @override
  154. * @export
  155. */
  156. isMuted() {
  157. return this.video_.muted;
  158. }
  159. /**
  160. * @override
  161. * @export
  162. */
  163. isLinear() {
  164. return true;
  165. }
  166. /**
  167. * @override
  168. * @export
  169. */
  170. resize(width, height) {
  171. // Nothing
  172. }
  173. /**
  174. * @override
  175. * @export
  176. */
  177. setMuted(muted) {
  178. this.video_.muted = muted;
  179. }
  180. /**
  181. * @override
  182. * @export
  183. */
  184. getSequenceLength() {
  185. const podInfo = this.ad_.getAdPodInfo();
  186. if (podInfo == null) {
  187. // No pod, just one ad.
  188. return 1;
  189. }
  190. return podInfo.getTotalAds();
  191. }
  192. /**
  193. * @override
  194. * @export
  195. */
  196. getPositionInSequence() {
  197. const podInfo = this.ad_.getAdPodInfo();
  198. if (podInfo == null) {
  199. // No pod, just one ad.
  200. return 1;
  201. }
  202. return podInfo.getAdPosition();
  203. }
  204. /**
  205. * @override
  206. * @export
  207. */
  208. getTitle() {
  209. return this.ad_.getTitle();
  210. }
  211. /**
  212. * @override
  213. * @export
  214. */
  215. getDescription() {
  216. return this.ad_.getDescription();
  217. }
  218. /**
  219. * @override
  220. * @export
  221. */
  222. getVastMediaBitrate() {
  223. return 0;
  224. }
  225. /**
  226. * @override
  227. * @export
  228. */
  229. getVastMediaHeight() {
  230. return this.ad_.getVastMediaHeight();
  231. }
  232. /**
  233. * @override
  234. * @export
  235. */
  236. getVastMediaWidth() {
  237. return this.ad_.getVastMediaWidth();
  238. }
  239. /**
  240. * @override
  241. * @export
  242. */
  243. getAdId() {
  244. return this.ad_.getAdId();
  245. }
  246. /**
  247. * @override
  248. * @export
  249. */
  250. getCreativeAdId() {
  251. return this.ad_.getCreativeAdId();
  252. }
  253. /**
  254. * @override
  255. * @export
  256. */
  257. getAdvertiserName() {
  258. return this.ad_.getAdvertiserName();
  259. }
  260. /**
  261. * @override
  262. * @export
  263. */
  264. getMediaUrl() {
  265. return null;
  266. }
  267. /**
  268. * @override
  269. * @export
  270. */
  271. getTimeOffset() {
  272. const podInfo = this.ad_.getAdPodInfo();
  273. if (podInfo == null) {
  274. // Defaults to 0 if this ad is not part of a pod, or the pod is not part
  275. // of an ad playlist.
  276. return 0;
  277. }
  278. return podInfo.getTimeOffset();
  279. }
  280. /**
  281. * @override
  282. * @export
  283. */
  284. getPodIndex() {
  285. const podInfo = this.ad_.getAdPodInfo();
  286. if (podInfo == null) {
  287. // Defaults to 0 if this ad is not part of a pod, or the pod is not part
  288. // of an ad playlist.
  289. return 0;
  290. }
  291. return podInfo.getPodIndex();
  292. }
  293. /**
  294. * @override
  295. * @export
  296. */
  297. release() {
  298. this.ad_ = null;
  299. this.adProgressData_ = null;
  300. this.video_ = null;
  301. }
  302. };