shaka-player 4.4.3 → 4.6.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 (307) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
  2. package/.github/workflows/release-please.yaml +2 -27
  3. package/AUTHORS +2 -0
  4. package/CHANGELOG.md +156 -39
  5. package/CODE_OF_CONDUCT.md +1 -1
  6. package/CONTRIBUTORS +2 -0
  7. package/README.md +54 -42
  8. package/demo/asset_card.js +18 -21
  9. package/demo/cast_receiver/index.html +0 -1
  10. package/demo/close_button.js +0 -3
  11. package/demo/common/asset.js +33 -22
  12. package/demo/common/assets.js +249 -60
  13. package/demo/config.js +219 -253
  14. package/demo/custom.js +88 -133
  15. package/demo/front.js +7 -10
  16. package/demo/index.html +19 -22
  17. package/demo/input.js +6 -11
  18. package/demo/input_container.js +8 -9
  19. package/demo/main.js +62 -126
  20. package/demo/search.js +29 -34
  21. package/demo/service_worker.js +0 -3
  22. package/demo/tooltip.js +3 -5
  23. package/demo/visualizer.js +3 -5
  24. package/demo/visualizer_button.js +1 -20
  25. package/dist/controls.css +1 -1
  26. package/dist/controls.css.map +1 -1
  27. package/dist/demo.compiled.debug.js +211 -228
  28. package/dist/demo.compiled.debug.map +4 -4
  29. package/dist/demo.compiled.js +211 -228
  30. package/dist/demo.compiled.map +4 -4
  31. package/dist/deps.js +42 -37
  32. package/dist/locales.js +34 -30
  33. package/dist/receiver.compiled.debug.js +64 -77
  34. package/dist/receiver.compiled.debug.map +4 -4
  35. package/dist/receiver.compiled.js +64 -77
  36. package/dist/receiver.compiled.map +4 -4
  37. package/dist/shaka-player.compiled.d.ts +343 -151
  38. package/dist/shaka-player.compiled.debug.d.ts +343 -151
  39. package/dist/shaka-player.compiled.debug.externs.js +356 -117
  40. package/dist/shaka-player.compiled.debug.js +952 -811
  41. package/dist/shaka-player.compiled.debug.map +4 -4
  42. package/dist/shaka-player.compiled.externs.js +356 -117
  43. package/dist/shaka-player.compiled.js +1165 -1078
  44. package/dist/shaka-player.compiled.map +4 -4
  45. package/dist/shaka-player.ui.d.ts +359 -153
  46. package/dist/shaka-player.ui.debug.d.ts +359 -153
  47. package/dist/shaka-player.ui.debug.externs.js +382 -117
  48. package/dist/shaka-player.ui.debug.js +1084 -918
  49. package/dist/shaka-player.ui.debug.map +4 -4
  50. package/dist/shaka-player.ui.externs.js +382 -117
  51. package/dist/shaka-player.ui.js +1377 -1274
  52. package/dist/shaka-player.ui.map +4 -4
  53. package/docs/design/lcevc-integration.md +14 -14
  54. package/docs/tutorials/ad_monetization.md +54 -0
  55. package/docs/tutorials/basic-usage.md +2 -1
  56. package/docs/tutorials/errors.md +2 -1
  57. package/docs/tutorials/faq.md +27 -55
  58. package/docs/tutorials/index.json +2 -1
  59. package/docs/tutorials/lcevc.md +118 -0
  60. package/docs/tutorials/offline.md +10 -8
  61. package/docs/tutorials/plugins.md +5 -0
  62. package/docs/tutorials/ui-customization.md +17 -0
  63. package/docs/tutorials/ui.md +2 -1
  64. package/docs/tutorials/upgrade.md +3 -0
  65. package/externs/css_style_declaration.js +19 -0
  66. package/externs/lcevc.js +37 -13
  67. package/externs/managedmediasource.js +24 -0
  68. package/externs/media_remote.js +68 -0
  69. package/externs/mediatailor.js +193 -0
  70. package/externs/pictureinpicture.js +11 -0
  71. package/externs/shaka/abr_manager.js +6 -2
  72. package/externs/shaka/ads.js +27 -0
  73. package/externs/shaka/cea.js +7 -0
  74. package/externs/shaka/codecs.js +5 -3
  75. package/externs/shaka/manifest.js +31 -10
  76. package/externs/shaka/manifest_parser.js +24 -1
  77. package/externs/shaka/net.js +2 -2
  78. package/externs/shaka/offline.js +13 -2
  79. package/externs/shaka/player.js +65 -8
  80. package/externs/shaka/text.js +3 -1
  81. package/externs/shaka/transmuxer.js +1 -1
  82. package/karma.conf.js +7 -3
  83. package/lib/abr/simple_abr_manager.js +66 -9
  84. package/lib/ads/ad_manager.js +104 -50
  85. package/lib/ads/media_tailor_ad.js +297 -0
  86. package/lib/ads/media_tailor_ad_manager.js +839 -0
  87. package/lib/cast/cast_receiver.js +1 -1
  88. package/lib/cea/cea_decoder.js +28 -0
  89. package/lib/cea/dummy_caption_decoder.js +5 -0
  90. package/lib/cea/ts_cea_parser.js +15 -2
  91. package/lib/config/codec_switching_strategy.js +24 -0
  92. package/lib/dash/content_protection.js +120 -2
  93. package/lib/dash/dash_parser.js +322 -93
  94. package/lib/dash/mpd_utils.js +62 -37
  95. package/lib/dash/segment_base.js +17 -10
  96. package/lib/dash/segment_list.js +18 -9
  97. package/lib/dash/segment_template.js +122 -107
  98. package/lib/dependencies/all.js +8 -7
  99. package/lib/hls/hls_classes.js +28 -43
  100. package/lib/hls/hls_parser.js +798 -658
  101. package/lib/hls/hls_utils.js +64 -5
  102. package/lib/hls/manifest_text_parser.js +7 -11
  103. package/lib/lcevc/lcevc_dec.js +220 -0
  104. package/lib/media/adaptation_set.js +32 -14
  105. package/lib/media/adaptation_set_criteria.js +86 -16
  106. package/lib/media/closed_caption_parser.js +13 -0
  107. package/lib/media/content_workarounds.js +6 -0
  108. package/lib/media/drm_engine.js +8 -13
  109. package/lib/media/manifest_parser.js +8 -113
  110. package/lib/media/media_source_capabilities.js +10 -3
  111. package/lib/media/media_source_engine.js +286 -44
  112. package/lib/media/play_rate_controller.js +8 -38
  113. package/lib/media/presentation_timeline.js +7 -1
  114. package/lib/media/quality_observer.js +1 -1
  115. package/lib/media/segment_index.js +6 -6
  116. package/lib/media/segment_prefetch.js +92 -24
  117. package/lib/media/segment_reference.js +73 -7
  118. package/lib/media/segment_utils.js +343 -0
  119. package/lib/media/stall_detector.js +0 -3
  120. package/lib/media/streaming_engine.js +73 -38
  121. package/lib/mss/mss_parser.js +19 -2
  122. package/lib/net/networking_engine.js +67 -12
  123. package/lib/net/networking_utils.js +95 -0
  124. package/lib/offline/indexeddb/v1_storage_cell.js +3 -0
  125. package/lib/offline/indexeddb/v2_storage_cell.js +3 -0
  126. package/lib/offline/manifest_converter.js +3 -0
  127. package/lib/offline/offline_manifest_parser.js +10 -0
  128. package/lib/offline/storage.js +14 -7
  129. package/lib/player.js +1098 -1537
  130. package/lib/polyfill/mediasource.js +22 -1
  131. package/lib/text/cue.js +15 -0
  132. package/lib/text/mp4_ttml_parser.js +2 -2
  133. package/lib/text/srt_text_parser.js +2 -2
  134. package/lib/text/stub_text_displayer.js +51 -0
  135. package/lib/text/text_engine.js +3 -2
  136. package/lib/text/ttml_text_parser.js +45 -5
  137. package/lib/text/ui_text_displayer.js +8 -0
  138. package/lib/text/vtt_text_parser.js +40 -22
  139. package/lib/transmuxer/aac_transmuxer.js +1 -1
  140. package/lib/transmuxer/ac3_transmuxer.js +1 -1
  141. package/lib/transmuxer/ec3_transmuxer.js +1 -1
  142. package/lib/transmuxer/h264.js +5 -4
  143. package/lib/transmuxer/h265.js +863 -0
  144. package/lib/transmuxer/mp3_transmuxer.js +1 -1
  145. package/lib/transmuxer/mpeg_ts_transmuxer.js +4 -3
  146. package/lib/transmuxer/mss_transmuxer.js +1 -1
  147. package/lib/transmuxer/ts_transmuxer.js +187 -22
  148. package/lib/util/buffer_utils.js +26 -4
  149. package/lib/util/content_steering_manager.js +358 -0
  150. package/lib/util/error.js +30 -15
  151. package/lib/util/exp_golomb.js +30 -2
  152. package/lib/util/fairplay_utils.js +1 -1
  153. package/lib/util/fake_event.js +8 -1
  154. package/lib/util/id3_utils.js +50 -1
  155. package/lib/util/manifest_parser_utils.js +12 -8
  156. package/lib/util/mp4_generator.js +6 -8
  157. package/lib/util/mutex.js +59 -0
  158. package/lib/util/object_utils.js +1 -1
  159. package/lib/util/periods.js +156 -179
  160. package/lib/util/platform.js +44 -3
  161. package/lib/util/player_configuration.js +43 -6
  162. package/lib/util/state_history.js +6 -2
  163. package/lib/util/stream_utils.js +206 -283
  164. package/lib/util/ts_parser.js +335 -98
  165. package/lib/util/uint8array_utils.js +5 -1
  166. package/lib/util/xml_utils.js +5 -0
  167. package/maintained-branches.md +3 -2
  168. package/package.json +4 -6
  169. package/roadmap.md +25 -5
  170. package/shaka-player.uncompiled.js +2 -2
  171. package/support.html +0 -1
  172. package/test/abr/simple_abr_manager_unit.js +33 -33
  173. package/test/ads/ad_manager_unit.js +3 -2
  174. package/test/cast/cast_receiver_integration.js +50 -4
  175. package/test/cast/cast_utils_unit.js +2 -0
  176. package/test/cea/cea_decoder_unit.js +7 -0
  177. package/test/codec_switching/codec_switching_integration.js +182 -0
  178. package/test/dash/dash_parser_content_protection_unit.js +2 -0
  179. package/test/dash/dash_parser_integration.js +74 -0
  180. package/test/dash/dash_parser_live_unit.js +2 -19
  181. package/test/dash/dash_parser_manifest_unit.js +536 -2
  182. package/test/dash/dash_parser_segment_base_unit.js +2 -0
  183. package/test/dash/dash_parser_segment_list_unit.js +2 -0
  184. package/test/dash/dash_parser_segment_template_unit.js +2 -0
  185. package/test/dash/mpd_utils_unit.js +61 -30
  186. package/test/demo/demo_unit.js +0 -16
  187. package/test/hls/hls_live_unit.js +14 -3
  188. package/test/hls/hls_parser_unit.js +385 -33
  189. package/test/hls/manifest_text_parser_unit.js +32 -99
  190. package/test/media/adaptation_set_criteria_unit.js +284 -15
  191. package/test/media/adaptation_set_unit.js +2 -0
  192. package/test/media/content_workarounds_unit.js +1 -1
  193. package/test/media/drm_engine_unit.js +3 -3
  194. package/test/media/media_source_engine_unit.js +166 -2
  195. package/test/media/play_rate_controller_unit.js +0 -48
  196. package/test/media/segment_index_unit.js +5 -4
  197. package/test/media/segment_prefetch_unit.js +1 -1
  198. package/test/media/streaming_engine_unit.js +17 -17
  199. package/test/mss/mss_parser_unit.js +2 -0
  200. package/test/mss/mss_player_integration.js +3 -2
  201. package/test/net/networking_engine_unit.js +3 -3
  202. package/test/{media/manifest_parser_unit.js → net/networking_utils_unit.js} +2 -2
  203. package/test/offline/manifest_convert_unit.js +14 -0
  204. package/test/offline/offline_integration.js +2 -1
  205. package/test/offline/storage_integration.js +22 -13
  206. package/test/player_external.js +4 -2
  207. package/test/player_integration.js +15 -4
  208. package/test/player_load_graph_integration.js +47 -151
  209. package/test/player_src_equals_external.js +1 -0
  210. package/test/player_src_equals_integration.js +71 -4
  211. package/test/player_unit.js +182 -158
  212. package/test/test/assets/dash-aes-128/Fragments(video=0,format=mpd-time-csf) +0 -0
  213. package/test/test/assets/dash-aes-128/Fragments(video=20000000,format=mpd-time-csf) +0 -0
  214. package/test/test/assets/dash-aes-128/Fragments(video=40000000,format=mpd-time-csf) +0 -0
  215. package/test/test/assets/dash-aes-128/Fragments(video=60000000,format=mpd-time-csf) +0 -0
  216. package/test/test/assets/dash-aes-128/Fragments(video=i,format=mpd-time-csf) +0 -0
  217. package/test/test/assets/dash-aes-128/dash.mpd +18 -0
  218. package/test/test/assets/dash-aes-128/license +1 -0
  219. package/test/test/assets/dash-multi-codec/audio_en_2c_128k_aac.mp4 +0 -0
  220. package/test/test/assets/dash-multi-codec/audio_es_2c_64k_opus.webm +0 -0
  221. package/test/test/assets/dash-multi-codec/dash.mpd +32 -0
  222. package/test/test/assets/dash-multi-codec/video_144p_108k_h264.mp4 +0 -0
  223. package/test/test/assets/hls-ts-h265/0.ts +0 -0
  224. package/test/test/assets/hls-ts-h265/hevc.m3u8 +6 -0
  225. package/test/test/assets/hls-ts-h265/index.m3u8 +7 -0
  226. package/test/test/assets/hls-ts-muxed-aac-h265/0.ts +0 -0
  227. package/test/test/assets/hls-ts-muxed-aac-h265/1.ts +0 -0
  228. package/test/test/assets/hls-ts-muxed-aac-h265/media.m3u8 +9 -0
  229. package/test/test/assets/hls-ts-muxed-ac3-h264/media.m3u8 +24 -0
  230. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00000.ts +0 -0
  231. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00001.ts +0 -0
  232. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00002.ts +0 -0
  233. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00003.ts +0 -0
  234. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00004.ts +0 -0
  235. package/test/test/assets/hls-ts-muxed-ac3-h264/s_00005.ts +0 -0
  236. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0000.ts +0 -0
  237. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0001.ts +0 -0
  238. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0002.ts +0 -0
  239. package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0003.ts +0 -0
  240. package/test/test/assets/hls-ts-muxed-ec3-h264/prog_index.m3u8 +14 -0
  241. package/test/test/assets/hls-ts-muxed-mp3-h264/index.m3u8 +23 -0
  242. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-1-v1-a1.ts +0 -0
  243. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-2-v1-a1.ts +0 -0
  244. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-3-v1-a1.ts +0 -0
  245. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-4-v1-a1.ts +0 -0
  246. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-5-v1-a1.ts +0 -0
  247. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-6-v1-a1.ts +0 -0
  248. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-7-v1-a1.ts +0 -0
  249. package/test/test/assets/hls-ts-muxed-mp3-h264/seg-8-v1-a1.ts +0 -0
  250. package/test/test/util/dash_parser_util.js +4 -0
  251. package/test/test/util/fake_ad_manager.js +20 -0
  252. package/test/test/util/fake_media_source_engine.js +13 -2
  253. package/test/test/util/fake_networking_engine.js +9 -1
  254. package/test/test/util/fake_segment_prefetch.js +3 -0
  255. package/test/test/util/manifest_generator.js +11 -3
  256. package/test/test/util/manifest_parser_util.js +14 -2
  257. package/test/test/util/mss_parser_util.js +4 -0
  258. package/test/test/util/offline_utils.js +2 -0
  259. package/test/test/util/simple_fakes.js +2 -2
  260. package/test/test/util/streaming_engine_util.js +10 -4
  261. package/test/test/util/test_scheme.js +6 -0
  262. package/test/test/util/ui_utils.js +4 -3
  263. package/test/text/mp4_ttml_parser_unit.js +4 -4
  264. package/test/text/srt_text_parser_unit.js +1 -1
  265. package/test/text/text_displayer_layout_unit.js +1 -1
  266. package/test/text/text_engine_unit.js +6 -0
  267. package/test/text/ttml_text_parser_unit.js +85 -2
  268. package/test/text/vtt_text_parser_unit.js +103 -31
  269. package/test/transmuxer/transmuxer_engine_integration.js +9 -0
  270. package/test/transmuxer/transmuxer_integration.js +150 -3
  271. package/test/ui/ad_ui_unit.js +2 -2
  272. package/test/ui/ui_customization_unit.js +17 -16
  273. package/test/ui/ui_integration.js +30 -20
  274. package/test/ui/ui_unit.js +28 -29
  275. package/test/util/buffer_utils_unit.js +1 -1
  276. package/test/util/content_steering_manager_unit.js +427 -0
  277. package/test/util/id3_utils_unit.js +52 -0
  278. package/test/util/stream_utils_unit.js +207 -169
  279. package/test/util/ts_parser_unit.js +3 -3
  280. package/third_party/closure-uri/uri.js +13 -1
  281. package/ui/audio_language_selection.js +9 -2
  282. package/ui/controls.js +125 -0
  283. package/ui/externs/ui.js +24 -2
  284. package/ui/language_utils.js +43 -8
  285. package/ui/less/range_elements.less +33 -0
  286. package/ui/locales/en.json +1 -0
  287. package/ui/locales/es-419.json +1 -0
  288. package/ui/locales/es.json +1 -0
  289. package/ui/locales/source.json +4 -0
  290. package/ui/localization.js +10 -0
  291. package/ui/pip_button.js +22 -120
  292. package/ui/remote_button.js +203 -0
  293. package/ui/resolution_selection.js +47 -10
  294. package/ui/seek_bar.js +296 -3
  295. package/ui/text_selection.js +2 -1
  296. package/ui/ui.js +11 -4
  297. package/demo/common/message_ids.js +0 -309
  298. package/demo/locales/en.json +0 -288
  299. package/demo/locales/source.json +0 -1146
  300. package/externs/mux.js +0 -69
  301. package/lib/lcevc/lcevc_dil.js +0 -152
  302. package/lib/routing/node.js +0 -23
  303. package/lib/routing/payload.js +0 -43
  304. package/lib/routing/walker.js +0 -587
  305. package/lib/transmuxer/muxjs_transmuxer.js +0 -242
  306. package/test/routing/walker_unit.js +0 -504
  307. package/test/transmuxer/muxjs_transmuxer_integration.js +0 -177
