shaka-player 4.3.10 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (316) hide show
  1. package/.github/workflows/release-please.yaml +7 -0
  2. package/AUTHORS +9 -0
  3. package/CHANGELOG.md +295 -200
  4. package/CONTRIBUTORS +8 -0
  5. package/LICENSE +32 -0
  6. package/README.md +63 -10
  7. package/demo/autoTemplate.txt +40 -5
  8. package/demo/close_button.js +11 -0
  9. package/demo/common/asset.js +13 -1
  10. package/demo/common/assets.js +53 -3
  11. package/demo/common/message_ids.js +25 -1
  12. package/demo/config.js +69 -10
  13. package/demo/customWarning.txt +2 -2
  14. package/demo/index.html +3 -1
  15. package/demo/locales/en.json +26 -2
  16. package/demo/locales/source.json +105 -9
  17. package/demo/main.js +52 -9
  18. package/demo/search.js +3 -1
  19. package/demo/service_worker.js +3 -0
  20. package/dist/controls.css +1 -1
  21. package/dist/controls.css.map +1 -1
  22. package/dist/demo.compiled.debug.js +124 -112
  23. package/dist/demo.compiled.debug.map +3 -3
  24. package/dist/demo.compiled.js +124 -112
  25. package/dist/demo.compiled.map +3 -3
  26. package/dist/deps.js +46 -28
  27. package/dist/locales.js +28 -28
  28. package/dist/receiver.compiled.debug.js +52 -46
  29. package/dist/receiver.compiled.debug.map +3 -3
  30. package/dist/receiver.compiled.js +52 -46
  31. package/dist/receiver.compiled.map +3 -3
  32. package/dist/shaka-player.compiled.d.ts +676 -391
  33. package/dist/shaka-player.compiled.debug.d.ts +676 -391
  34. package/dist/shaka-player.compiled.debug.externs.js +1188 -616
  35. package/dist/shaka-player.compiled.debug.js +1045 -700
  36. package/dist/shaka-player.compiled.debug.map +4 -4
  37. package/dist/shaka-player.compiled.externs.js +1188 -616
  38. package/dist/shaka-player.compiled.js +1094 -933
  39. package/dist/shaka-player.compiled.map +4 -4
  40. package/dist/shaka-player.ui.d.ts +677 -392
  41. package/dist/shaka-player.ui.debug.d.ts +677 -392
  42. package/dist/shaka-player.ui.debug.externs.js +1023 -451
  43. package/dist/shaka-player.ui.debug.js +1100 -739
  44. package/dist/shaka-player.ui.debug.map +4 -4
  45. package/dist/shaka-player.ui.externs.js +1023 -451
  46. package/dist/shaka-player.ui.js +1244 -1071
  47. package/dist/shaka-player.ui.map +4 -4
  48. package/docs/tutorials/ad_monetization.md +15 -1
  49. package/docs/tutorials/application-level-redirects.md +1 -1
  50. package/docs/tutorials/config.md +9 -5
  51. package/docs/tutorials/drm-config.md +61 -0
  52. package/docs/tutorials/fairplay.md +19 -4
  53. package/docs/tutorials/license-server-auth.md +4 -4
  54. package/docs/tutorials/license-wrapping.md +2 -2
  55. package/docs/tutorials/ui-customization.md +7 -3
  56. package/docs/tutorials/ui.md +7 -7
  57. package/docs/tutorials/upgrade.md +3 -0
  58. package/externs/ima.js +123 -2
  59. package/externs/isoboxer.js +217 -0
  60. package/externs/mediakeys.js +18 -0
  61. package/externs/mux.js +1 -105
  62. package/externs/pictureinpicture.js +48 -0
  63. package/externs/shaka/ads.js +61 -1
  64. package/externs/shaka/cea.js +110 -0
  65. package/externs/shaka/codecs.js +32 -0
  66. package/externs/shaka/manifest.js +101 -1
  67. package/externs/shaka/manifest_parser.js +0 -10
  68. package/externs/shaka/net.js +36 -7
  69. package/externs/shaka/offline.js +8 -1
  70. package/externs/shaka/player.js +220 -21
  71. package/externs/shaka/text.js +1 -382
  72. package/externs/shaka/transmuxer.js +59 -0
  73. package/karma.conf.js +13 -0
  74. package/lib/abr/simple_abr_manager.js +6 -3
  75. package/lib/ads/ad_manager.js +60 -2
  76. package/lib/ads/client_side_ad.js +86 -0
  77. package/lib/ads/client_side_ad_manager.js +79 -3
  78. package/lib/ads/server_side_ad.js +86 -0
  79. package/lib/ads/server_side_ad_manager.js +13 -0
  80. package/lib/cast/cast_utils.js +1 -0
  81. package/lib/cea/cea608_data_channel.js +24 -14
  82. package/lib/cea/cea608_memory.js +5 -2
  83. package/lib/cea/cea708_service.js +8 -9
  84. package/lib/cea/cea708_window.js +1 -2
  85. package/lib/cea/cea_decoder.js +23 -6
  86. package/lib/cea/cea_utils.js +25 -2
  87. package/lib/cea/dummy_caption_decoder.js +21 -0
  88. package/lib/cea/dummy_cea_parser.js +1 -3
  89. package/lib/cea/mp4_cea_parser.js +15 -10
  90. package/lib/cea/ts_cea_parser.js +69 -0
  91. package/lib/dash/content_protection.js +32 -2
  92. package/lib/dash/dash_parser.js +93 -31
  93. package/lib/dash/mpd_utils.js +6 -25
  94. package/lib/dash/segment_base.js +12 -14
  95. package/lib/dash/segment_list.js +10 -6
  96. package/lib/dash/segment_template.js +349 -32
  97. package/lib/dependencies/all.js +8 -0
  98. package/lib/hls/hls_classes.js +33 -8
  99. package/lib/hls/hls_parser.js +805 -191
  100. package/lib/hls/manifest_text_parser.js +4 -14
  101. package/lib/media/adaptation_set_criteria.js +43 -3
  102. package/lib/media/closed_caption_parser.js +74 -12
  103. package/lib/media/drm_engine.js +189 -49
  104. package/lib/media/gap_jumping_controller.js +1 -1
  105. package/lib/media/manifest_parser.js +34 -0
  106. package/lib/media/media_source_capabilities.js +10 -0
  107. package/lib/media/media_source_engine.js +475 -231
  108. package/lib/media/playhead.js +1 -1
  109. package/lib/media/presentation_timeline.js +62 -0
  110. package/lib/media/segment_index.js +50 -14
  111. package/lib/media/segment_prefetch.js +277 -0
  112. package/lib/media/segment_reference.js +70 -4
  113. package/lib/media/streaming_engine.js +258 -81
  114. package/lib/media/video_wrapper.js +15 -7
  115. package/lib/mss/content_protection.js +353 -0
  116. package/lib/mss/mss_parser.js +1081 -0
  117. package/lib/net/networking_engine.js +60 -10
  118. package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
  119. package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
  120. package/lib/offline/manifest_converter.js +6 -0
  121. package/lib/offline/storage.js +2 -4
  122. package/lib/player.js +309 -105
  123. package/lib/polyfill/media_capabilities.js +43 -3
  124. package/lib/polyfill/patchedmediakeys_apple.js +5 -0
  125. package/lib/polyfill/patchedmediakeys_nop.js +5 -0
  126. package/lib/polyfill/patchedmediakeys_webkit.js +5 -0
  127. package/lib/text/cue.js +208 -130
  128. package/lib/text/lrc_text_parser.js +2 -2
  129. package/lib/text/mp4_vtt_parser.js +2 -2
  130. package/lib/text/sbv_text_parser.js +1 -1
  131. package/lib/text/simple_text_displayer.js +2 -1
  132. package/lib/text/srt_text_parser.js +9 -1
  133. package/lib/text/ssa_text_parser.js +2 -2
  134. package/lib/text/text_engine.js +3 -21
  135. package/lib/text/text_utils.js +71 -20
  136. package/lib/text/ui_text_displayer.js +14 -14
  137. package/lib/text/vtt_text_parser.js +22 -14
  138. package/lib/transmuxer/aac_transmuxer.js +224 -0
  139. package/lib/transmuxer/ac3.js +142 -0
  140. package/lib/transmuxer/ac3_transmuxer.js +212 -0
  141. package/lib/transmuxer/adts.js +232 -0
  142. package/lib/transmuxer/ec3.js +103 -0
  143. package/lib/transmuxer/ec3_transmuxer.js +212 -0
  144. package/lib/transmuxer/h264.js +324 -0
  145. package/lib/transmuxer/mp3_transmuxer.js +204 -0
  146. package/lib/transmuxer/mpeg_audio.js +196 -0
  147. package/lib/transmuxer/mpeg_ts_transmuxer.js +182 -0
  148. package/lib/transmuxer/mss_transmuxer.js +389 -0
  149. package/lib/{media/transmuxer.js → transmuxer/muxjs_transmuxer.js} +34 -80
  150. package/lib/transmuxer/transmuxer_engine.js +161 -0
  151. package/lib/transmuxer/ts_transmuxer.js +738 -0
  152. package/lib/util/cmcd_manager.js +131 -71
  153. package/lib/util/error.js +62 -26
  154. package/lib/util/exp_golomb.js +220 -0
  155. package/lib/util/fairplay_utils.js +64 -13
  156. package/lib/util/id3_utils.js +56 -3
  157. package/lib/util/language_utils.js +11 -8
  158. package/lib/util/manifest_parser_utils.js +3 -0
  159. package/lib/util/mime_utils.js +44 -7
  160. package/lib/util/mp4_box_parsers.js +233 -5
  161. package/lib/util/mp4_generator.js +1381 -0
  162. package/lib/util/periods.js +40 -34
  163. package/lib/util/platform.js +17 -3
  164. package/lib/util/player_configuration.js +38 -1
  165. package/lib/util/stream_utils.js +138 -27
  166. package/lib/util/text_parser.js +1 -1
  167. package/lib/util/ts_parser.js +470 -47
  168. package/lib/util/xml_utils.js +16 -3
  169. package/maintained-branches.md +2 -2
  170. package/package.json +3 -1
  171. package/roadmap.md +21 -6
  172. package/shaka-player.uncompiled.js +18 -0
  173. package/test/abr/simple_abr_manager_unit.js +32 -4
  174. package/test/ads/ad_manager_unit.js +18 -2
  175. package/test/cast/cast_utils_unit.js +7 -2
  176. package/test/cea/cea608_memory_unit.js +24 -0
  177. package/test/cea/cea_decoder_unit.js +33 -0
  178. package/test/dash/dash_parser_content_protection_unit.js +93 -3
  179. package/test/dash/dash_parser_live_unit.js +56 -13
  180. package/test/dash/dash_parser_manifest_unit.js +70 -2
  181. package/test/dash/dash_parser_segment_base_unit.js +14 -9
  182. package/test/dash/dash_parser_segment_template_unit.js +286 -6
  183. package/test/demo/demo_unit.js +5 -1
  184. package/test/hls/hls_live_unit.js +188 -28
  185. package/test/hls/hls_parser_unit.js +250 -109
  186. package/test/hls/manifest_text_parser_unit.js +18 -13
  187. package/test/media/adaptation_set_criteria_unit.js +46 -14
  188. package/test/media/adaptation_set_unit.js +2 -0
  189. package/test/media/drm_engine_integration.js +11 -8
  190. package/test/media/drm_engine_unit.js +220 -7
  191. package/test/media/media_source_engine_integration.js +122 -38
  192. package/test/media/media_source_engine_unit.js +133 -153
  193. package/test/media/playhead_unit.js +3 -0
  194. package/test/media/presentation_timeline_unit.js +51 -0
  195. package/test/media/segment_index_unit.js +52 -0
  196. package/test/media/segment_prefetch_unit.js +243 -0
  197. package/test/media/streaming_engine_integration.js +9 -3
  198. package/test/media/streaming_engine_unit.js +440 -59
  199. package/test/mss/mss_parser_content_protection_unit.js +49 -0
  200. package/test/mss/mss_parser_unit.js +472 -0
  201. package/test/mss/mss_player_integration.js +123 -0
  202. package/test/offline/manifest_convert_unit.js +9 -0
  203. package/test/offline/storage_integration.js +6 -1
  204. package/test/player_unit.js +386 -133
  205. package/test/polyfill/media_capabilities_unit.js +18 -0
  206. package/test/test/assets/hls-raw-aac/fileSequence0.aac +0 -0
  207. package/test/test/assets/hls-raw-aac/fileSequence1.aac +0 -0
  208. package/test/test/assets/hls-raw-aac/fileSequence2.aac +0 -0
  209. package/test/test/assets/hls-raw-aac/fileSequence3.aac +0 -0
  210. package/test/test/assets/hls-raw-aac/manifest.m3u8 +4 -0
  211. package/test/test/assets/hls-raw-aac/stream.m4a.m3u8 +14 -0
  212. package/test/test/assets/hls-raw-ac3/fileSequence0.ac3 +0 -0
  213. package/test/test/assets/hls-raw-ac3/fileSequence1.ac3 +0 -0
  214. package/test/test/assets/hls-raw-ac3/fileSequence2.ac3 +0 -0
  215. package/test/test/assets/hls-raw-ac3/fileSequence3.ac3 +0 -0
  216. package/test/test/assets/hls-raw-ac3/fileSequence4.ac3 +0 -0
  217. package/test/test/assets/hls-raw-ac3/fileSequence5.ac3 +0 -0
  218. package/test/test/assets/hls-raw-ac3/fileSequence6.ac3 +0 -0
  219. package/test/test/assets/hls-raw-ac3/fileSequence7.ac3 +0 -0
  220. package/test/test/assets/hls-raw-ac3/prog_index.m3u8 +31 -0
  221. package/test/test/assets/hls-raw-ec3/fileSequence0.ec3 +0 -0
  222. package/test/test/assets/hls-raw-ec3/fileSequence1.ec3 +0 -0
  223. package/test/test/assets/hls-raw-ec3/fileSequence2.ec3 +0 -0
  224. package/test/test/assets/hls-raw-ec3/fileSequence3.ec3 +0 -0
  225. package/test/test/assets/hls-raw-ec3/fileSequence4.ec3 +0 -0
  226. package/test/test/assets/hls-raw-ec3/fileSequence5.ec3 +0 -0
  227. package/test/test/assets/hls-raw-ec3/fileSequence6.ec3 +0 -0
  228. package/test/test/assets/hls-raw-ec3/fileSequence7.ec3 +0 -0
  229. package/test/test/assets/hls-raw-ec3/prog_index.m3u8 +31 -0
  230. package/test/test/assets/hls-raw-mp3/chunklist_w905519204.m3u8 +13 -0
  231. package/test/test/assets/hls-raw-mp3/media_w905519204_0.mp3 +0 -0
  232. package/test/test/assets/hls-raw-mp3/media_w905519204_1.mp3 +0 -0
  233. package/test/test/assets/hls-raw-mp3/media_w905519204_2.mp3 +0 -0
  234. package/test/test/assets/hls-raw-mp3/media_w905519204_3.mp3 +0 -0
  235. package/test/test/assets/hls-raw-mp3/playlist.m3u8 +4 -0
  236. package/test/test/assets/hls-ts-aac/playlist.m3u8 +23 -0
  237. package/test/test/assets/hls-ts-aac/segment_0.ts +0 -0
  238. package/test/test/assets/hls-ts-aac/segment_1.ts +0 -0
  239. package/test/test/assets/hls-ts-aac/segment_2.ts +0 -0
  240. package/test/test/assets/hls-ts-aac/segment_3.ts +0 -0
  241. package/test/test/assets/hls-ts-aac/segment_4.ts +0 -0
  242. package/test/test/assets/hls-ts-aac/segment_5.ts +0 -0
  243. package/test/test/assets/hls-ts-aac/segment_6.ts +0 -0
  244. package/test/test/assets/hls-ts-aac/segment_7.ts +0 -0
  245. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0000.ts +0 -0
  246. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0001.ts +0 -0
  247. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0002.ts +0 -0
  248. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0003.ts +0 -0
  249. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0004.ts +0 -0
  250. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0005.ts +0 -0
  251. package/test/test/assets/hls-ts-ac3/prog_index.m3u8 +19 -0
  252. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0000.ts +0 -0
  253. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0001.ts +0 -0
  254. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0002.ts +0 -0
  255. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0003.ts +0 -0
  256. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0004.ts +0 -0
  257. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0005.ts +0 -0
  258. package/test/test/assets/hls-ts-ec3/prog_index.m3u8 +19 -0
  259. package/test/test/assets/hls-ts-h264/fileSequence0.ts +0 -0
  260. package/test/test/assets/hls-ts-h264/fileSequence1.ts +0 -0
  261. package/test/test/assets/hls-ts-h264/fileSequence2.ts +0 -0
  262. package/test/test/assets/hls-ts-h264/fileSequence3.ts +0 -0
  263. package/test/test/assets/hls-ts-h264/fileSequence4.ts +0 -0
  264. package/test/test/assets/hls-ts-h264/fileSequence5.ts +0 -0
  265. package/test/test/assets/hls-ts-h264/prog_index.m3u8 +25 -0
  266. package/test/test/assets/hls-ts-mp3/manifest.m3u8 +13 -0
  267. package/test/test/assets/hls-ts-mp3/media_w239891843_0.ts +0 -0
  268. package/test/test/assets/hls-ts-mp3/media_w239891843_1.ts +0 -0
  269. package/test/test/assets/hls-ts-mp3/media_w239891843_2.ts +0 -0
  270. package/test/test/assets/hls-ts-mp3/media_w239891843_3.ts +0 -0
  271. package/test/test/assets/hls-ts-muxed-aac-h264/chunk.m3u8 +17 -0
  272. package/test/test/assets/hls-ts-muxed-aac-h264/n_0_0_0.ts +0 -0
  273. package/test/test/assets/hls-ts-muxed-aac-h264/n_1_0_0.ts +0 -0
  274. package/test/test/assets/hls-ts-muxed-aac-h264/n_2_0_0.ts +0 -0
  275. package/test/test/assets/hls-ts-muxed-aac-h264/n_3_0_0.ts +0 -0
  276. package/test/test/assets/hls-ts-muxed-aac-h264/n_4_0_0.ts +0 -0
  277. package/test/test/assets/hls-ts-muxed-aac-h264/n_5_0_0.ts +0 -0
  278. package/test/test/assets/hls-ts-muxed-aac-h264/playlist.m3u8 +4 -0
  279. package/test/test/boot.js +7 -2
  280. package/test/test/util/fake_ad.js +99 -0
  281. package/test/test/util/fake_ad_manager.js +7 -1
  282. package/test/test/util/fake_networking_engine.js +41 -14
  283. package/test/test/util/fake_segment_prefetch.js +81 -0
  284. package/test/test/util/manifest_generator.js +19 -5
  285. package/test/test/util/mss_parser_util.js +115 -0
  286. package/test/test/util/offline_utils.js +1 -0
  287. package/test/test/util/simple_fakes.js +12 -3
  288. package/test/test/util/streaming_engine_util.js +14 -4
  289. package/test/test/util/ttml_utils.js +2 -2
  290. package/test/text/cue_integration.js +1 -1
  291. package/test/text/srt_text_parser_unit.js +78 -0
  292. package/test/text/text_engine_unit.js +17 -8
  293. package/test/text/ui_text_displayer_unit.js +4 -4
  294. package/test/text/vtt_text_parser_unit.js +59 -40
  295. package/test/text/web_vtt_generator_unit.js +9 -3
  296. package/test/{media/transmuxer_integration.js → transmuxer/muxjs_transmuxer_integration.js} +30 -33
  297. package/test/transmuxer/transmuxer_engine_integration.js +60 -0
  298. package/test/transmuxer/transmuxer_integration.js +296 -0
  299. package/test/util/cmcd_manager_unit.js +162 -13
  300. package/test/util/language_utils_unit.js +9 -2
  301. package/test/util/mp4_box_parsers_unit.js +39 -4
  302. package/test/util/periods_unit.js +34 -26
  303. package/test/util/stream_utils_unit.js +60 -107
  304. package/ui/controls.js +19 -1
  305. package/ui/controls.less +1 -0
  306. package/ui/externs/ui.js +11 -1
  307. package/ui/language_utils.js +15 -0
  308. package/ui/less/thumbnails.less +26 -0
  309. package/ui/locales/oc.json +42 -0
  310. package/ui/pip_button.js +83 -2
  311. package/ui/range_element.js +15 -0
  312. package/ui/resolution_selection.js +9 -2
  313. package/ui/seek_bar.js +223 -0
  314. package/ui/ui.js +5 -0
  315. package/lib/cea/i_caption_decoder.js +0 -51
  316. package/lib/cea/i_cea_parser.js +0 -68
