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
@@ -8,10 +8,11 @@ goog.provide('shaka.media.AdaptationSetCriteria');
8
8
  goog.provide('shaka.media.ExampleBasedCriteria');
9
9
  goog.provide('shaka.media.PreferenceBasedCriteria');
10
10
 
11
+ goog.require('shaka.config.CodecSwitchingStrategy');
11
12
  goog.require('shaka.log');
12
13
  goog.require('shaka.media.AdaptationSet');
14
+ goog.require('shaka.media.Capabilities');
13
15
  goog.require('shaka.util.LanguageUtils');
14
- goog.require('shaka.util.StreamUtils');
15
16
 
16
17
 
17
18
  /**
@@ -40,38 +41,54 @@ shaka.media.AdaptationSetCriteria = class {
40
41
  shaka.media.ExampleBasedCriteria = class {
41
42
  /**
42
43
  * @param {shaka.extern.Variant} example
44
+ * @param {shaka.config.CodecSwitchingStrategy=} codecSwitchingStrategy
45
+ * @param {boolean=} enableAudioGroups
43
46
  */
44
- constructor(example) {
47
+ constructor(example,
48
+ codecSwitchingStrategy = shaka.config.CodecSwitchingStrategy.RELOAD,
49
+ enableAudioGroups = false) {
45
50
  /** @private {shaka.extern.Variant} */
46
51
  this.example_ = example;
52
+ /** @private {shaka.config.CodecSwitchingStrategy} */
53
+ this.codecSwitchingStrategy_ = codecSwitchingStrategy;
54
+ /** @private {boolean} */
55
+ this.enableAudioGroups_ = enableAudioGroups;
56
+
47
57
 
48
58
  // We can't know if role and label are really important, so we don't use
49
59
  // role and label for this.
50
60
  const role = '';
51
61
  const label = '';
52
62
  const hdrLevel = '';
63
+ const videoLayout = '';
53
64
  const channelCount = example.audio && example.audio.channelsCount ?
54
65
  example.audio.channelsCount :
55
66
  0;
56
67
 
57
68
  /** @private {!shaka.media.AdaptationSetCriteria} */
58
69
  this.fallback_ = new shaka.media.PreferenceBasedCriteria(
59
- example.language, role, channelCount, hdrLevel, label);
70
+ example.language, role, channelCount, hdrLevel, videoLayout, label,
71
+ codecSwitchingStrategy, enableAudioGroups);
60
72
  }
61
73
 
62
74
  /** @override */