@@ -390,88 +390,6 @@ describe('StreamUtils', () => {
390
390
  });
391
391
  });
392
392
 
393
- describe('filterVariantsByAudioChannelCount', () => {
394
- it('chooses variants with preferred audio channels count', () => {
395
- manifest = shaka.test.ManifestGenerator.generate((manifest) => {
396
- manifest.addVariant(0, (variant) => {
397
- variant.addAudio(0, (stream) => {
398
- stream.channelsCount = 2;
399
- });
400
- });
401
- manifest.addVariant(1, (variant) => {
402
- variant.addAudio(1, (stream) => {
403
- stream.channelsCount = 6;
404
- });
405
- });
406
- manifest.addVariant(2, (variant) => {
407
- variant.addAudio(2, (stream) => {
408
- stream.channelsCount = 2;
409
- });
410
- });
411
- });
412
-
413
- const chosen = StreamUtils.filterVariantsByAudioChannelCount(
414
- manifest.variants, 2);
415
- expect(chosen.length).toBe(2);
416
- expect(chosen[0]).toBe(manifest.variants[0]);
417
- expect(chosen[1]).toBe(manifest.variants[2]);
418
- });
419
-
420
- it('chooses variants with largest audio channel count less than config' +
421
- ' when no exact audio channel count match is possible', () => {
422
- manifest = shaka.test.ManifestGenerator.generate((manifest) => {
423
- manifest.addVariant(0, (variant) => {
424
- variant.addAudio(0, (stream) => {
425
- stream.channelsCount = 2;
426
- });
427
- });
428
- manifest.addVariant(1, (variant) => {
429
- variant.addAudio(1, (stream) => {
430
- stream.channelsCount = 8;
431
- });
432
- });
433
- manifest.addVariant(2, (variant) => {
434
- variant.addAudio(2, (stream) => {
435
- stream.channelsCount = 2;
436
- });
437
- });
438
- });
439
-
440
- const chosen = StreamUtils.filterVariantsByAudioChannelCount(
441
- manifest.variants, 6);
442
- expect(chosen.length).toBe(2);
443
- expect(chosen[0]).toBe(manifest.variants[0]);
444
- expect(chosen[1]).toBe(manifest.variants[2]);
445
- });
446
-
447
- it('chooses variants with fewest audio channels when none fit in the ' +
448
- 'config', () => {
449
- manifest = shaka.test.ManifestGenerator.generate((manifest) => {
450
- manifest.addVariant(0, (variant) => {
451
- variant.addAudio(0, (stream) => {
452
- stream.channelsCount = 6;
453
- });
454
- });
455
- manifest.addVariant(1, (variant) => {
456
- variant.addAudio(1, (stream) => {
457
- stream.channelsCount = 8;
458
- });
459
- });
460
- manifest.addVariant(2, (variant) => {
461
- variant.addAudio(2, (stream) => {
462
- stream.channelsCount = 6;
463
- });
464
- });
465
- });
466
-
467
- const chosen = StreamUtils.filterVariantsByAudioChannelCount(
468
- manifest.variants, 2);
469
- expect(chosen.length).toBe(2);
470
- expect(chosen[0]).toBe(manifest.variants[0]);
471
- expect(chosen[1]).toBe(manifest.variants[2]);
472
- });
473
- });
474
-
475
393
  describe('getDecodingInfosForVariants', () => {
476
394
  it('for multiplexd content', async () => {
477
395
  manifest = shaka.test.ManifestGenerator.generate((manifest) => {
@@ -634,9 +552,7 @@ describe('StreamUtils', () => {
634
552
  });
635
553
  });
636
554
 
637
- const noVariant = null;
638
- await shaka.util.StreamUtils.filterManifest(
639
- fakeDrmEngine, noVariant, manifest);
555
+ await shaka.util.StreamUtils.filterManifest(fakeDrmEngine, manifest);
640
556
 
641
557
  // Covers a regression in which we would remove streams with codecs.
642
558
  // The last two streams should be removed because their full MIME types
@@ -671,9 +587,7 @@ describe('StreamUtils', () => {
671
587
  });
672
588
  });
673
589
 
674
- const noVariant = null;
675
- await shaka.util.StreamUtils.filterManifest(
676
- fakeDrmEngine, noVariant, manifest);
590
+ await shaka.util.StreamUtils.filterManifest(fakeDrmEngine, manifest);
677
591
 
678
592
  // Covers a regression in which we would remove streams with codecs.
679
593
  // The first 4 streams should be there because they are always supported.
@@ -691,6 +605,36 @@ describe('StreamUtils', () => {
691
605
  jasmine.objectContaining({id: 5}));
692
606
  });
693
607
 
608
+ it('does not filter manifest when codec switching is enabled', async () => {
609
+ manifest = shaka.test.ManifestGenerator.generate((manifest) => {
610
+ manifest.addVariant(1, (variant) => {
611
+ variant.addAudio(10, (stream) => {
612
+ stream.codecs = 'mp4a.69';
613
+ });
614
+ variant.addVideo(11, (stream) => {
615
+ stream.codecs = 'avc1';
616
+ });
617
+ });
618
+ });
619
+
620
+ const originalFilterManifestByCurrentVariant =
621
+ shaka.util.StreamUtils.filterManifestByCurrentVariant;
622
+
623
+ try {
624
+ const filterManifestByCurrentVariantSpy =
625
+ jasmine.createSpy('filterManifestByCurrentVariant');
626
+ shaka.util.StreamUtils.filterManifestByCurrentVariant =
627
+ shaka.test.Util.spyFunc(filterManifestByCurrentVariantSpy);
628
+
629
+ await shaka.util.StreamUtils.filterManifest(fakeDrmEngine, manifest);
630
+
631
+ expect(filterManifestByCurrentVariantSpy).not.toHaveBeenCalled();
632
+ } finally {
633
+ shaka.util.StreamUtils.filterManifestByCurrentVariant =
634
+ originalFilterManifestByCurrentVariant;
635
+ }
636
+ });
637
+
694
638
  it('filters transport streams', async () => {
695
639
  manifest = shaka.test.ManifestGenerator.generate((manifest) => {
696
640
  manifest.addVariant(0, (variant) => {
@@ -704,8 +648,7 @@ describe('StreamUtils', () => {
704
648
  });
705
649
  });
706
650
 
707
- await shaka.util.StreamUtils.filterManifest(
708
- fakeDrmEngine, /* currentVariant= */ null, manifest);
651
+ await shaka.util.StreamUtils.filterManifest(fakeDrmEngine, manifest);
709
652
 
710
653
  // Covers a regression in which we would remove streams with codecs.
711
654
  // The last two streams should be removed because their full MIME types
@@ -731,8 +674,7 @@ describe('StreamUtils', () => {
731
674
  });
732
675
  });
733
676
 
734
- await shaka.util.StreamUtils.filterManifest(
735
- fakeDrmEngine, /* currentVariant= */ null, manifest);
677
+ await shaka.util.StreamUtils.filterManifest(fakeDrmEngine, manifest);
736
678
  expect(manifest.variants.length).toBe(1);
737
679
  });
738
680
 
@@ -748,8 +690,7 @@ describe('StreamUtils', () => {
748
690
  });
749
691
  });