@@ -135,7 +135,7 @@ shaka.text.Mp4VttParser = class {
135
135
  box.version == 0 || box.version == 1,
136
136
  'TFDT version can only be 0 or 1');
137
137
 
138
- const parsedTFDTBox = shaka.util.Mp4BoxParsers.parseTFDT(
138
+ const parsedTFDTBox = shaka.util.Mp4BoxParsers.parseTFDTInaccurate(
139
139
  box.reader, box.version);
140
140
  baseTime = parsedTFDTBox.baseMediaDecodeTime;
141
141
  })
@@ -250,7 +250,7 @@ shaka.text.Mp4VttParser = class {
250
250
  'MDAT which contain VTT cues and non-VTT data are not currently ' +
251
251
  'supported!');
252
252
 
253
- return /** @type {!Array.<!shaka.extern.Cue>} */ (
253
+ return /** @type {!Array.<!shaka.text.Cue>} */ (
254
254
  cues.filter(shaka.util.Functional.isNotNull));
255
255
  }
256
256
 
@@ -50,7 +50,7 @@ shaka.text.SbvTextParser = class {
50
50
  // trim white space start and end
51
51
  str = str.trim();
52
52
 
53
- /** @type {!Array.<!shaka.extern.Cue>} */
53
+ /** @type {!Array.<!shaka.text.Cue>} */
54
54
  const cues = [];
55
55
 
56
56
  // Supports no cues
@@ -51,6 +51,7 @@ shaka.text.SimpleTextDisplayer = class {
51
51
  // kinds which can be displayed in the app's UI.
52
52
  this.textTrack_ = video.addTextTrack(
53
53
  'subtitles', shaka.Player.TextTrackLabel);
54
+ console.log(this.textTrack_);
54
55
  }
55
56
  this.textTrack_.mode = 'hidden';
56
57
  }