63
75
  create(variants) {
76
+ const supportsSmoothCodecTransitions = this.codecSwitchingStrategy_ ==
77
+ shaka.config.CodecSwitchingStrategy.SMOOTH &&
78
+ shaka.media.Capabilities.isChangeTypeSupported();
64
79
  // We can't assume that the example is in |variants| because it could
65
80
  // actually be from another period.
66
81
  const shortList = variants.filter((variant) => {
67
- return shaka.media.AdaptationSet.areAdaptable(this.example_, variant);
82
+ return shaka.media.AdaptationSet.areAdaptable(this.example_, variant,
83
+ !supportsSmoothCodecTransitions, this.enableAudioGroups_);
68
84
  });
69
85
 
70
86
  if (shortList.length) {
71
87
  // Use the first item in the short list as the root. It should not matter
72
88
  // which element we use as all items in the short list should already be
73
89
  // compatible.
74
- return new shaka.media.AdaptationSet(shortList[0], shortList);
90
+ return new shaka.media.AdaptationSet(shortList[0], shortList,
91
+ !supportsSmoothCodecTransitions, this.enableAudioGroups_);
75
92
  } else {
76
93
  return this.fallback_.create(variants);
77
94
  }
@@ -89,9 +106,14 @@ shaka.media.PreferenceBasedCriteria = class {
89
106
  * @param {string} role
90
107
  * @param {number} channelCount
91
108
  * @param {string} hdrLevel
109
+ * @param {string} videoLayout
92
110
  * @param {string=} label
111
+ * @param {shaka.config.CodecSwitchingStrategy=} codecSwitchingStrategy
112
+ * @param {boolean=} enableAudioGroups
93
113
  */
94
- constructor(language, role, channelCount, hdrLevel, label = '') {
114
+ constructor(language, role, channelCount, hdrLevel, videoLayout, label = '',
115
+ codecSwitchingStrategy = shaka.config.CodecSwitchingStrategy.RELOAD,
116
+ enableAudioGroups = false) {
95
117
  /** @private {string} */
96
118
  this.language_ = language;
97
119
  /** @private {string} */
@@ -101,13 +123,18 @@ shaka.media.PreferenceBasedCriteria = class {
101
123
  /** @private {string} */
102
124
  this.hdrLevel_ = hdrLevel;
103
125
  /** @private {string} */
126
+ this.videoLayout_ = videoLayout;
127
+ /** @private {string} */
104
128
  this.label_ = label;
129
+ /** @private {shaka.config.CodecSwitchingStrategy} */
130
+ this.codecSwitchingStrategy_ = codecSwitchingStrategy;
131
+ /** @private {boolean} */
132
+ this.enableAudioGroups_ = enableAudioGroups;
105
133
  }
106
134
 
107
135
  /** @override */
108
136
  create(variants) {
109
137
  const Class = shaka.media.PreferenceBasedCriteria;
110
- const StreamUtils = shaka.util.StreamUtils;
111
138
 
112
139
  let current = [];
113
140
 
@@ -131,6 +158,17 @@ shaka.media.PreferenceBasedCriteria = class {
131
158
  shaka.log.warning('No exact match for variant role could be found.');
132
159
  }
133
160
 
161
+ if (this.videoLayout_) {
162
+ const byVideoLayout = Class.filterVariantsByVideoLayout_(
163
+ current, this.videoLayout_);
164
+ if (byVideoLayout.length) {
165
+ current = byVideoLayout;
166
+ } else {
167
+ shaka.log.warning(
168
+ 'No exact match for the video layout could be found.');
169
+ }
170
+ }
171
+
134
172
  if (this.hdrLevel_) {
135
173
  const byHdrLevel = Class.filterVariantsByHDRLevel_(
136
174
  current, this.hdrLevel_);
@@ -143,7 +181,7 @@ shaka.media.PreferenceBasedCriteria = class {
143
181
  }
144
182
 
145
183
  if (this.channelCount_) {
146
- const byChannel = StreamUtils.filterVariantsByAudioChannelCount(
184
+ const byChannel = Class.filterVariantsByAudioChannelCount_(
147
185
  current, this.channelCount_);
148
186
  if (byChannel.length) {
149
187
  current = byChannel;
@@ -162,15 +200,12 @@ shaka.media.PreferenceBasedCriteria = class {
162
200
  }
163
201
  }
164
202
 
165
- // Make sure we only return a valid adaptation set.
166
- const set = new shaka.media.AdaptationSet(current[0]);
167
- for (const variant of current) {
168
- if (set.canInclude(variant)) {
169
- set.add(variant);
170
- }
171
- }
203
+ const supportsSmoothCodecTransitions = this.codecSwitchingStrategy_ ==
204
+ shaka.config.CodecSwitchingStrategy.SMOOTH &&
205
+ shaka.media.Capabilities.isChangeTypeSupported();
172
206
 
173
- return set;
207
+ return new shaka.media.AdaptationSet(current[0], current,
208
+ !supportsSmoothCodecTransitions, this.enableAudioGroups_);
174
209
  }
175
210
 
176
211
  /**
@@ -243,6 +278,23 @@ shaka.media.PreferenceBasedCriteria = class {
243
278
  });
244
279
  }
245
280
 
281
+ /**
282
+ * Filter Variants by channelCount.
283
+ *
284
+ * @param {!Array.<shaka.extern.Variant>} variants
285
+ * @param {number} channelCount
286
+ * @return {!Array.<shaka.extern.Variant>}
287
+ * @private
288
+ */
289
+ static filterVariantsByAudioChannelCount_(variants, channelCount) {
290
+ return variants.filter((variant) => {
291
+ if (variant.audio && variant.audio.channelsCount &&
292
+ variant.audio.channelsCount != channelCount) {
293
+ return false;
294
+ }
295
+ return true;
296
+ });
297
+ }
246
298
 
247
299
  /**
248
300
  * Filters variants according to the given hdr level config.
@@ -267,4 +319,22 @@ shaka.media.PreferenceBasedCriteria = class {
267
319
  return true;
268
320
  });
269
321
  }
322
+
323
+
324
+ /**
325
+ * Filters variants according to the given video layout config.
326
+ *
327
+ * @param {!Array.<shaka.extern.Variant>} variants
328
+ * @param {string} videoLayout
329
+ * @private
330
+ */
331
+ static filterVariantsByVideoLayout_(variants, videoLayout) {
332
+ return variants.filter((variant) => {
333
+ if (variant.video && variant.video.videoLayout &&
334
+ variant.video.videoLayout != videoLayout) {
335
+ return false;
336
+ }
337
+ return true;
338
+ });
339
+ }
270
340
  };
@@ -42,6 +42,12 @@ shaka.media.IClosedCaptionParser = class {
42
42
  * Resets the CaptionStream.
43
43
  */
44
44
  reset() {}
45
+
46
+ /**
47
+ * Returns the streams that the CEA decoder found.
48
+ * @return {!Array.<string>}
49
+ */
50
+ getStreams() {}
45
51
  };
46
52
 
47
53
  /**
@@ -112,6 +118,13 @@ shaka.media.ClosedCaptionParser = class {
112
118
  this.ceaDecoder_.clear();
113
119
  }
114
120
 
121
+ /**
122
+ * @override
123
+ */
124
+ getStreams() {
125
+ return this.ceaDecoder_.getStreams();
126
+ }
127
+
115
128
  /**
116
129
  * @param {string} mimeType
117
130
  * @param {!shaka.extern.CeaParserPlugin} plugin
@@ -105,6 +105,12 @@ shaka.media.ContentWorkarounds = class {
105
105
  newType: ContentWorkarounds.BOX_TYPE_ENCA_,
106
106
  });
107
107
  })
108
+ .fullBox('ac-4', (box) => {
109
+ boxesToModify.push({
110
+ box,
111
+ newType: ContentWorkarounds.BOX_TYPE_ENCA_,
112
+ });
113
+ })
108
114
  .fullBox('mp4a', (box) => {
109
115
  boxesToModify.push({
110
116
  box,
@@ -715,11 +715,8 @@ shaka.media.DrmEngine = class {
715
715
 
716
716
  const metadatas = this.activeSessions_.values();
717
717
  for (const metadata of metadatas) {
718
- // Tizen 2015 and 2016 models will send multiple webkitneedkey events
719
- // with the same init data. If the duplicates are supressed, playback
720
- // will stall without errors.
721
718
  if (shaka.util.BufferUtils.equal(initData, metadata.initData) &&
722
- !shaka.util.Platform.isTizen2()) {
719
+ this.config_.ignoreDuplicateInitData) {
723
720
  shaka.log.debug('Ignoring duplicate init data.');
724
721
  return;
725
722
  }
@@ -2045,15 +2042,13 @@ shaka.media.DrmEngine = class {
2045
2042
  // audio adaptations, so we shouldn't have to worry about checking
2046
2043
  // robustness.
2047
2044
  if (drm1.keySystem == drm2.keySystem) {
2048
- /** @type {Array<shaka.extern.InitDataOverride>} */
2049
- let initData = [];
2050
- initData = initData.concat(drm1.initData || []);
2051
- initData = initData.concat(drm2.initData || []);
2052
- initData = initData.filter((d, i) => {
2053
- return d.keyId === undefined || i === initData.findIndex((d2) => {
2054
- return d2.keyId === d.keyId;
2055
- });
2056
- });
2045
+ const initDataMap = new Map();
2046
+ const bothInitDatas = (drm1.initData || [])
2047
+ .concat(drm2.initData || []);
2048
+ for (const d of bothInitDatas) {
2049
+ initDataMap.set(d.keyId, d);
2050
+ }
2051
+ const initData = Array.from(initDataMap.values());
2057
2052
 
2058
2053
  const keyIds = drm1.keyIds && drm2.keyIds ?
2059
2054
  new Set([...drm1.keyIds, ...drm2.keyIds]) :
@@ -6,9 +6,8 @@
6
6
 
7
7
  goog.provide('shaka.media.ManifestParser');
8
8
 
9
- goog.require('goog.Uri');
9
+ goog.require('shaka.Deprecate');
10
10
  goog.require('shaka.log');
11
- goog.require('shaka.net.NetworkingEngine');
12
11
  goog.require('shaka.util.Error');
13
12
  goog.require('shaka.util.Platform');
14
13
 
@@ -28,7 +27,9 @@ shaka.media.ManifestParser = class {
28
27
  * @export
29
28
  */
30
29
  static registerParserByExtension(extension, parserFactory) {
31
- shaka.media.ManifestParser.parsersByExtension[extension] = parserFactory;
30
+ shaka.Deprecate.deprecateFeature(5,
31
+ 'ManifestParser',
32
+ 'Please use an ManifestParser with registerParserByMime function.');
32
33
  }
33
34
 
34
35
 
@@ -70,9 +71,6 @@ shaka.media.ManifestParser = class {
70
71
  for (const type in ManifestParser.parsersByMime) {
71
72
  support[type] = true;
72
73
  }
73
- for (const type in ManifestParser.parsersByExtension) {
74
- support[type] = true;
75
- }
76
74
  }
77
75
 
78
76
  // Make sure all well-known types are tested as well, just to show an
@@ -86,14 +84,6 @@ shaka.media.ManifestParser = class {
86
84
  // SmoothStreaming
87
85
  'application/vnd.ms-sstr+xml',
88
86
  ];
89
- const testExtensions = {
90
- // DASH
91
- 'mpd': 'application/dash+xml',
92
- // HLS
93
- 'm3u8': 'application/x-mpegurl',
94
- // SmoothStreaming
95
- 'ism': 'application/vnd.ms-sstr+xml',
96
- };
97
87
 
98
88
  for (const type of testMimeTypes) {
99
89
  // Only query our parsers for MSE-enabled platforms. Otherwise, query a
@@ -105,18 +95,6 @@ shaka.media.ManifestParser = class {
105
95
  }
106
96
  }
107
97
 
108
- for (const extension in testExtensions) {
109
- // Only query our parsers for MSE-enabled platforms. Otherwise, query a
110
- // temporary media element for native support for these MIME type for the
111
- // extension.
112
- if (shaka.util.Platform.supportsMediaSource()) {
113
- support[extension] = !!ManifestParser.parsersByExtension[extension];
114
- } else {
115
- const type = testExtensions[extension];
116
- support[extension] = shaka.util.Platform.supportsMediaType(type);
117
- }
118
- }
119
-
120
98
  return support;
121
99
  }
122
100
 
@@ -126,12 +104,10 @@ shaka.media.ManifestParser = class {
126
104
  * parse the manifest at |uri|.
127
105
  *
128
106
  * @param {string} uri
129
- * @param {!shaka.net.NetworkingEngine} netEngine
130
- * @param {shaka.extern.RetryParameters} retryParams
131
107
  * @param {?string} mimeType
132
- * @return {!Promise.<shaka.extern.ManifestParser.Factory>}
108
+ * @return {shaka.extern.ManifestParser.Factory}
133
109
  */
134
- static async getFactory(uri, netEngine, retryParams, mimeType) {
110
+ static getFactory(uri, mimeType) {
135
111
  const ManifestParser = shaka.media.ManifestParser;
136
112
 
137
113
  // Try using the MIME type we were given.
@@ -145,33 +121,6 @@ shaka.media.ManifestParser = class {
145
121
  'Could not determine manifest type using MIME type ', mimeType);
146
122
  }
147
123
 
148
- const extension = ManifestParser.getExtension(uri);
149
- if (extension) {
150
- const factory = ManifestParser.parsersByExtension[extension];
151
- if (factory) {
152
- return factory;
153
- }
154
-
155
- shaka.log.warning(
156
- 'Could not determine manifest type for extension ', extension);
157
- } else {
158
- shaka.log.warning('Could not find extension for ', uri);
159
- }
160
-
161
- if (!mimeType) {
162
- mimeType = await ManifestParser.getMimeType(uri, netEngine, retryParams);
163
-
164
- if (mimeType) {
165
- const factory = shaka.media.ManifestParser.parsersByMime[mimeType];
166
- if (factory) {
167
- return factory;
168
- }
169
-
170
- shaka.log.warning('Could not determine manifest type using MIME type',
171
- mimeType);
172
- }
173
- }
174
-
175
124
  throw new shaka.util.Error(
176
125
  shaka.util.Error.Severity.CRITICAL,
177
126
  shaka.util.Error.Category.MANIFEST,
@@ -181,56 +130,15 @@ shaka.media.ManifestParser = class {
181
130
 
182
131
 
183
132
  /**
184
- * @param {string} uri
185
- * @param {!shaka.net.NetworkingEngine} netEngine
186
- * @param {shaka.extern.RetryParameters} retryParams
187
- * @return {!Promise.<string>}
188
- */
189
- static async getMimeType(uri, netEngine, retryParams) {
190
- const type = shaka.net.NetworkingEngine.RequestType.MANIFEST;
191
-
192
- const request = shaka.net.NetworkingEngine.makeRequest([uri], retryParams);
193
- request.method = 'HEAD';
194
-
195
- const response = await netEngine.request(type, request).promise;
196
-
197
- // https://bit.ly/2K9s9kf says this header should always be available,
198
- // but just to be safe:
199
- const mimeType = response.headers['content-type'];
200
- return mimeType ? mimeType.toLowerCase().split(';').shift() : '';
201
- }
202
-
203
-
204
- /**
205
- * @param {string} uri
206
- * @return {string}
207
- */
208
- static getExtension(uri) {
209
- const uriObj = new goog.Uri(uri);
210
- const uriPieces = uriObj.getPath().split('/');
211
- const uriFilename = uriPieces.pop();
212
- const filenamePieces = uriFilename.split('.');
213
-
214
- // Only one piece means there is no extension.
215
- if (filenamePieces.length == 1) {
216
- return '';
217
- }
218
-
219
- return filenamePieces.pop().toLowerCase();
220
- }
221
-
222
-
223
- /**
224
- * Determines whether or not this URI and MIME type are supported by our own
133
+ * Determines whether or not the MIME type is supported by our own
225
134
  * manifest parsers on this platform. This takes into account whether or not
226
135
  * MediaSource is available, as well as which parsers are registered to the
227
136
  * system.
228
137
  *
229
- * @param {string} uri
230
138
  * @param {string} mimeType
231
139
  * @return {boolean}
232
140
  */
233
- static isSupported(uri, mimeType) {
141
+ static isSupported(mimeType) {
234
142
  // Without MediaSource, our own parsers are useless.
235
143
  if (!shaka.util.Platform.supportsMediaSource()) {
236
144
  return false;
@@ -240,11 +148,6 @@ shaka.media.ManifestParser = class {
240
148
  return true;
241
149
  }
242
150
 
243
- const extension = shaka.media.ManifestParser.getExtension(uri);
244
- if (extension in shaka.media.ManifestParser.parsersByExtension) {
245
- return true;
246
- }
247
-
248
151
  return false;
249
152
  }
250
153
  };
@@ -292,11 +195,3 @@ shaka.media.ManifestParser.AccessibilityPurpose = {
292
195
  shaka.media.ManifestParser.parsersByMime = {};
293
196
 
294
197
 
295
- /**
296
- * Contains the parser factory functions indexed by file extension.
297
- *
298
- * @type {!Object.<string, shaka.extern.ManifestParser.Factory>}
299
- */
300
- shaka.media.ManifestParser.parsersByExtension = {};
301
-
302
-
@@ -23,9 +23,16 @@ shaka.media.Capabilities = class {
23
23
  if (supportMap.has(type)) {
24
24
  return supportMap.get(type);
25
25
  }
26
- const currentSupport = MediaSource.isTypeSupported(type);
27
- supportMap.set(type, currentSupport);
28
- return currentSupport;
26
+ if (window.ManagedMediaSource) {
27
+ const currentSupport = ManagedMediaSource.isTypeSupported(type);
28
+ supportMap.set(type, currentSupport);
29
+ return currentSupport;
30
+ } else if (window.MediaSource) {
31
+ const currentSupport = MediaSource.isTypeSupported(type);
32
+ supportMap.set(type, currentSupport);
33
+ return currentSupport;
34
+ }
35
+ return false;
29
36
  }
30
37
 
31
38
  /**