750
692
 
751
- await shaka.util.StreamUtils.filterManifest(
752
- fakeDrmEngine, /* currentVariant= */ null, manifest);
693
+ await shaka.util.StreamUtils.filterManifest(fakeDrmEngine, manifest);
753
694
 
754
695
  expect(manifest.variants.length).toBe(1);
755
696
  });
@@ -771,8 +712,7 @@ describe('StreamUtils', () => {
771
712
  });
772
713
  });
773
714
 
774
- await shaka.util.StreamUtils.filterManifest(
775
- fakeDrmEngine, /* currentVariant= */ null, manifest);
715
+ await shaka.util.StreamUtils.filterManifest(fakeDrmEngine, manifest);
776
716
 
777
717
  expect(manifest.variants.length).toBe(2);
778
718
  });
@@ -794,8 +734,7 @@ describe('StreamUtils', () => {
794
734
  });
795
735
  });
796
736
 
797
- await shaka.util.StreamUtils.filterManifest(
798
- fakeDrmEngine, /* currentVariant= */ null, manifest);
737
+ await shaka.util.StreamUtils.filterManifest(fakeDrmEngine, manifest);
799
738
 
800
739
  expect(manifest.variants.length).toBe(2);
801
740
  });
@@ -812,149 +751,249 @@ describe('StreamUtils', () => {
812
751
  });