@@ -179,7 +180,7 @@ shaka.text.SimpleTextDisplayer = class {
179
180
  }
180
181
 
181
182
  /**
182
- * @param {!shaka.extern.Cue} shakaCue
183
+ * @param {!shaka.text.Cue} shakaCue
183
184
  * @return {TextTrackCue}
184
185
  * @private
185
186
  */
@@ -110,7 +110,15 @@ shaka.text.SrtTextParser = class {
110
110
  // convert time codes
111
111
  lines[0] = lines[0].replace(/,/g, '.');
112
112
 
113
- return lines.join('\n') + '\n\n';
113
+ const webvttCue = lines.join('\n')
114
+ .replace(/{b}/g, '<b>')
115
+ .replace(/{\/b}/g, '</b>')
116
+ .replace(/{i}/g, '<i>')
117
+ .replace(/{\/i}/g, '</i>')
118
+ .replace(/{u}/g, '<u>')
119
+ .replace(/{\/u}/g, '</u>');
120
+
121
+ return webvttCue + '\n\n';
114
122
  }
115
123
  };
116
124
 
@@ -105,7 +105,7 @@ shaka.text.SsaTextParser = class {
105
105
  }
106
106
 
107
107
  // Process cues
108
- /** @type {!Array.<!shaka.extern.Cue>} */
108
+ /** @type {!Array.<!shaka.text.Cue>} */
109
109
  const cues = [];
