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
@@ -35,6 +35,9 @@ shaka.util.TsParser = class {
35
35
  /** @private {!Array.<Uint8Array>} */
36
36
  this.videoData_ = [];
37
37
 
38
+ /** @private {!Array.<shaka.extern.MPEG_PES>} */
39
+ this.videoPes_ = [];
40
+
38
41
  /** @private {?number} */
39
42
  this.audioPid_ = null;
40
43
 
@@ -44,6 +47,9 @@ shaka.util.TsParser = class {
44
47
  /** @private {!Array.<Uint8Array>} */
45
48
  this.audioData_ = [];
46
49
 
50
+ /** @private {!Array.<shaka.extern.MPEG_PES>} */
51
+ this.audioPes_ = [];
52
+
47
53
  /** @private {?number} */
48
54
  this.id3Pid_ = null;
49
55
 
@@ -58,7 +64,9 @@ shaka.util.TsParser = class {
58
64
  */
59
65
  clearData() {
60
66
  this.videoData_ = [];
67
+ this.videoPes_ = [];
61
68
  this.audioData_ = [];
69
+ this.audioPes_ = [];
62
70
  this.id3Data_ = [];
63
71
  }
64
72
 
@@ -360,6 +368,7 @@ shaka.util.TsParser = class {
360
368
  packetLength: ((data[4] << 8) | data[5]),
361
369
  pts: null,
362
370
  dts: null,
371
+ nalus: [],
363
372
  };
364
373
 
365
374
  // if PES parsed length is not zero and greater than total received length,
@@ -427,10 +436,33 @@ shaka.util.TsParser = class {
427
436
  * @export
428
437
  */
429
438
  parseAvcNalus(pes, nextPes) {
439
+ shaka.Deprecate.deprecateFeature(5,
440
+ 'TsParser',
441
+ 'Please use parseNalus function instead.');
442
+ return this.parseNalus(pes);
443
+ }
444
+
445
+ /**
446
+ * Parse AVC and HVC Nalus
447
+ *
448
+ * The code is based on hls.js
449
+ * Credit to https://github.com/video-dev/hls.js/blob/master/src/demux/tsdemuxer.ts
450
+ *
451
+ * @param {shaka.extern.MPEG_PES} pes
452
+ * @param {?shaka.extern.VideoNalu=} lastNalu
453
+ * @return {!Array.<shaka.extern.VideoNalu>}
454
+ * @export
455
+ */
456
+ parseNalus(pes, lastNalu) {
430
457
  const timescale = shaka.util.TsParser.Timescale;
431
458
  const time = pes.pts ? pes.pts / timescale : null;
432
- let data = pes.data;
433
- let len = data.byteLength;
459
+ const data = pes.data;
460
+ const len = data.byteLength;
461
+
462
+ let naluHeaderSize = 1;
463
+ if (this.videoCodec_ == 'hvc') {
464
+ naluHeaderSize = 2;
465
+ }
434
466
 
435
467
  // A NALU does not contain is its size.
436
468
  // The Annex B specification solves this by requiring ‘Start Codes’ to
@@ -448,8 +480,6 @@ shaka.util.TsParser = class {
448
480
  // Extracted from the first byte.
449
481
  let lastNaluType = 0;
450
482
 
451
- let tryToFinishLastNalu = false;
452
-
453
483
  /** @type {?shaka.extern.VideoNalu} */
454
484
  let infoOfLastNalu;
455
485
 
@@ -457,25 +487,25 @@ shaka.util.TsParser = class {
457
487
  const value = data[i];
458
488
  if (!value) {
459
489
  numZeros++;
460
- } else if (numZeros >= 2 && value == 1 && tryToFinishLastNalu) {
461
- // If we are scanning the next PES, we need append the data to the
462
- // previous Nalu and don't scan for more nalus.
463
- const startCodeSize = numZeros > 3 ? 3 : numZeros;
464
- const lastByteToKeep = i - startCodeSize;
465
- // Optimization
466
- if (lastByteToKeep == 0) {
467
- break;
468
- }
469
- infoOfLastNalu.data = shaka.util.Uint8ArrayUtils.concat(
470
- infoOfLastNalu.data, data.subarray(0, lastByteToKeep));
471
- infoOfLastNalu.fullData = shaka.util.Uint8ArrayUtils.concat(
472
- infoOfLastNalu.fullData, data.subarray(0, lastByteToKeep));
473
- break;
474
490
  } else if (numZeros >= 2 && value == 1) {
491
+ if (lastNalu && !nalus.length && lastNaluStart == -1) {
492
+ // If we are scanning the next PES, we need append the data to the
493
+ // previous Nalu and don't scan for more nalus.
494
+ const startCodeSize = numZeros > 3 ? 3 : numZeros;
495
+ const lastByteToKeep = i - startCodeSize;
496
+ // Optimization
497
+ if (lastByteToKeep != 0) {
498
+ const prevData = data.subarray(0, lastByteToKeep);
499
+ lastNalu.data = shaka.util.Uint8ArrayUtils.concat(
500
+ lastNalu.data, prevData);
501
+ lastNalu.fullData = shaka.util.Uint8ArrayUtils.concat(
502
+ lastNalu.fullData, prevData);
503
+ }
504
+ }
475
505
  // We just read a start code. Consume the NALU we passed, if any.
476
506
  if (lastNaluStart >= 0) {
477
- // Because the start position includes the type, skip the first byte.
478
- const firstByteToKeep = lastNaluStart + 1;
507
+ // Because the start position includes the header size.
508
+ const firstByteToKeep = lastNaluStart + naluHeaderSize;
479
509
 
480
510
  // Compute the last byte to keep. The start code is at most 3 zeros.
481
511
  // Any earlier zeros are not part of the start code.
@@ -491,11 +521,20 @@ shaka.util.TsParser = class {
491
521
  time: time,
492
522
  };
493
523
  nalus.push(nalu);
524
+ } else if (lastNalu && !nalus.length) {
525
+ const overflow = i - numZeros;
526
+ if (overflow > 0) {
527
+ const prevData = data.subarray(0, overflow);
528
+ lastNalu.data = shaka.util.Uint8ArrayUtils.concat(
529
+ lastNalu.data, prevData);
530
+ lastNalu.fullData = shaka.util.Uint8ArrayUtils.concat(
531
+ lastNalu.fullData, prevData);
532
+ }
494
533
  }
495
534
 
496
535
  // We just read a start code, so there should be another byte here, at
497
536
  // least, for the NALU type. Check just in case.
498
- if (i >= len - 1) {
537
+ if (i >= len - naluHeaderSize) {
499
538
  shaka.log.warning('Malformed TS, incomplete NALU, ignoring.');
500
539
  return nalus;
501
540
  }
@@ -503,7 +542,11 @@ shaka.util.TsParser = class {
503
542
  // Advance and read the type of the next NALU.
504
543
  i++;
505
544
  lastNaluStart = i;
506
- lastNaluType = data[i] & 0x1f;
545
+ if (this.videoCodec_ == 'hvc') {
546
+ lastNaluType = (data[i] >> 1) & 0x3f;
547
+ } else {
548
+ lastNaluType = data[i] & 0x1f;
549
+ }
507
550
  numZeros = 0;
508
551
  } else {
509
552
  numZeros = 0;
@@ -512,34 +555,27 @@ shaka.util.TsParser = class {
512
555
  // unfinished Nalu, we will try to use the next PES to complete the
513
556
  // unfinished Nalu.
514
557
  if (i >= (len - 1) && lastNaluStart >= 0 && numZeros >= 0) {
515
- if (tryToFinishLastNalu) {
516
- infoOfLastNalu.data = shaka.util.Uint8ArrayUtils.concat(
517
- infoOfLastNalu.data, data);
518
- infoOfLastNalu.fullData = shaka.util.Uint8ArrayUtils.concat(
519
- infoOfLastNalu.fullData, data);
520
- } else {
521
- tryToFinishLastNalu = true;
522
- // The rest of the buffer was a NALU.
523
- // Because the start position includes the type, skip the first byte.
524
- const firstByteToKeep = lastNaluStart + 1;
525
- infoOfLastNalu = {
526
- data: data.subarray(firstByteToKeep, len),
527
- fullData: data.subarray(lastNaluStart, len),
528
- type: lastNaluType,
529
- time: time,
530
- };
531
- if (nextPes && pes.packetLength == 0) {
532
- data = nextPes.data;
533
- len = data.byteLength;
534
- i = -1;
535
- }
536
- }
558
+ // The rest of the buffer was a NALU.
559
+ // Because the start position includes the header size.
560
+ const firstByteToKeep = lastNaluStart + naluHeaderSize;
561
+ infoOfLastNalu = {
562
+ data: data.subarray(firstByteToKeep, len),
563
+ fullData: data.subarray(lastNaluStart, len),
564
+ type: lastNaluType,
565
+ time: time,
566
+ };
537
567
  }
538
568
  }
539
569
 
540
570
  if (infoOfLastNalu) {
541
571
  nalus.push(infoOfLastNalu);
542
572
  }
573
+ if (!nalus.length && lastNalu) {
574
+ lastNalu.data = shaka.util.Uint8ArrayUtils.concat(
575
+ lastNalu.data, data);
576
+ lastNalu.fullData = shaka.util.Uint8ArrayUtils.concat(
577
+ lastNalu.fullData, data);
578
+ }
543
579
  return nalus;
544
580
  }
545
581
 
@@ -574,73 +610,122 @@ shaka.util.TsParser = class {
574
610
  * @export
575
611
  */
576
612
  getAudioData() {
577
- const audio = [];
578
- for (const audioData of this.audioData_) {
579
- const pes = this.parsePES_(audioData);
580
- if (pes) {
581
- audio.push(pes);
613
+ if (this.audioData_.length && !this.audioPes_.length) {
614
+ let sort = false;
615
+ for (const audioData of this.audioData_) {
616
+ const pes = this.parsePES_(audioData);
617
+ if (pes && pes.pts != null && pes.dts != null) {
618
+ if (this.audioPes_.length &&
619
+ pes.dts < (this.audioPes_[this.audioPes_.length - 1].dts || 0)) {
620
+ sort = true;
621
+ }
622
+ this.audioPes_.push(pes);
623
+ } else if (this.audioPes_.length) {
624
+ const data = pes ? pes.data : audioData;
625
+ if (!data) {
626
+ continue;
627
+ }
628
+ const previousPes = this.audioPes_.pop();
629
+ previousPes.data =
630
+ shaka.util.Uint8ArrayUtils.concat(previousPes.data, data);
631
+ this.audioPes_.push(previousPes);
632
+ }
633
+ }
634
+ if (sort) {
635
+ this.audioPes_ = this.audioPes_.sort((a, b) => {
636
+ const deltadts = (a.dts || 0) - (b.dts || 0);
637
+ const deltapts = (a.pts || 0) - (b.pts || 0);
638
+ return deltadts || deltapts;
639
+ });
582
640
  }
583
641
  }
584
- return audio;
642
+ return this.audioPes_;
585
643
  }
586
644
 
587
645
  /**
588
646
  * Return the audio data
589
647
  *
648
+ * @param {boolean=} naluProcessing
590
649
  * @return {!Array.<shaka.extern.MPEG_PES>}
591
650
  * @export
592
651
  */
593
- getVideoData() {
594
- const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;
595
- const video = [];
596
- for (const videoData of this.videoData_) {
597
- const pes = this.parsePES_(videoData);
598
- if (pes && pes.pts != null && pes.dts != null) {
599
- video.push(pes);
600
- } else if (video.length) {
601
- const data = pes ? pes.data : videoData;
602
- if (!data) {
603
- continue;
652
+ getVideoData(naluProcessing = true) {
653
+ if (this.videoData_.length && !this.videoPes_.length) {
654
+ let sort = false;
655
+ for (const videoData of this.videoData_) {
656
+ const pes = this.parsePES_(videoData);
657
+ if (pes && pes.pts != null && pes.dts != null) {
658
+ if (this.videoPes_.length &&
659
+ pes.dts < (this.videoPes_[this.videoPes_.length - 1].dts || 0)) {
660
+ sort = true;
661
+ }
662
+ this.videoPes_.push(pes);
663
+ } else if (this.videoPes_.length) {
664
+ const data = pes ? pes.data : videoData;
665
+ if (!data) {
666
+ continue;
667
+ }
668
+ const previousPes = this.videoPes_.pop();
669
+ previousPes.data =
670
+ shaka.util.Uint8ArrayUtils.concat(previousPes.data, data);
671
+ this.videoPes_.push(previousPes);
604
672
  }
605
- const previousPes = video.pop();
606
- previousPes.data =
607
- Uint8ArrayUtils.concat(previousPes.data, data);
608
- video.push(previousPes);
609
673
  }
674
+ if (naluProcessing) {
675
+ let lastNalu;
676
+ for (const pes of this.videoPes_) {
677
+ pes.nalus = this.parseNalus(pes, lastNalu);
678
+ if (pes.nalus.length) {
679
+ lastNalu = pes.nalus[pes.nalus.length - 1];
680
+ }
681
+ }
682
+ this.videoPes_ = this.videoPes_.filter((pes) => {
683
+ return pes.nalus.length;
684
+ });
685
+ }
686
+ if (sort) {
687
+ this.videoPes_ = this.videoPes_.sort((a, b) => {
688
+ const deltadts = (a.dts || 0) - (b.dts || 0);
689
+ const deltapts = (a.pts || 0) - (b.pts || 0);
690
+ return deltadts || deltapts;
691
+ });
692
+ }
693
+ }
694
+ if (!naluProcessing) {
695
+ const prevVideoPes = this.videoPes_;
696
+ this.videoPes_ = [];
697
+ return prevVideoPes;
610
698
  }
611
- return video;
699
+ return this.videoPes_;
612
700
  }
613
701
 
614
702
  /**
615
703
  * Return the start time for the audio and video
616
704
  *
617
- * @return {{audio: ?number, video: ?number}}
705
+ * @param {string} contentType
706
+ * @return {?number}
618
707
  * @export
619
708
  */
620
- getStartTime() {
709
+ getStartTime(contentType) {
621
710
  const timescale = shaka.util.TsParser.Timescale;
622
- let audioStartTime = null;
623
- for (const pes of this.getAudioData()) {
624
- if (pes && pes.pts != null) {
625
- const startTime = Math.min(pes.dts, pes.pts) / timescale;
626
- if (audioStartTime == null || audioStartTime > startTime) {
627
- audioStartTime = startTime;
628
- }
711
+ if (contentType == 'audio') {
712
+ let audioStartTime = null;
713
+ const audioData = this.getAudioData();
714
+ if (audioData.length) {
715
+ const pes = audioData[0];
716
+ audioStartTime = Math.min(pes.dts, pes.pts) / timescale;
629
717
  }
630
- }
631
- let videoStartTime = null;
632
- for (const pes of this.getVideoData()) {
633
- if (pes && pes.pts != null) {
634
- const startTime = Math.min(pes.dts, pes.pts) / timescale;
635
- if (videoStartTime == null || videoStartTime > startTime) {
636
- videoStartTime = startTime;
637
- }
718
+ return audioStartTime;
719
+ } else if (contentType == 'video') {
720
+ let videoStartTime = null;
721
+ const videoData = this.getVideoData(/* naluProcessing= */ false);
722
+ if (videoData.length) {
723
+ const pes = videoData[0];
724
+ videoStartTime = Math.min(pes.dts, pes.pts) / timescale;
638
725
  }
726
+ return videoStartTime;
639
727
  }
640
- return {
641
- audio: audioStartTime,
642
- video: videoStartTime,
643
- };
728
+ return null;
644
729
  }
645
730
 
646
731
  /**
@@ -664,17 +749,8 @@ shaka.util.TsParser = class {
664
749
  */
665
750
  getVideoNalus() {
666
751
  const nalus = [];
667
- if (this.videoCodec_ != 'avc') {
668
- return nalus;
669
- }
670
- const videoData = this.getVideoData();
671
- for (let i = 0; i < videoData.length; i++) {
672
- const pes = videoData[i];
673
- let nextPes;
674
- if (i + 1 < videoData.length) {
675
- nextPes = videoData[i + 1];
676
- }
677
- nalus.push(...this.parseAvcNalus(pes, nextPes));
752
+ for (const pes of this.getVideoData()) {
753
+ nalus.push(...pes.nalus);
678
754
  }
679
755
  return nalus;
680
756
  }
@@ -703,6 +779,19 @@ shaka.util.TsParser = class {
703
779
  * @export
704
780
  */
705
781
  getVideoInfo() {
782
+ if (this.videoCodec_ == 'hvc') {
783
+ return this.getHvcInfo_();
784
+ }
785
+ return this.getAvcInfo_();
786
+ }
787
+
788
+ /**
789
+ * Return the video information for AVC
790
+ *
791
+ * @return {{height: ?string, width: ?string, codec: ?string}}
792
+ * @private
793
+ */
794
+ getAvcInfo_() {
706
795
  const TsParser = shaka.util.TsParser;
707
796
  const videoInfo = {
708
797
  height: null,
@@ -823,6 +912,146 @@ shaka.util.TsParser = class {
823
912
  return videoInfo;
824
913
  }
825
914
 
915
+ /**
916
+ * Return the video information for HVC
917
+ *
918
+ * @return {{height: ?string, width: ?string, codec: ?string}}
919
+ * @private
920
+ */
921
+ getHvcInfo_() {
922
+ const TsParser = shaka.util.TsParser;
923
+ const videoInfo = {
924
+ height: null,
925
+ width: null,
926
+ codec: null,
927
+ };
928
+ const videoNalus = this.getVideoNalus();
929
+ if (!videoNalus.length) {
930
+ return videoInfo;
931
+ }
932
+ const spsNalu = videoNalus.find((nalu) => {
933
+ return nalu.type == TsParser.H265_NALU_TYPE_SPS_;
934
+ });
935
+ if (!spsNalu) {
936
+ return videoInfo;
937
+ }
938
+
939
+ const gb = new shaka.util.ExpGolomb(
940
+ spsNalu.fullData, /* convertEbsp2rbsp= */ true);
941
+
942
+ // remove NALu Header
943
+ gb.readUnsignedByte();
944
+ gb.readUnsignedByte();
945
+
946
+ // SPS
947
+ gb.readBits(4); // video_paramter_set_id
948
+ const maxSubLayersMinus1 = gb.readBits(3);
949
+ gb.readBoolean(); // temporal_id_nesting_flag
950
+
951
+ // profile_tier_level begin
952
+ const generalProfileSpace = gb.readBits(2);
953
+ const generalTierFlag = gb.readBits(1);
954
+ const generalProfileIdc = gb.readBits(5);
955
+ const generalProfileCompatibilityFlags = gb.readBits(32);
956
+ const generalConstraintIndicatorFlags1 = gb.readUnsignedByte();
957
+ const generalConstraintIndicatorFlags2 = gb.readUnsignedByte();
958
+ const generalConstraintIndicatorFlags3 = gb.readUnsignedByte();
959
+ const generalConstraintIndicatorFlags4 = gb.readUnsignedByte();
960
+ const generalConstraintIndicatorFlags5 = gb.readUnsignedByte();
961
+ const generalConstraintIndicatorFlags6 = gb.readUnsignedByte();
962
+ const generalLevelIdc = gb.readUnsignedByte();
963
+ const subLayerProfilePresentFlag = [];
964
+ const subLayerLevelPresentFlag = [];
965
+ for (let i = 0; i < maxSubLayersMinus1; i++) {
966
+ subLayerProfilePresentFlag.push(gb.readBoolean());
967
+ subLayerLevelPresentFlag.push(gb.readBoolean());
968
+ }
969
+ if (maxSubLayersMinus1 > 0) {
970
+ for (let i = maxSubLayersMinus1; i < 8; i++) {
971
+ gb.readBits(2);
972
+ }
973
+ }
974
+ for (let i = 0; i < maxSubLayersMinus1; i++) {
975
+ if (subLayerProfilePresentFlag[i]) {
976
+ gb.readBits(88);
977
+ }
978
+ if (subLayerLevelPresentFlag[i]) {
979
+ gb.readUnsignedByte();
980
+ }
981
+ }
982
+ // profile_tier_level end
983
+
984
+ gb.readUnsignedExpGolomb(); // seq_parameter_set_id
985
+ const chromaFormatIdc = gb.readUnsignedExpGolomb();
986
+ if (chromaFormatIdc == 3) {
987
+ gb.readBits(1); // separate_colour_plane_flag
988
+ }
989
+ const picWidthInLumaSamples = gb.readUnsignedExpGolomb();
990
+ const picHeightInLumaSamples = gb.readUnsignedExpGolomb();
991
+ let leftOffset = 0;
992
+ let rightOffset = 0;
993
+ let topOffset = 0;
994
+ let bottomOffset = 0;
995
+ const conformanceWindowFlag = gb.readBoolean();
996
+ if (conformanceWindowFlag) {
997
+ leftOffset += gb.readUnsignedExpGolomb();
998
+ rightOffset += gb.readUnsignedExpGolomb();
999
+ topOffset += gb.readUnsignedExpGolomb();
1000
+ bottomOffset += gb.readUnsignedExpGolomb();
1001
+ }
1002
+
1003
+ const subWc = chromaFormatIdc === 1 || chromaFormatIdc === 2 ? 2 : 1;
1004
+ const subHc = chromaFormatIdc === 1 ? 2 : 1;
1005
+ videoInfo.width =
1006
+ String(picWidthInLumaSamples - (leftOffset + rightOffset) * subWc);
1007
+ videoInfo.height =
1008
+ String(picHeightInLumaSamples - (topOffset + bottomOffset) * subHc);
1009
+
1010
+ const reverseBits = (integer) => {
1011
+ let result = 0;
1012
+ for (let i = 0; i < 32; i++) {
1013
+ result |= ((integer >> i) & 1) << (31 - i);
1014
+ }
1015
+ return result >>> 0;
1016
+ };
1017
+
1018
+ const profileSpace = ['', 'A', 'B', 'C'][generalProfileSpace];
1019
+ const profileCompatibility = reverseBits(generalProfileCompatibilityFlags);
1020
+ const tierFlag = generalTierFlag == 1 ? 'H' : 'L';
1021
+
1022
+ let codec = 'hvc1';
1023
+ codec += '.' + profileSpace + generalProfileIdc;
1024
+ codec += '.' + profileCompatibility.toString(16).toUpperCase();
1025
+ codec += '.' + tierFlag + generalLevelIdc;
1026
+ if (generalConstraintIndicatorFlags6) {
1027
+ codec += '.' +
1028
+ generalConstraintIndicatorFlags6.toString(16).toUpperCase();
1029
+ }
1030
+ if (generalConstraintIndicatorFlags5) {
1031
+ codec += '.' +
1032
+ generalConstraintIndicatorFlags5.toString(16).toUpperCase();
1033
+ }
1034
+ if (generalConstraintIndicatorFlags4) {
1035
+ codec += '.' +
1036
+ generalConstraintIndicatorFlags4.toString(16).toUpperCase();
1037
+ }
1038
+ if (generalConstraintIndicatorFlags3) {
1039
+ codec += '.' +
1040
+ generalConstraintIndicatorFlags3.toString(16).toUpperCase();
1041
+ }
1042
+ if (generalConstraintIndicatorFlags2) {
1043
+ codec += '.' +
1044
+ generalConstraintIndicatorFlags2.toString(16).toUpperCase();
1045
+ }
1046
+ if (generalConstraintIndicatorFlags1) {
1047
+ codec += '.' +
1048
+ generalConstraintIndicatorFlags1.toString(16).toUpperCase();
1049
+ }
1050
+ videoInfo.codec = codec;
1051
+
1052
+ return videoInfo;
1053
+ }
1054
+
826
1055
  /**
827
1056
  * Convert a byte to 2 digits of hex. (Only handles values 0-255.)
828
1057
  *
@@ -904,6 +1133,14 @@ shaka.util.TsParser.PacketLength_ = 188;
904
1133
  shaka.util.TsParser.H264_NALU_TYPE_SPS_ = 0x07;
905
1134
 
906
1135
 
1136
+ /**
1137
+ * NALU type for Sequence Parameter Set (SPS) for H.265.
1138
+ * @const {number}
1139
+ * @private
1140
+ */
1141
+ shaka.util.TsParser.H265_NALU_TYPE_SPS_ = 0x21;
1142
+
1143
+
907
1144
  /**
908
1145
  * Values of profile_idc that indicate additional fields are included in the
909
1146
  * SPS.
@@ -115,7 +115,11 @@ shaka.util.Uint8ArrayUtils = class {
115
115
  const result = new Uint8Array(totalLength);
116
116
  let offset = 0;
117
117
  for (const arr of varArgs) {
118
- result.set(shaka.util.BufferUtils.toUint8(arr), offset);
118
+ if (arr instanceof Uint8Array) {
119
+ result.set(arr, offset);
120
+ } else {
121
+ result.set(shaka.util.BufferUtils.toUint8(arr), offset);
122
+ }
119
123
  offset += arr.byteLength;
120
124
  }
121
125
  return result;
@@ -397,6 +397,11 @@ shaka.util.XmlUtils = class {
397
397
  return null;
398
398
  }
399
399
 
400
+ // Cobalt browser doesn't support document.createNodeIterator.
401
+ if (!('createNodeIterator' in document)) {
402
+ return rootElem;
403
+ }
404
+
400
405
  // SECURITY: Verify that the document does not contain elements from the
401
406
  // HTML or SVG namespaces, which could trigger script execution and XSS.
402
407
  const iterator = document.createNodeIterator(
@@ -2,8 +2,9 @@
2
2
 
3
3
  We are currently maintaining the following branches of Shaka Player:
4
4
 
5
- - v4.4 (latest)
6
- - v4.3 (previous, also in use by the Cast Application Framework)
5
+ - v4.6 (latest)
6
+ - v4.5 (previous)
7
+ - v4.3 (in use by the Cast Application Framework)
7
8
  - No active LTS branches at this time
8
9
 
9
10
  Other branches are no longer receiving bug fixes, and we recommend you upgrade
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "shaka-player",
3
3
  "description": "DASH/EME video player library",
4
- "version": "4.4.3",
4
+ "version": "4.6.0",
5
5
  "homepage": "https://github.com/shaka-project/shaka-player",
6
6
  "author": "Google",
7
7
  "maintainers": [
@@ -48,11 +48,10 @@
48
48
  "karma-sourcemap-loader": "^0.3.8",
49
49
  "karma-spec-reporter": "^0.0.34",
50
50
  "karma-webdriver-launcher": "^1.0.8",
51
- "lcevc_dil.js": "^1.1.20",
51
+ "lcevc_dec.js": "^1.0.0",
52
52
  "less": "https://gitpkg.now.sh/joeyparrish/less.js/packages/less?28c63a43",
53
53
  "less-plugin-clean-css": "github:austingardner/less-plugin-clean-css#4e9e77bf",
54
54
  "material-design-lite": "^1.3.0",
55
- "mux.js": "^6.2.0",
56
55
  "open-sans-fonts": "^1.6.2",
57
56
  "postcss-less": "^6.0.0",
58
57
  "pwacompat": "^2.0.17",
@@ -75,12 +74,11 @@
75
74
  "eme-encryption-scheme-polyfill/index.js",
76
75
  "es6-promise-polyfill/promise.min.js",
77
76
  "google-closure-library/closure/goog/base.js",
78
- "lcevc_dil.js/dist/lcevc_dil.min.js",
79
- "lcevc_dil.js/dist/liblcevc_dpi.wasm",
77
+ "lcevc_dec.js/dist/lcevc_dec.min.js",
78
+ "lcevc_dec.js/dist/liblcevc_dpi.wasm",
80
79
  "less/dist/less.js",
81
80
  "material-design-lite/dist/material.indigo-blue.min.css",
82
81
  "material-design-lite/dist/material.min.js",
83
- "mux.js/dist/mux.min.js",
84
82
  "popper.js/dist/umd/popper.min.js",
85
83
  "pwacompat/pwacompat.min.js",
86
84
  "tippy.js/umd/index.min.js",