813
752
  });
814
753
 
815
- await shaka.util.StreamUtils.filterManifest(
816
- fakeDrmEngine, /* currentVariant= */ null, manifest);
754
+ await shaka.util.StreamUtils.filterManifest(fakeDrmEngine, manifest);
817
755
 
818
756
  expect(manifest.variants.length).toBe(1);
819
757
  });
820
758
  });
821
759
 
822
760
  describe('chooseCodecsAndFilterManifest', () => {
823
- const avc1Codecs = 'avc1.640028';
824
- const vp09Codecs = 'vp09.00.40.08.00.02.02.02.00';
825
-
826
- const addVariant1080Avc1 = (manifest) => {
761
+ const addVariant720Avc1 = (manifest) => {
827
762
  manifest.addVariant(0, (variant) => {
828
763
  variant.bandwidth = 5058558;
829
764
  variant.addAudio(1, (stream) => {
830
765
  stream.bandwidth = 129998;
831
- stream.codecs = 'opus';
766
+ stream.mime('audio/mp4', 'mp4a.40.2');
832
767
  });
833
768
  variant.addVideo(2, (stream) => {
834
769
  stream.bandwidth = 4928560;
835
- stream.codecs = avc1Codecs;
836
- stream.size(1920, 1080);
770
+ stream.size(1280, 720);
771
+ stream.mime('video/mp4', 'avc1.640028');
837
772
  });
838
773
  });
839
774
  };
840
775
 
841
- const addVariant1080Vp9 = (manifest) => {
776
+ const addVariant720Vp9 = (manifest) => {
842
777
  manifest.addVariant(3, (variant) => {
843
778
  variant.bandwidth = 4911000;
844
779
  variant.addAudio(4, (stream) => {
845
780
  stream.bandwidth = 129998;
846
- stream.codecs = 'vorbis';
781
+ stream.mime('audio/webm', 'vorbis');
847
782
  });
848
783
  variant.addVideo(5, (stream) => {
849
784
  stream.bandwidth = 4781002;
850
- stream.codecs = vp09Codecs;
851
- stream.size(1920, 1080);
785
+ stream.size(1280, 720);
786
+ stream.mime('video/webm', 'vp9');
852
787
  });
853
788
  });
854
789
  };
855
790
 
856
- const addVariant2160Vp9 = (manifest) => {
791
+ const addVariant1080Vp9 = (manifest) => {
857
792
  manifest.addVariant(6, (variant) => {
858
793
  variant.bandwidth = 10850316;
859
- variant.addAudio(7, (stream) => {
794
+ variant.addAudio(1, (stream) => {
860
795
  stream.bandwidth = 129998;
861
- stream.codecs = 'opus';
796
+ stream.mime('audio/mp4', 'mp4a.40.2');
862
797
  });
863
798
  variant.addVideo(8, (stream) => {
864
799
  stream.bandwidth = 10784324;
865
- stream.codecs = vp09Codecs;
866
- stream.size(3840, 2160);
800
+ stream.size(1920, 1080);
801
+ stream.mime('video/webm', 'vp9');
867
802
  });
868
803
  });
869
804
  };
870
805
 
806
+ it('should filter variants by the best available bandwidth' +
807
+ ' for video resolution', () => {
808
+ manifest = shaka.test.ManifestGenerator.generate((manifest) => {
809
+ manifest.addVariant(0, (variant) => {
810
+ variant.bandwidth = 4058558;
811
+ variant.addVideo(1, (stream) => {
812
+ stream.bandwidth = 300000;
813
+ stream.size(10, 10);
814
+ });
815
+ });
816
+ manifest.addVariant(2, (variant) => {
817
+ variant.bandwidth = 4781002;
818
+ variant.addVideo(3, (stream) => {
819
+ stream.bandwidth = 400000;
820
+ stream.size(10, 10);
821
+ });
822
+ });
823
+ manifest.addVariant(4, (variant) => {
824
+ variant.addVideo(5, (stream) => {
825
+ stream.bandwidth = 500000;
826
+ stream.size(20, 20);
827
+ });
828
+ });
829
+ manifest.addVariant(6, (variant) => {
830
+ variant.addVideo(7, (stream) => {
831
+ stream.bandwidth = 600000;
832
+ stream.size(20, 20);
833
+ });
834
+ });
835
+ });
836
+
837
+ shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
838
+ /* preferredVideoCodecs= */[],
839
+ /* preferredAudioCodecs= */[],
840
+ /* preferredDecodingAttributes= */[]);
841
+
842
+ expect(manifest.variants.length).toBe(2);
843
+ expect(manifest.variants.every((v) => [300000, 500000].includes(
844
+ v.video.bandwidth))).toBeTruthy();
845
+ });
846
+
847
+ it('should filter variants by the best available bandwidth' +
848
+ ' for audio language', () => {
849
+ // This test is flaky in some Tizen devices, due to codec restrictions.
850
+ if (shaka.util.Platform.isTizen()) {
851
+ pending('Skip flaky test in Tizen');
852
+ }
853
+ manifest = shaka.test.ManifestGenerator.generate((manifest) => {
854
+ manifest.addVariant(0, (variant) => {
855
+ variant.bandwidth = 4058558;
856
+ variant.addAudio(1, (stream) => {
857
+ stream.bandwidth = 100000;
858
+ stream.language = 'en';
859
+ stream.mime('audio/mp4', 'mp4a.40.2');
860
+ });
861
+ });
862
+ manifest.addVariant(2, (variant) => {
863
+ variant.bandwidth = 4781002;
864
+ variant.addAudio(3, (stream) => {
865
+ stream.bandwidth = 200000;
866
+ stream.language = 'en';
867
+ stream.mime('audio/mp4', 'flac');
868
+ });
869
+ });
870
+ manifest.addVariant(4, (variant) => {
871
+ variant.addAudio(5, (stream) => {
872
+ stream.bandwidth = 100000;
873
+ stream.language = 'es';
874
+ stream.mime('audio/mp4', 'mp4a.40.2');
875
+ });
876
+ });
877
+ manifest.addVariant(6, (variant) => {
878
+ variant.addAudio(7, (stream) => {
879
+ stream.bandwidth = 500000;
880
+ stream.language = 'es';
881
+ stream.mime('audio/mp4', 'flac');
882
+ });
883
+ });
884
+ });
885
+
886
+ shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
887
+ /* preferredVideoCodecs= */[],
888
+ /* preferredAudioCodecs= */[],
889
+ /* preferredDecodingAttributes= */[]);
890
+
891
+ expect(manifest.variants.length).toBe(2);
892
+ expect(manifest.variants.every((v) => v.audio.bandwidth == 100000))
893
+ .toBeTruthy();
894
+ });
895
+
896
+ it('should allow multiple codecs for codec switching', () => {
897
+ if (!MediaSource.isTypeSupported('video/webm; codecs="vp9"')) {
898
+ pending('Codec VP9 is not supported by the platform.');
899
+ }
900
+ if (!MediaSource.isTypeSupported('video/webm; codecs="vorbis"')) {
901
+ pending('Codec vorbis is not supported by the platform.');
902
+ }
903
+ // This test is flaky in some Tizen devices, due to codec restrictions.
904
+ if (shaka.util.Platform.isTizen()) {
905
+ pending('Skip flaky test in Tizen');
906
+ }
907
+ manifest = shaka.test.ManifestGenerator.generate((manifest) => {
908
+ addVariant720Avc1(manifest);
909
+ addVariant720Vp9(manifest);
910
+ addVariant1080Vp9(manifest);
911
+ });
912
+
913
+ manifest.variants[0].video.bandwidth = 1;
914
+
915
+ shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
916
+ /* preferredVideoCodecs= */[],
917
+ /* preferredAudioCodecs= */[],
918
+ /* preferredDecodingAttributes= */[]);
919
+
920
+ expect(manifest.variants.length).toBe(2);
921
+ expect(manifest.variants[0].video.codecs)
922
+ .not.toBe(manifest.variants[1].video.codecs);
923
+ });
924
+
871
925
  it('chooses preferred audio and video codecs', () => {
926
+ if (!MediaSource.isTypeSupported('video/webm; codecs="vp9"')) {
927
+ pending('Codec VP9 is not supported by the platform.');
928
+ }
929
+ if (!MediaSource.isTypeSupported('video/webm; codecs="vorbis"')) {
930
+ pending('Codec vorbis is not supported by the platform.');
931
+ }
872
932
  manifest = shaka.test.ManifestGenerator.generate((manifest) => {
873
- addVariant1080Avc1(manifest);
933
+ addVariant720Avc1(manifest);
934
+ addVariant720Vp9(manifest);
874
935
  addVariant1080Vp9(manifest);
875
- addVariant2160Vp9(manifest);
876
936
  });
877
937
  const variants =
878
938
  shaka.util.StreamUtils.choosePreferredCodecs(manifest.variants,
879
- /* preferredVideoCodecs= */['vp09'],
880
- /* preferredAudioCodecs= */['opus']);
939
+ /* preferredVideoCodecs= */['vp9'],
940
+ /* preferredAudioCodecs= */['mp4a']);
881
941
 
882
942
  expect(variants.length).toBe(1);
883
- expect(variants[0].video.codecs).toBe(vp09Codecs);
884
- expect(variants[0].audio.codecs).toBe('opus');
943
+ expect(variants[0].video.codecs).toBe('vp9');
944
+ expect(variants[0].audio.codecs).toBe('mp4a.40.2');
885
945
  });
886
946
 
887
947
  it('chooses preferred video codecs', () => {
948
+ if (!MediaSource.isTypeSupported('video/webm; codecs="vp9"')) {
949
+ pending('Codec VP9 is not supported by the platform.');
950
+ }
951
+ if (!MediaSource.isTypeSupported('video/webm; codecs="vorbis"')) {
952
+ pending('Codec vorbis is not supported by the platform.');
953
+ }
888
954
  // If no preferred audio codecs is specified or can be found, choose the
889
955
  // variants with preferred video codecs.
890
956
  manifest = shaka.test.ManifestGenerator.generate((manifest) => {
891
- addVariant1080Avc1(manifest);
957
+ addVariant720Avc1(manifest);
958
+ addVariant720Vp9(manifest);
892
959
  addVariant1080Vp9(manifest);
893
- addVariant2160Vp9(manifest);
894
960
  });
895
961
  const variants =
896
962
  shaka.util.StreamUtils.choosePreferredCodecs(manifest.variants,
897
- /* preferredVideoCodecs= */['vp09'],
963
+ /* preferredVideoCodecs= */['vp9'],
898
964
  /* preferredAudioCodecs= */[]);
899
965
 
900
966
  expect(variants.length).toBe(2);
901
- expect(variants[0].video.codecs).toBe(vp09Codecs);
967
+ expect(variants[0].video.codecs).toBe('vp9');
902
968
  expect(variants[0].audio.codecs).toBe('vorbis');
903
- expect(variants[1].video.codecs).toBe(vp09Codecs);
904
- expect(variants[1].audio.codecs).toBe('opus');
969
+ expect(variants[1].video.codecs).toBe('vp9');
970
+ expect(variants[1].audio.codecs).toBe('mp4a.40.2');
905
971
  });
906
972
 
907
973
  it('chooses preferred audio codecs', () => {
974
+ if (!MediaSource.isTypeSupported('video/webm; codecs="vp9"')) {
975
+ pending('Codec VP9 is not supported by the platform.');
976
+ }
977
+ if (!MediaSource.isTypeSupported('video/webm; codecs="vorbis"')) {
978
+ pending('Codec vorbis is not supported by the platform.');
979
+ }
908
980
  // If no preferred video codecs is specified or can be found, choose the
909
981
  // variants with preferred audio codecs.
910
982
  manifest = shaka.test.ManifestGenerator.generate((manifest) => {
911
- addVariant1080Avc1(manifest);
983
+ addVariant720Avc1(manifest);
984
+ addVariant720Vp9(manifest);
912
985
  addVariant1080Vp9(manifest);
913
- addVariant2160Vp9(manifest);
914
986
  });
915
987
  const variants =
916
988
  shaka.util.StreamUtils.choosePreferredCodecs(manifest.variants,
917
989
  /* preferredVideoCodecs= */['foo'],
918
- /* preferredAudioCodecs= */['opus']);
990
+ /* preferredAudioCodecs= */['mp4a.40.2']);
919
991
 
920
992
  expect(variants.length).toBe(2);
921
- expect(variants[0].video.codecs).toBe(avc1Codecs);
922
- expect(variants[0].audio.codecs).toBe('opus');
923
- expect(variants[1].video.codecs).toBe(vp09Codecs);
924
- expect(variants[1].audio.codecs).toBe('opus');
925
- });
926
-
927
- it('chooses variants with different sizes (density) by codecs', () => {
928
- manifest = shaka.test.ManifestGenerator.generate((manifest) => {
929
- addVariant1080Avc1(manifest);
930
- addVariant1080Vp9(manifest);
931
- addVariant2160Vp9(manifest);
932
- });
933
-
934
- shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
935
- /* preferredVideoCodecs= */[],
936
- /* preferredAudioCodecs= */[],
937
- /* preferredAudioChannelCount= */2,
938
- /* preferredDecodingAttributes= */[]);
939
-
940
- expect(manifest.variants.length).toBe(1);
941
- expect(manifest.variants[0].video.codecs).toBe(vp09Codecs);
942
- });
943
-
944
- it('chooses variants with same sizes (density) by codecs', () => {
945
- manifest = shaka.test.ManifestGenerator.generate((manifest) => {
946
- addVariant1080Avc1(manifest);
947
- addVariant1080Vp9(manifest);
948
- });
949
-
950
- shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
951
- /* preferredVideoCodecs= */[],
952
- /* preferredAudioCodecs= */[],
953
- /* preferredAudioChannelCount= */2,
954
- /* preferredDecodingAttributes= */[]);
955
-
956
- expect(manifest.variants.length).toBe(1);
957
- expect(manifest.variants[0].video.codecs).toBe(vp09Codecs);
993
+ expect(variants[0].video.codecs).toBe('avc1.640028');
994
+ expect(variants[0].audio.codecs).toBe('mp4a.40.2');
995
+ expect(variants[1].video.codecs).toBe('vp9');
996
+ expect(variants[1].audio.codecs).toBe('mp4a.40.2');
958
997
  });