110
110
 
111
111
  // Used to be able to iterate over the event parameters.
@@ -160,7 +160,7 @@ shaka.text.SsaTextParser = class {
160
160
  /**
161
161
  * Adds applicable style properties to a cue.
162
162
  *
163
- * @param {shaka.extern.Cue} cue
163
+ * @param {shaka.text.Cue} cue
164
164
  * @param {Object} style
165
165
  * @private
166
166
  */
@@ -8,11 +8,11 @@ goog.provide('shaka.text.TextEngine');
8
8
 
9
9
  goog.require('goog.asserts');
10
10
  goog.require('shaka.log');
11
+ goog.require('shaka.media.ClosedCaptionParser');
11
12
  goog.require('shaka.text.Cue');
12
13
  goog.require('shaka.util.BufferUtils');
13
14
  goog.require('shaka.util.IDestroyable');
14
15
  goog.require('shaka.util.MimeUtils');
15
- goog.requireType('shaka.cea.ICaptionDecoder');
16
16
 
17
17
 
18
18
  // TODO: revisit this when Closure Compiler supports partially-exported classes.
@@ -100,8 +100,7 @@ shaka.text.TextEngine = class {
100
100
  }
101
101
  if (mimeType == shaka.util.MimeUtils.CEA608_CLOSED_CAPTION_MIMETYPE ||
102
102
  mimeType == shaka.util.MimeUtils.CEA708_CLOSED_CAPTION_MIMETYPE ) {
103
- // Closed captions.
104
- return true;
103
+ return !!shaka.media.ClosedCaptionParser.findDecoder();
105
104
  }
106
105
  return false;
107
106
  }