959
998
 
960
999
  it('chooses variants by decoding attributes', async () => {
@@ -994,7 +1033,6 @@ describe('StreamUtils', () => {
994
1033
  shaka.util.StreamUtils.chooseCodecsAndFilterManifest(manifest,
995
1034
  /* preferredVideoCodecs= */[],
996
1035
  /* preferredAudioCodecs= */[],
997
- /* preferredAudioChannelCount= */2,
998
1036
  /* preferredDecodingAttributes= */
999
1037
  [shaka.util.StreamUtils.DecodingAttributes.SMOOTH]);
1000
1038
  // 2 video codecs are smooth. Choose the one with the lowest bandwidth.
@@ -7,6 +7,7 @@
7
7
  describe('TsParser', () => {
8
8
  const Util = shaka.test.Util;
9
9
  const BufferUtils = shaka.util.BufferUtils;
10
+ const ContentType = shaka.util.ManifestParserUtils.ContentType;
10
11
 
11
12
  it('probes a TS segment', async () => {
12
13
  const responses = await Promise.all([
@@ -59,9 +60,8 @@ describe('TsParser', () => {
59
60
  ]);
60
61
  const tsSegment = BufferUtils.toUint8(responses[0]);
61
62
  const starttime = new shaka.util.TsParser().parse(tsSegment)
62
- .getStartTime();
63
- expect(starttime.audio).toBeCloseTo(90019.586, 3);
64
- expect(starttime.video).toBe(null);
63
+ .getStartTime(ContentType.AUDIO);
64
+ expect(starttime).toBeCloseTo(90019.586, 3);
65
65
  });
66
66
 
67
67
  it('get the codecs from a TS segment', async () => {
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * Use new goog.Uri(string) to parse a URI string.
10
10
  *
11
- * e.g: <code>var myUri = new goog.Uri(window.location);</code>
11
+ * e.g.: <code>var myUri = new goog.Uri(window.location);</code>
12
12
  *
13
13
  * Implements RFC 3986 for parsing/formatting URIs.
14
14
  * http://www.ietf.org/rfc/rfc3986.txt
@@ -830,6 +830,18 @@ goog.Uri.QueryData.prototype.add = function(key, value) {
830
830
  };
831
831
 
832
832
 
833
+ /**
834
+ * Get the values from a key.
835
+ *
836
+ * @param {string} key Name.
837
+ * @return {Array.<string>}
838
+ */
839
+ goog.Uri.QueryData.prototype.get = function(key) {
840
+ this.ensureKeyMapInitialized_();
841
+ return this.keyMap_[key] || [];
842
+ };
843
+
844
+
833
845
  /**
834
846
  * @return {string} Encoded query string.
835
847
  * @override
@@ -68,7 +68,8 @@ shaka.ui.AudioLanguageSelection = class extends shaka.ui.SettingsMenu {
68
68
  shaka.ui.LanguageUtils.updateTracks(tracks, this.menu,
69
69
  (track) => this.onAudioTrackSelected_(track),
70
70
  /* updateChosen= */ true, this.currentSelection, this.localization,
71
- this.controls.getConfig().trackLabelFormat);
71
+ this.controls.getConfig().trackLabelFormat,
72
+ this.controls.getConfig().showAudioChannelCountVariants);
72
73
  shaka.ui.Utils.focusOnTheChosenItem(this.menu);
73
74
 
74
75
  this.controls.dispatchEvent(
@@ -89,7 +90,13 @@ shaka.ui.AudioLanguageSelection = class extends shaka.ui.SettingsMenu {
89
90
  * @private
90
91
  */
91
92
  onAudioTrackSelected_(track) {
92
- this.player.selectAudioLanguage(track.language, track.roles[0]);
93
+ if (track.channelsCount &&
94
+ this.controls.getConfig().showAudioChannelCountVariants) {
95
+ this.player.selectAudioLanguage(
96
+ track.language, track.roles[0], track.channelsCount);
97
+ } else {
98
+ this.player.selectAudioLanguage(track.language, track.roles[0]);
99
+ }
93
100
  }
94
101
 
95
102