@@ -345,23 +344,6 @@ shaka.text.TextEngine = class {
345
344
  }
346
345
  }
347
346
 
348
- /**
349
- * @param {!Array<muxjs.mp4.ClosedCaption>} closedCaptions
350
- * @return {!Array<!shaka.cea.ICaptionDecoder.ClosedCaption>}
351
- */
352
- convertMuxjsCaptionsToShakaCaptions(closedCaptions) {
353
- const cues = [];
354
- for (const caption of closedCaptions) {
355
- const cue = new shaka.text.Cue(
356
- caption.startTime, caption.endTime, caption.text);
357
- cues.push({
358
- stream: caption.stream,
359
- cue,
360
- });
361
- }
362
- return cues;
363
- }
364
-
365
347
  /**
366
348
  * @param {!shaka.text.Cue} cue the cue to apply the timestamp to recursively
367
349
  * @param {number} videoTimestampOffset the timestamp offset of the video
@@ -379,7 +361,7 @@ shaka.text.TextEngine = class {
379
361
  * Store the closed captions in the text engine, and append the cues to the
380
362
  * text displayer. This is a side-channel used for embedded text only.
381
363
  *
382
- * @param {!Array.<!shaka.cea.ICaptionDecoder.ClosedCaption>} closedCaptions
364
+ * @param {!Array<!shaka.extern.ICaptionDecoder.ClosedCaption>} closedCaptions
383
365
  * @param {?number} startTime relative to the start of the presentation
384
366
  * @param {?number} endTime relative to the start of the presentation
385
367
  * @param {number} videoTimestampOffset the timestamp offset of the video
@@ -19,40 +19,91 @@ shaka.text.Utils = class {
19
19
  * @private
20
20
  */
21
21
  static flattenPayload_(cue) {
22
- // Handle styles (currently bold/italics/underline).
23
- // TODO: add support for color rendering.
22
+ if (cue.lineBreak) {
23
+ // This is a vertical lineBreak, so insert a newline.
24
+ return '\n';
25
+ }
26
+ if (cue.nestedCues.length) {
27
+ return cue.nestedCues.map(shaka.text.Utils.flattenPayload_).join('');
28
+ }
29
+
30
+ // Handle bold, italics and underline
24
31
  const openStyleTags = [];
25
32
  const bold = cue.fontWeight >= shaka.text.Cue.fontWeight.BOLD;
26
33
  const italics = cue.fontStyle == shaka.text.Cue.fontStyle.ITALIC;
27
34
  const underline = cue.textDecoration.includes(
28
35
  shaka.text.Cue.textDecoration.UNDERLINE);
29
36
  if (bold) {
30
- openStyleTags.push('b');
37
+ openStyleTags.push(['b']);
31
38
  }
32
39
  if (italics) {
33
- openStyleTags.push('i');
40
+ openStyleTags.push(['i']);
34
41
  }
35
42
  if (underline) {
36
- openStyleTags.push('u');
43
+ openStyleTags.push(['u']);
44
+ }
45
+ // Handle color classes, if the value consists of letters
46
+ let classes = '';
47
+ const color = shaka.text.Utils.getColorName_(cue.color);
48
+ if (color) {
49
+ classes += `.${color}`;
50
+ }
51
+ const bgColor = shaka.text.Utils.getColorName_(cue.backgroundColor);
52
+ if (bgColor) {
53
+ classes += `.bg_${bgColor}`;
54
+ }
55
+ if (classes) {
56
+ openStyleTags.push(['c', classes]);
37
57
  }
38
58
 
39
- // Prefix opens tags, suffix closes tags in reverse order of opening.
40
- const prefixStyleTags = openStyleTags.reduce((acc, tag) => {
41
- return `${acc}<${tag}>`;
42
- }, '');
43
- const suffixStyleTags = openStyleTags.reduceRight((acc, tag) => {
44
- return `${acc}</${tag}>`;
45
- }, '');
59
+ return openStyleTags.reduceRight((acc, [tag, classes = '']) => {
60
+ return `<${tag}${classes}>${acc}</${tag}>`;
61
+ }, cue.payload);
62
+ }
46
63
 
47
- if (cue.lineBreak) {
48
- // This is a vertical lineBreak, so insert a newline.
49
- return '\n';
50
- } else if (cue.nestedCues.length) {
51
- return cue.nestedCues.map(shaka.text.Utils.flattenPayload_).join('');
52
- } else {
53
- // This is a real cue.
54
- return prefixStyleTags + cue.payload + suffixStyleTags;
64
+ /**
65
+ * Gets the color name from a color string.
66
+ *
67
+ * @param {string} string
68
+ * @return {?string}
69
+ * @private
70
+ */
71
+ static getColorName_(string) {
72
+ switch (string.toLowerCase()) {
73
+ case 'white':
74
+ case '#fff':
75
+ case '#ffffff':
76
+ return 'white';
77
+ case 'lime':
78
+ case '#0f0':
79
+ case '#00ff00':
80
+ return 'lime';
81
+ case 'cyan':
82
+ case '#0ff':
83
+ case '#00ffff':
84
+ return 'cyan';
85
+ case 'red':
86
+ case '#f00':
87
+ case '#ff0000':
88
+ return 'red';
89
+ case 'yellow':
90
+ case '#ff0':
91
+ case '#ffff00':
92
+ return 'yellow';
93
+ case 'magenta':
94
+ case '#f0f':
95
+ return 'magenta';
96
+ case 'blue':
97
+ case '#00f':
98
+ case '#0000ff':
99
+ return 'blue';
100
+ case 'black':
101
+ case '#000':
102
+ case '#000000':
103
+ return 'black';
55
104
  }
105
+ // No color name
106
+ return null;
56
107
  }
57
108
 
58
109
  /**
@@ -75,7 +75,7 @@ shaka.text.UITextDisplayer = class {
75
75
  /**
76
76
  * Maps cues to cue elements. Specifically points out the wrapper element of
77
77
  * the cue (e.g. the HTML element to put nested cues inside).
78
- * @private {Map.<!shaka.extern.Cue, !{
78
+ * @private {Map.<!shaka.text.Cue, !{
79
79
  * cueElement: !HTMLElement,
80
80
  * regionElement: HTMLElement,
81
81
  * wrapper: !HTMLElement
@@ -213,10 +213,10 @@ shaka.text.UITextDisplayer = class {
213
213
  }
214
214
 
215
215
  /**
216
- * @param {!Array.<!shaka.extern.Cue>} cues
216
+ * @param {!Array.<!shaka.text.Cue>} cues
217
217
  * @param {!HTMLElement} container
218
218
  * @param {number} currentTime
219
- * @param {!Array.<!shaka.extern.Cue>} parents
219
+ * @param {!Array.<!shaka.text.Cue>} parents
220
220
  * @private
221
221
  */
222
222
  updateCuesRecursive_(cues, container, currentTime, parents) {
@@ -235,7 +235,7 @@ shaka.text.UITextDisplayer = class {
235
235
  * The cues whose corresponding elements should be in the DOM.
236
236
  * Some of these might be new, some might have been displayed beforehand.
237
237
  * These will only be added if updateDOM is true.
238
- * @type {!Array.<!shaka.extern.Cue>}
238
+ * @type {!Array.<!shaka.text.Cue>}
239
239
  */
240
240
  const toPlant = [];
241
241
  for (const cue of cues) {
@@ -375,7 +375,7 @@ shaka.text.UITextDisplayer = class {
375
375
  * Compute a unique internal id:
376
376
  * Regions can reuse the id but have different dimensions, we need to
377
377
  * consider those differences
378
- * @param {shaka.extern.CueRegion} region
378
+ * @param {shaka.text.CueRegion} region
379
379
  * @private
380
380
  */
381
381
  generateRegionId_(region) {
@@ -394,7 +394,7 @@ shaka.text.UITextDisplayer = class {
394
394
  * Get or create a region element corresponding to the cue region. These are
395
395
  * cached by ID.
396
396
  *
397
- * @param {!shaka.extern.Cue} cue
397
+ * @param {!shaka.text.Cue} cue
398
398
  * @return {!HTMLElement}
399
399
  * @private
400
400
  */
@@ -442,8 +442,8 @@ shaka.text.UITextDisplayer = class {
442
442
  /**
443
443
  * Creates the object for a cue.
444
444
  *
445
- * @param {!shaka.extern.Cue} cue
446
- * @param {!Array.<!shaka.extern.Cue>} parents
445
+ * @param {!shaka.text.Cue} cue
446
+ * @param {!Array.<!shaka.text.Cue>} parents
447
447
  * @private
448
448
  */
449
449
  createCue_(cue, parents) {
@@ -483,8 +483,8 @@ shaka.text.UITextDisplayer = class {
483
483
 
484
484
  /**
485
485
  * @param {!HTMLElement} cueElement
486
- * @param {!shaka.extern.Cue} cue
487
- * @param {!Array.<!shaka.extern.Cue>} parents
486
+ * @param {!shaka.text.Cue} cue
487
+ * @param {!Array.<!shaka.text.Cue>} parents
488
488
  * @param {boolean} hasWrapper
489
489
  * @private
490
490
  */
@@ -722,7 +722,7 @@ shaka.text.UITextDisplayer = class {
722
722
  * absolute value in pixels based on Computed Cell Size
723
723
  *
724
724
  * @param {string} lengthValue
725
- * @param {!shaka.extern.Cue} cue
725
+ * @param {!shaka.text.Cue} cue
726
726
  * @param {HTMLElement} videoContainer
727
727
  * @return {string}
728
728
  * @private
@@ -753,7 +753,7 @@ shaka.text.UITextDisplayer = class {
753
753
  * Returns computed absolute length value in pixels based on cell
754
754
  * and a video container size
755
755
  * @param {number} value
756
- * @param {!shaka.extern.Cue} cue
756
+ * @param {!shaka.text.Cue} cue
757
757
  * @param {HTMLElement} videoContainer
758
758
  * @return {string}
759
759
  *
@@ -770,8 +770,8 @@ shaka.text.UITextDisplayer = class {
770
770
  * it is assumed to be inherited from the parent. This returns null if the
771
771
  * value isn't found.
772
772
  *
773
- * @param {!Array.<!shaka.extern.Cue>} parents
774
- * @param {function(!shaka.extern.Cue):?T} cb
773
+ * @param {!Array.<!shaka.text.Cue>} parents
774
+ * @param {function(!shaka.text.Cue):?T} cb
775
775
  * @return {?T}
776
776
  * @template T
777
777
  * @private
@@ -116,7 +116,7 @@ shaka.text.VttTextParser = class {
116
116
  }
117
117
 
118
118
  // Parse VTT regions.
119
- /* !Array.<!shaka.extern.CueRegion> */
119
+ /* !Array.<!shaka.text.CueRegion> */
120
120
  const regions = [];
121
121
  for (const line of blocks[0].split('\n')) {
122
122
  if (/^Region:/.test(line)) {
@@ -169,7 +169,7 @@ shaka.text.VttTextParser = class {
169
169
  * Parses a string into a Region object.
170
170
  *
171
171
  * @param {string} text
172
- * @return {!shaka.extern.CueRegion}
172
+ * @return {!shaka.text.CueRegion}
173
173
  * @private
174
174
  */
175
175
  static parseRegion_(text) {
@@ -344,7 +344,7 @@ shaka.text.VttTextParser = class {
344
344
  *
345
345
  * @param {!Array.<string>} text
346
346
  * @param {number} timeOffset
347
- * @param {!Array.<!shaka.extern.CueRegion>} regions
347
+ * @param {!Array.<!shaka.text.CueRegion>} regions
348
348
  * @param {!Map.<string, shaka.text.Cue>} styles
349
349
  * @return {shaka.text.Cue}
350
350
  * @private
@@ -380,11 +380,9 @@ shaka.text.VttTextParser = class {
380
380
  let end = VttTextParser.parseTime_(parser);
381
381
 
382
382
  if (start == null || expect == null || end == null) {
383
- throw new shaka.util.Error(
384
- shaka.util.Error.Severity.CRITICAL,
385
- shaka.util.Error.Category.TEXT,
386
- shaka.util.Error.Code.INVALID_TEXT_CUE,
387
- 'Could not parse cue time range in WebVTT');
383
+ shaka.log.alwaysWarn(
384
+ 'Failed to parse VTT time code. Cue skipped:', id, text);
385
+ return null;
388
386
  }
389
387
 
390
388
  start += timeOffset;
@@ -442,7 +440,7 @@ shaka.text.VttTextParser = class {
442
440
  const xmlPayload = '<span>' + payload + '</span>';
443
441
  const element = shaka.util.XmlUtils.parseXmlString(xmlPayload, 'span');
444
442
  if (element) {
445
- /** @type {!Array.<!shaka.extern.Cue>} */
443
+ /** @type {!Array.<!shaka.text.Cue>} */
446
444
  const cues = [];
447
445
  const childNodes = element.childNodes;
448
446
  if (childNodes.length == 1) {
@@ -649,8 +647,8 @@ shaka.text.VttTextParser = class {
649
647
 
650
648
  /**
651
649
  * Merges values created in parseStyle_
652
- * @param {!shaka.extern.Cue} cue
653
- * @param {shaka.extern.Cue} refCue
650
+ * @param {!shaka.text.Cue} cue
651
+ * @param {shaka.text.Cue} refCue
654
652
  * @private
655
653
  */
656
654
  static mergeStyle_(cue, refCue) {
@@ -681,7 +679,7 @@ shaka.text.VttTextParser = class {
681
679
  /**
682
680
  * @param {!Node} element
683
681
  * @param {!shaka.text.Cue} rootCue
684
- * @param {Array.<!shaka.extern.Cue>} cues
682
+ * @param {Array.<!shaka.text.Cue>} cues
685
683
  * @param {!Map.<string, shaka.text.Cue>} styles
686
684
  * @private
687
685
  */
@@ -724,6 +722,14 @@ shaka.text.VttTextParser = class {
724
722
  case 'u':
725
723
  nestedCue.textDecoration.push(underline);
726
724
  break;
725
+ case 'font': {
726
+ const color =
727
+ /** @type {!Element} */(element).getAttribute('color');
728
+ if (color) {
729
+ nestedCue.color = color;
730
+ }
731
+ break;
732
+ }
727
733
  case 'div': {
728
734
  const time = /** @type {!Element} */(element).getAttribute('time');
729
735
  if (!time) {
@@ -787,7 +793,7 @@ shaka.text.VttTextParser = class {
787
793
  cue.size = Number(results[1]);
788
794
  } else if ((results =
789
795
  // eslint-disable-next-line max-len
790
- /^position:([\d.]+)%(?:,(line-left|line-right|middle|center|start|end))?$/
796
+ /^position:([\d.]+)%(?:,(line-left|line-right|middle|center|start|end|auto))?$/
791
797
  .exec(word))) {
792
798
  cue.position = Number(results[1]);
793
799
  if (results[2]) {
@@ -891,8 +897,10 @@ shaka.text.VttTextParser = class {
891
897
  cue.positionAlign = Cue.positionAlign.LEFT;
892
898
  } else if (align == 'line-right' || align == 'end') {
893
899
  cue.positionAlign = Cue.positionAlign.RIGHT;
894
- } else {
900
+ } else if (align == 'center' || align == 'middle') {
895
901
  cue.positionAlign = Cue.positionAlign.CENTER;
902
+ } else {
903
+ cue.positionAlign = Cue.positionAlign.AUTO;
896
904
  }
897
905
  }
898
906
 
@@ -0,0 +1,224 @@
1
+ /*! @license
2
+ * Shaka Player
3
+ * Copyright 2016 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ goog.provide('shaka.transmuxer.AacTransmuxer');
8
+
9
+ goog.require('shaka.media.Capabilities');
10
+ goog.require('shaka.transmuxer.ADTS');
11
+ goog.require('shaka.transmuxer.TransmuxerEngine');
12
+ goog.require('shaka.util.BufferUtils');
13
+ goog.require('shaka.util.Error');
14
+ goog.require('shaka.util.Id3Utils');
15
+ goog.require('shaka.util.ManifestParserUtils');
16
+ goog.require('shaka.util.MimeUtils');
17
+ goog.require('shaka.util.Mp4Generator');
18
+ goog.require('shaka.util.Uint8ArrayUtils');
19
+
20
+
21
+ /**
22
+ * @implements {shaka.extern.Transmuxer}
23
+ * @export
24
+ */
25
+ shaka.transmuxer.AacTransmuxer = class {
26
+ /**
27
+ * @param {string} mimeType
28
+ */
29
+ constructor(mimeType) {
30
+ /** @private {string} */
31
+ this.originalMimeType_ = mimeType;
32
+
33
+ /** @private {number} */
34
+ this.frameIndex_ = 0;
35
+
36
+ /** @private {!Map.<number, !Uint8Array>} */
37
+ this.initSegments = new Map();
38
+ }
39
+
40
+
41
+ /**
42
+ * @override
43
+ * @export
44
+ */
45
+ destroy() {
46
+ this.initSegments.clear();
47
+ }
48
+
49
+
50
+ /**
51
+ * Check if the mime type and the content type is supported.
52
+ * @param {string} mimeType
53
+ * @param {string=} contentType
54
+ * @return {boolean}
55
+ * @override
56
+ * @export
57
+ */
58
+ isSupported(mimeType, contentType) {
59
+ const Capabilities = shaka.media.Capabilities;
60
+
61
+ if (!this.isAacContainer_(mimeType)) {
62
+ return false;
63
+ }
64
+ const ContentType = shaka.util.ManifestParserUtils.ContentType;
65
+ return Capabilities.isTypeSupported(
66
+ this.convertCodecs(ContentType.AUDIO, mimeType));
67
+ }
68
+
69
+
70
+ /**
71
+ * Check if the mimetype is 'audio/aac'.
72
+ * @param {string} mimeType
73
+ * @return {boolean}
74
+ * @private
75
+ */
76
+ isAacContainer_(mimeType) {
77
+ return mimeType.toLowerCase().split(';')[0] == 'audio/aac';
78
+ }
79
+
80
+
81
+ /**
82
+ * @override
83
+ * @export
84
+ */
85
+ convertCodecs(contentType, mimeType) {
86
+ if (this.isAacContainer_(mimeType)) {
87
+ const codecs = shaka.util.MimeUtils.getCodecs(mimeType);
88
+ return `audio/mp4; codecs="${codecs || 'mp4a.40.2'}"`;
89
+ }
90
+ return mimeType;
91
+ }
92
+
93
+
94
+ /**
95
+ * @override
96
+ * @export
97
+ */
98
+ getOrginalMimeType() {
99
+ return this.originalMimeType_;
100
+ }
101
+
102
+
103
+ /**
104
+ * @override
105
+ * @export
106
+ */
107
+ transmux(data, stream, reference, duration) {
108
+ const ADTS = shaka.transmuxer.ADTS;
109
+ const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;
110
+
111
+ const uint8ArrayData = shaka.util.BufferUtils.toUint8(data);
112
+
113
+ // Check for the ADTS sync word
114
+ // Look for ADTS header | 1111 1111 | 1111 X00X | where X can be
115
+ // either 0 or 1
116
+ // Layer bits (position 14 and 15) in header should be always 0 for ADTS
117
+ // More info https://wiki.multimedia.cx/index.php?title=ADTS
118
+ const id3Data = shaka.util.Id3Utils.getID3Data(uint8ArrayData);
119
+ let offset = id3Data.length;
120
+ for (; offset < uint8ArrayData.length; offset++) {
121
+ if (ADTS.probe(uint8ArrayData, offset)) {
122
+ break;
123
+ }
124
+ }
125
+
126
+ let timestamp = reference.endTime * 1000;
127
+
128
+ const frames = shaka.util.Id3Utils.getID3Frames(id3Data);
129
+ if (frames.length && reference) {
130
+ const metadataTimestamp = frames.find((frame) => {
131
+ return frame.description ===
132
+ 'com.apple.streaming.transportStreamTimestamp';
133
+ });
134
+ if (metadataTimestamp) {
135
+ timestamp = /** @type {!number} */(metadataTimestamp.data);
136
+ }
137
+ }
138
+
139
+ const info = ADTS.parseInfo(uint8ArrayData, offset);
140
+ if (!info) {
141
+ return Promise.reject(new shaka.util.Error(
142
+ shaka.util.Error.Severity.CRITICAL,
143
+ shaka.util.Error.Category.MEDIA,
144
+ shaka.util.Error.Code.TRANSMUXING_FAILED));
145
+ }
146
+ stream.audioSamplingRate = info.sampleRate;
147
+ stream.channelsCount = info.channelCount;
148
+ stream.codecs = info.codec;
149
+
150
+ /** @type {!Array.<shaka.util.Mp4Generator.Mp4Sample>} */
151
+ const samples = [];
152
+
153
+ while (offset < uint8ArrayData.length) {
154
+ const header = ADTS.parseHeader(uint8ArrayData, offset);
155
+ if (!header) {
156
+ return Promise.reject(new shaka.util.Error(
157
+ shaka.util.Error.Severity.CRITICAL,
158
+ shaka.util.Error.Category.MEDIA,
159
+ shaka.util.Error.Code.TRANSMUXING_FAILED));
160
+ }
161
+ const length = header.headerLength + header.frameLength;
162
+ if (offset + length <= uint8ArrayData.length) {
163
+ const data = uint8ArrayData.subarray(
164
+ offset + header.headerLength, offset + length);
165
+ samples.push({
166
+ data: data,
167
+ size: header.frameLength,
168
+ duration: ADTS.AAC_SAMPLES_PER_FRAME,
169
+ cts: 0,
170
+ flags: {
171
+ isLeading: 0,
172
+ isDependedOn: 0,
173
+ hasRedundancy: 0,
174
+ degradPrio: 0,
175
+ dependsOn: 2,
176
+ isNonSync: 0,
177
+ },
178
+ });
179
+ }
180
+ offset += length;
181
+ }
182
+
183
+ /** @type {number} */
184
+ const sampleRate = info.sampleRate;
185
+ /** @type {number} */
186
+ const baseMediaDecodeTime = Math.floor(timestamp * sampleRate / 1000);
187
+
188
+ /** @type {shaka.util.Mp4Generator.StreamInfo} */
189
+ const streamInfo = {
190
+ id: stream.id,
191
+ type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
192
+ encrypted: stream.encrypted && stream.drmInfos.length > 0,
193
+ timescale: sampleRate,
194
+ duration: duration,
195
+ videoNalus: [],
196
+ audioConfig: new Uint8Array([]),
197
+ videoConfig: new Uint8Array([]),
198
+ data: {
199
+ sequenceNumber: this.frameIndex_,
200
+ baseMediaDecodeTime: baseMediaDecodeTime,
201
+ samples: samples,
202
+ },
203
+ stream: stream,
204
+ };
205
+ const mp4Generator = new shaka.util.Mp4Generator([streamInfo]);
206
+ let initSegment;
207
+ if (!this.initSegments.has(stream.id)) {
208
+ initSegment = mp4Generator.initSegment();
209
+ this.initSegments.set(stream.id, initSegment);
210
+ } else {
211
+ initSegment = this.initSegments.get(stream.id);
212
+ }
213
+ const segmentData = mp4Generator.segmentData();
214
+
215
+ this.frameIndex_++;
216
+ const transmuxData = Uint8ArrayUtils.concat(initSegment, segmentData);
217
+ return Promise.resolve(transmuxData);
218
+ }
219
+ };
220
+
221
+ shaka.transmuxer.TransmuxerEngine.registerTransmuxer(
222
+ 'audio/aac',
223
+ () => new shaka.transmuxer.AacTransmuxer('audio/aac'),
224
+ shaka.transmuxer.TransmuxerEngine.PluginPriority.FALLBACK);