shaka-player 4.3.11 → 4.4.1

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 (315) hide show
  1. package/AUTHORS +9 -0
  2. package/CHANGELOG.md +303 -202
  3. package/CONTRIBUTORS +8 -0
  4. package/LICENSE +32 -0
  5. package/README.md +63 -10
  6. package/demo/autoTemplate.txt +40 -5
  7. package/demo/close_button.js +11 -0
  8. package/demo/common/asset.js +13 -1
  9. package/demo/common/assets.js +53 -3
  10. package/demo/common/message_ids.js +25 -1
  11. package/demo/config.js +69 -10
  12. package/demo/customWarning.txt +2 -2
  13. package/demo/index.html +3 -1
  14. package/demo/locales/en.json +26 -2
  15. package/demo/locales/source.json +105 -9
  16. package/demo/main.js +52 -9
  17. package/demo/search.js +3 -1
  18. package/demo/service_worker.js +3 -0
  19. package/dist/controls.css +1 -1
  20. package/dist/controls.css.map +1 -1
  21. package/dist/demo.compiled.debug.js +124 -112
  22. package/dist/demo.compiled.debug.map +3 -3
  23. package/dist/demo.compiled.js +124 -112
  24. package/dist/demo.compiled.map +3 -3
  25. package/dist/deps.js +46 -28
  26. package/dist/locales.js +33 -33
  27. package/dist/receiver.compiled.debug.js +52 -46
  28. package/dist/receiver.compiled.debug.map +3 -3
  29. package/dist/receiver.compiled.js +52 -46
  30. package/dist/receiver.compiled.map +3 -3
  31. package/dist/shaka-player.compiled.d.ts +676 -391
  32. package/dist/shaka-player.compiled.debug.d.ts +676 -391
  33. package/dist/shaka-player.compiled.debug.externs.js +1188 -616
  34. package/dist/shaka-player.compiled.debug.js +1043 -699
  35. package/dist/shaka-player.compiled.debug.map +4 -4
  36. package/dist/shaka-player.compiled.externs.js +1188 -616
  37. package/dist/shaka-player.compiled.js +1091 -929
  38. package/dist/shaka-player.compiled.map +4 -4
  39. package/dist/shaka-player.ui.d.ts +677 -392
  40. package/dist/shaka-player.ui.debug.d.ts +677 -392
  41. package/dist/shaka-player.ui.debug.externs.js +1023 -451
  42. package/dist/shaka-player.ui.debug.js +1098 -737
  43. package/dist/shaka-player.ui.debug.map +4 -4
  44. package/dist/shaka-player.ui.externs.js +1023 -451
  45. package/dist/shaka-player.ui.js +1246 -1071
  46. package/dist/shaka-player.ui.map +4 -4
  47. package/docs/tutorials/ad_monetization.md +15 -1
  48. package/docs/tutorials/application-level-redirects.md +1 -1
  49. package/docs/tutorials/config.md +9 -5
  50. package/docs/tutorials/drm-config.md +61 -0
  51. package/docs/tutorials/fairplay.md +19 -4
  52. package/docs/tutorials/license-server-auth.md +4 -4
  53. package/docs/tutorials/license-wrapping.md +2 -2
  54. package/docs/tutorials/ui-customization.md +7 -3
  55. package/docs/tutorials/ui.md +7 -7
  56. package/docs/tutorials/upgrade.md +3 -0
  57. package/externs/ima.js +123 -2
  58. package/externs/isoboxer.js +217 -0
  59. package/externs/mediakeys.js +18 -0
  60. package/externs/mux.js +1 -105
  61. package/externs/pictureinpicture.js +48 -0
  62. package/externs/shaka/ads.js +61 -1
  63. package/externs/shaka/cea.js +110 -0
  64. package/externs/shaka/codecs.js +32 -0
  65. package/externs/shaka/manifest.js +101 -1
  66. package/externs/shaka/manifest_parser.js +0 -10
  67. package/externs/shaka/net.js +36 -7
  68. package/externs/shaka/offline.js +8 -1
  69. package/externs/shaka/player.js +220 -21
  70. package/externs/shaka/text.js +1 -382
  71. package/externs/shaka/transmuxer.js +60 -0
  72. package/karma.conf.js +13 -0
  73. package/lib/abr/simple_abr_manager.js +6 -3
  74. package/lib/ads/ad_manager.js +60 -2
  75. package/lib/ads/client_side_ad.js +86 -0
  76. package/lib/ads/client_side_ad_manager.js +79 -3
  77. package/lib/ads/server_side_ad.js +86 -0
  78. package/lib/ads/server_side_ad_manager.js +13 -0
  79. package/lib/cast/cast_utils.js +1 -0
  80. package/lib/cea/cea608_data_channel.js +24 -14
  81. package/lib/cea/cea608_memory.js +5 -2
  82. package/lib/cea/cea708_service.js +8 -9
  83. package/lib/cea/cea708_window.js +1 -2
  84. package/lib/cea/cea_decoder.js +23 -6
  85. package/lib/cea/cea_utils.js +25 -2
  86. package/lib/cea/dummy_caption_decoder.js +21 -0
  87. package/lib/cea/dummy_cea_parser.js +1 -3
  88. package/lib/cea/mp4_cea_parser.js +15 -10
  89. package/lib/cea/ts_cea_parser.js +69 -0
  90. package/lib/dash/content_protection.js +32 -2
  91. package/lib/dash/dash_parser.js +93 -31
  92. package/lib/dash/mpd_utils.js +6 -25
  93. package/lib/dash/segment_base.js +12 -14
  94. package/lib/dash/segment_list.js +10 -6
  95. package/lib/dash/segment_template.js +349 -32
  96. package/lib/dependencies/all.js +8 -0
  97. package/lib/hls/hls_classes.js +33 -8
  98. package/lib/hls/hls_parser.js +805 -191
  99. package/lib/hls/manifest_text_parser.js +4 -14
  100. package/lib/media/adaptation_set_criteria.js +43 -3
  101. package/lib/media/closed_caption_parser.js +74 -12
  102. package/lib/media/drm_engine.js +189 -49
  103. package/lib/media/gap_jumping_controller.js +1 -1
  104. package/lib/media/manifest_parser.js +34 -0
  105. package/lib/media/media_source_capabilities.js +10 -0
  106. package/lib/media/media_source_engine.js +495 -231
  107. package/lib/media/playhead.js +1 -1
  108. package/lib/media/presentation_timeline.js +62 -0
  109. package/lib/media/segment_index.js +50 -14
  110. package/lib/media/segment_prefetch.js +277 -0
  111. package/lib/media/segment_reference.js +70 -4
  112. package/lib/media/streaming_engine.js +258 -81
  113. package/lib/media/video_wrapper.js +15 -7
  114. package/lib/mss/content_protection.js +353 -0
  115. package/lib/mss/mss_parser.js +1082 -0
  116. package/lib/net/networking_engine.js +60 -10
  117. package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
  118. package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
  119. package/lib/offline/manifest_converter.js +6 -0
  120. package/lib/offline/storage.js +2 -4
  121. package/lib/player.js +309 -105
  122. package/lib/polyfill/media_capabilities.js +43 -3
  123. package/lib/polyfill/patchedmediakeys_apple.js +5 -0
  124. package/lib/polyfill/patchedmediakeys_nop.js +5 -0
  125. package/lib/polyfill/patchedmediakeys_webkit.js +5 -0
  126. package/lib/text/cue.js +208 -130
  127. package/lib/text/lrc_text_parser.js +2 -2
  128. package/lib/text/mp4_vtt_parser.js +2 -2
  129. package/lib/text/sbv_text_parser.js +1 -1
  130. package/lib/text/simple_text_displayer.js +1 -1
  131. package/lib/text/srt_text_parser.js +9 -1
  132. package/lib/text/ssa_text_parser.js +2 -2
  133. package/lib/text/text_engine.js +3 -21
  134. package/lib/text/text_utils.js +71 -20
  135. package/lib/text/ui_text_displayer.js +14 -14
  136. package/lib/text/vtt_text_parser.js +22 -14
  137. package/lib/transmuxer/aac_transmuxer.js +224 -0
  138. package/lib/transmuxer/ac3.js +142 -0
  139. package/lib/transmuxer/ac3_transmuxer.js +213 -0
  140. package/lib/transmuxer/adts.js +232 -0
  141. package/lib/transmuxer/ec3.js +103 -0
  142. package/lib/transmuxer/ec3_transmuxer.js +213 -0
  143. package/lib/transmuxer/h264.js +324 -0
  144. package/lib/transmuxer/mp3_transmuxer.js +205 -0
  145. package/lib/transmuxer/mpeg_audio.js +196 -0
  146. package/lib/transmuxer/mpeg_ts_transmuxer.js +182 -0
  147. package/lib/transmuxer/mss_transmuxer.js +389 -0
  148. package/lib/{media/transmuxer.js → transmuxer/muxjs_transmuxer.js} +34 -80
  149. package/lib/transmuxer/transmuxer_engine.js +161 -0
  150. package/lib/transmuxer/ts_transmuxer.js +721 -0
  151. package/lib/util/cmcd_manager.js +131 -71
  152. package/lib/util/error.js +62 -26
  153. package/lib/util/exp_golomb.js +220 -0
  154. package/lib/util/fairplay_utils.js +64 -13
  155. package/lib/util/id3_utils.js +56 -3
  156. package/lib/util/language_utils.js +11 -8
  157. package/lib/util/manifest_parser_utils.js +3 -0
  158. package/lib/util/mime_utils.js +44 -7
  159. package/lib/util/mp4_box_parsers.js +233 -5
  160. package/lib/util/mp4_generator.js +1388 -0
  161. package/lib/util/periods.js +40 -34
  162. package/lib/util/platform.js +17 -3
  163. package/lib/util/player_configuration.js +38 -1
  164. package/lib/util/stream_utils.js +138 -27
  165. package/lib/util/text_parser.js +1 -1
  166. package/lib/util/ts_parser.js +460 -74
  167. package/lib/util/xml_utils.js +16 -3
  168. package/maintained-branches.md +2 -2
  169. package/package.json +3 -1
  170. package/roadmap.md +21 -6
  171. package/shaka-player.uncompiled.js +18 -0
  172. package/test/abr/simple_abr_manager_unit.js +32 -4
  173. package/test/ads/ad_manager_unit.js +18 -2
  174. package/test/cast/cast_utils_unit.js +7 -2
  175. package/test/cea/cea608_memory_unit.js +24 -0
  176. package/test/cea/cea_decoder_unit.js +33 -0
  177. package/test/dash/dash_parser_content_protection_unit.js +93 -3
  178. package/test/dash/dash_parser_live_unit.js +56 -13
  179. package/test/dash/dash_parser_manifest_unit.js +70 -2
  180. package/test/dash/dash_parser_segment_base_unit.js +14 -9
  181. package/test/dash/dash_parser_segment_template_unit.js +286 -6
  182. package/test/demo/demo_unit.js +5 -1
  183. package/test/hls/hls_live_unit.js +188 -28
  184. package/test/hls/hls_parser_unit.js +250 -109
  185. package/test/hls/manifest_text_parser_unit.js +18 -13
  186. package/test/media/adaptation_set_criteria_unit.js +46 -14
  187. package/test/media/adaptation_set_unit.js +2 -0
  188. package/test/media/drm_engine_integration.js +11 -8
  189. package/test/media/drm_engine_unit.js +220 -7
  190. package/test/media/media_source_engine_integration.js +124 -40
  191. package/test/media/media_source_engine_unit.js +133 -153
  192. package/test/media/playhead_unit.js +3 -0
  193. package/test/media/presentation_timeline_unit.js +51 -0
  194. package/test/media/segment_index_unit.js +52 -0
  195. package/test/media/segment_prefetch_unit.js +243 -0
  196. package/test/media/streaming_engine_integration.js +9 -3
  197. package/test/media/streaming_engine_unit.js +440 -59
  198. package/test/mss/mss_parser_content_protection_unit.js +49 -0
  199. package/test/mss/mss_parser_unit.js +472 -0
  200. package/test/mss/mss_player_integration.js +123 -0
  201. package/test/offline/manifest_convert_unit.js +9 -0
  202. package/test/offline/storage_integration.js +6 -1
  203. package/test/player_unit.js +386 -133
  204. package/test/polyfill/media_capabilities_unit.js +18 -0
  205. package/test/test/assets/hls-raw-aac/fileSequence0.aac +0 -0
  206. package/test/test/assets/hls-raw-aac/fileSequence1.aac +0 -0
  207. package/test/test/assets/hls-raw-aac/fileSequence2.aac +0 -0
  208. package/test/test/assets/hls-raw-aac/fileSequence3.aac +0 -0
  209. package/test/test/assets/hls-raw-aac/manifest.m3u8 +4 -0
  210. package/test/test/assets/hls-raw-aac/stream.m4a.m3u8 +14 -0
  211. package/test/test/assets/hls-raw-ac3/fileSequence0.ac3 +0 -0
  212. package/test/test/assets/hls-raw-ac3/fileSequence1.ac3 +0 -0
  213. package/test/test/assets/hls-raw-ac3/fileSequence2.ac3 +0 -0
  214. package/test/test/assets/hls-raw-ac3/fileSequence3.ac3 +0 -0
  215. package/test/test/assets/hls-raw-ac3/fileSequence4.ac3 +0 -0
  216. package/test/test/assets/hls-raw-ac3/fileSequence5.ac3 +0 -0
  217. package/test/test/assets/hls-raw-ac3/fileSequence6.ac3 +0 -0
  218. package/test/test/assets/hls-raw-ac3/fileSequence7.ac3 +0 -0
  219. package/test/test/assets/hls-raw-ac3/prog_index.m3u8 +31 -0
  220. package/test/test/assets/hls-raw-ec3/fileSequence0.ec3 +0 -0
  221. package/test/test/assets/hls-raw-ec3/fileSequence1.ec3 +0 -0
  222. package/test/test/assets/hls-raw-ec3/fileSequence2.ec3 +0 -0
  223. package/test/test/assets/hls-raw-ec3/fileSequence3.ec3 +0 -0
  224. package/test/test/assets/hls-raw-ec3/fileSequence4.ec3 +0 -0
  225. package/test/test/assets/hls-raw-ec3/fileSequence5.ec3 +0 -0
  226. package/test/test/assets/hls-raw-ec3/fileSequence6.ec3 +0 -0
  227. package/test/test/assets/hls-raw-ec3/fileSequence7.ec3 +0 -0
  228. package/test/test/assets/hls-raw-ec3/prog_index.m3u8 +31 -0
  229. package/test/test/assets/hls-raw-mp3/chunklist_w905519204.m3u8 +13 -0
  230. package/test/test/assets/hls-raw-mp3/media_w905519204_0.mp3 +0 -0
  231. package/test/test/assets/hls-raw-mp3/media_w905519204_1.mp3 +0 -0
  232. package/test/test/assets/hls-raw-mp3/media_w905519204_2.mp3 +0 -0
  233. package/test/test/assets/hls-raw-mp3/media_w905519204_3.mp3 +0 -0
  234. package/test/test/assets/hls-raw-mp3/playlist.m3u8 +4 -0
  235. package/test/test/assets/hls-ts-aac/playlist.m3u8 +23 -0
  236. package/test/test/assets/hls-ts-aac/segment_0.ts +0 -0
  237. package/test/test/assets/hls-ts-aac/segment_1.ts +0 -0
  238. package/test/test/assets/hls-ts-aac/segment_2.ts +0 -0
  239. package/test/test/assets/hls-ts-aac/segment_3.ts +0 -0
  240. package/test/test/assets/hls-ts-aac/segment_4.ts +0 -0
  241. package/test/test/assets/hls-ts-aac/segment_5.ts +0 -0
  242. package/test/test/assets/hls-ts-aac/segment_6.ts +0 -0
  243. package/test/test/assets/hls-ts-aac/segment_7.ts +0 -0
  244. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0000.ts +0 -0
  245. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0001.ts +0 -0
  246. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0002.ts +0 -0
  247. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0003.ts +0 -0
  248. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0004.ts +0 -0
  249. package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0005.ts +0 -0
  250. package/test/test/assets/hls-ts-ac3/prog_index.m3u8 +19 -0
  251. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0000.ts +0 -0
  252. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0001.ts +0 -0
  253. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0002.ts +0 -0
  254. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0003.ts +0 -0
  255. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0004.ts +0 -0
  256. package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0005.ts +0 -0
  257. package/test/test/assets/hls-ts-ec3/prog_index.m3u8 +19 -0
  258. package/test/test/assets/hls-ts-h264/fileSequence0.ts +0 -0
  259. package/test/test/assets/hls-ts-h264/fileSequence1.ts +0 -0
  260. package/test/test/assets/hls-ts-h264/fileSequence2.ts +0 -0
  261. package/test/test/assets/hls-ts-h264/fileSequence3.ts +0 -0
  262. package/test/test/assets/hls-ts-h264/fileSequence4.ts +0 -0
  263. package/test/test/assets/hls-ts-h264/fileSequence5.ts +0 -0
  264. package/test/test/assets/hls-ts-h264/prog_index.m3u8 +25 -0
  265. package/test/test/assets/hls-ts-mp3/manifest.m3u8 +13 -0
  266. package/test/test/assets/hls-ts-mp3/media_w239891843_0.ts +0 -0
  267. package/test/test/assets/hls-ts-mp3/media_w239891843_1.ts +0 -0
  268. package/test/test/assets/hls-ts-mp3/media_w239891843_2.ts +0 -0
  269. package/test/test/assets/hls-ts-mp3/media_w239891843_3.ts +0 -0
  270. package/test/test/assets/hls-ts-muxed-aac-h264/chunk.m3u8 +17 -0
  271. package/test/test/assets/hls-ts-muxed-aac-h264/n_0_0_0.ts +0 -0
  272. package/test/test/assets/hls-ts-muxed-aac-h264/n_1_0_0.ts +0 -0
  273. package/test/test/assets/hls-ts-muxed-aac-h264/n_2_0_0.ts +0 -0
  274. package/test/test/assets/hls-ts-muxed-aac-h264/n_3_0_0.ts +0 -0
  275. package/test/test/assets/hls-ts-muxed-aac-h264/n_4_0_0.ts +0 -0
  276. package/test/test/assets/hls-ts-muxed-aac-h264/n_5_0_0.ts +0 -0
  277. package/test/test/assets/hls-ts-muxed-aac-h264/playlist.m3u8 +4 -0
  278. package/test/test/boot.js +7 -2
  279. package/test/test/util/fake_ad.js +99 -0
  280. package/test/test/util/fake_ad_manager.js +7 -1
  281. package/test/test/util/fake_networking_engine.js +41 -14
  282. package/test/test/util/fake_segment_prefetch.js +81 -0
  283. package/test/test/util/manifest_generator.js +19 -5
  284. package/test/test/util/mss_parser_util.js +115 -0
  285. package/test/test/util/offline_utils.js +1 -0
  286. package/test/test/util/simple_fakes.js +12 -3
  287. package/test/test/util/streaming_engine_util.js +14 -4
  288. package/test/test/util/ttml_utils.js +2 -2
  289. package/test/text/cue_integration.js +1 -1
  290. package/test/text/srt_text_parser_unit.js +78 -0
  291. package/test/text/text_engine_unit.js +17 -8
  292. package/test/text/ui_text_displayer_unit.js +4 -4
  293. package/test/text/vtt_text_parser_unit.js +59 -40
  294. package/test/text/web_vtt_generator_unit.js +9 -3
  295. package/test/{media/transmuxer_integration.js → transmuxer/muxjs_transmuxer_integration.js} +30 -33
  296. package/test/transmuxer/transmuxer_engine_integration.js +60 -0
  297. package/test/transmuxer/transmuxer_integration.js +296 -0
  298. package/test/util/cmcd_manager_unit.js +162 -13
  299. package/test/util/language_utils_unit.js +9 -2
  300. package/test/util/mp4_box_parsers_unit.js +39 -4
  301. package/test/util/periods_unit.js +34 -26
  302. package/test/util/stream_utils_unit.js +60 -107
  303. package/ui/controls.js +19 -1
  304. package/ui/controls.less +1 -0
  305. package/ui/externs/ui.js +11 -1
  306. package/ui/language_utils.js +15 -0
  307. package/ui/less/thumbnails.less +26 -0
  308. package/ui/locales/oc.json +42 -0
  309. package/ui/pip_button.js +83 -2
  310. package/ui/range_element.js +15 -0
  311. package/ui/resolution_selection.js +9 -2
  312. package/ui/seek_bar.js +223 -0
  313. package/ui/ui.js +5 -0
  314. package/lib/cea/i_caption_decoder.js +0 -51
  315. package/lib/cea/i_cea_parser.js +0 -68
@@ -6,8 +6,8 @@
6
6
 
7
7
  goog.provide('shaka.util.TsParser');
8
8
 
9
- goog.require('goog.asserts');
10
9
  goog.require('shaka.log');
10
+ goog.require('shaka.util.ExpGolomb');
11
11
  goog.require('shaka.util.Id3Utils');
12
12
  goog.require('shaka.util.Uint8ArrayUtils');
13
13
 
@@ -25,9 +25,6 @@ shaka.util.TsParser = class {
25
25
  /** @private {boolean} */
26
26
  this.pmtParsed_ = false;
27
27
 
28
- /** @private {?number} */
29
- this.videoStartTime_ = null;
30
-
31
28
  /** @private {?number} */
32
29
  this.videoPid_ = null;
33
30
 
@@ -37,9 +34,6 @@ shaka.util.TsParser = class {
37
34
  /** @private {!Array.<Uint8Array>} */
38
35
  this.videoData_ = [];
39
36
 
40
- /** @private {?number} */
41
- this.audioStartTime_ = null;
42
-
43
37
  /** @private {?number} */
44
38
  this.audioPid_ = null;
45
39
 
@@ -56,15 +50,27 @@ shaka.util.TsParser = class {
56
50
  this.id3Data_ = [];
57
51
  }
58
52
 
53
+ /**
54
+ * Clear previous data
55
+ *
56
+ * @export
57
+ */
58
+ clearData() {
59
+ this.videoData_ = [];
60
+ this.audioData_ = [];
61
+ this.id3Data_ = [];
62
+ }
63
+
59
64
  /**
60
65
  * Parse the given data
61
66
  *
62
67
  * @param {Uint8Array} data
63
68
  * @return {!shaka.util.TsParser}
69
+ * @export
64
70
  */
65
71
  parse(data) {
66
- const timescale = shaka.util.TsParser.Timescale_;
67
72
  const packetLength = shaka.util.TsParser.PacketLength_;
73
+ const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;
68
74
 
69
75
  // A TS fragment should contain at least 3 TS packets, a PAT, a PMT, and
70
76
  // one PID.
@@ -79,7 +85,7 @@ shaka.util.TsParser = class {
79
85
 
80
86
  // loop through TS packets
81
87
  for (let start = syncOffset; start < length; start += packetLength) {
82
- if (data[start] === 0x47) {
88
+ if (data[start] == 0x47) {
83
89
  const payloadUnitStartIndicator = !!(data[start + 1] & 0x40);
84
90
  // pid is a 13-bit field starting at the last 5 bits of TS[1]
85
91
  const pid = ((data[start + 1] & 0x1f) << 8) + data[start + 2];
@@ -91,7 +97,7 @@ shaka.util.TsParser = class {
91
97
  if (adaptationFieldControl > 1) {
92
98
  offset = start + 5 + data[start + 4];
93
99
  // continue if there is only adaptation field
94
- if (offset === start + packetLength) {
100
+ if (offset == start + packetLength) {
95
101
  continue;
96
102
  }
97
103
  } else {
@@ -113,7 +119,7 @@ shaka.util.TsParser = class {
113
119
  offset += data[offset] + 1;
114
120
  }
115
121
 
116
- const parsedPIDs = this.parsePMT(data, offset);
122
+ const parsedPIDs = this.parsePMT_(data, offset);
117
123
 
118
124
  // only update track id if track PID found while parsing PMT
119
125
  // this is to avoid resetting the PID to -1 in case
@@ -146,29 +152,43 @@ shaka.util.TsParser = class {
146
152
  }
147
153
  case this.videoPid_: {
148
154
  const videoData = data.subarray(offset, start + packetLength);
149
- if (this.videoStartTime_ == null) {
150
- const pes = this.parsePES(videoData);
151
- if (pes && pes.pts != null) {
152
- this.videoStartTime_ = pes.pts / timescale;
155
+ if (payloadUnitStartIndicator) {
156
+ this.videoData_.push(videoData);
157
+ } else if (this.videoData_.length) {
158
+ const prevVideoData = this.videoData_[this.videoData_.length - 1];
159
+ if (prevVideoData) {
160
+ this.videoData_[this.videoData_.length - 1] =
161
+ Uint8ArrayUtils.concat(prevVideoData, videoData);
153
162
  }
154
163
  }
155
- this.videoData_.push(videoData);
156
164
  break;
157
165
  }
158
166
  case this.audioPid_: {
159
167
  const audioData = data.subarray(offset, start + packetLength);
160
- if (this.audioStartTime_ == null) {
161
- const pes = this.parsePES(audioData);
162
- if (pes && pes.pts != null) {
163
- this.audioStartTime_ = pes.pts / timescale;
168
+ if (payloadUnitStartIndicator) {
169
+ this.audioData_.push(audioData);
170
+ } else if (this.audioData_.length) {
171
+ const prevAudioData = this.audioData_[this.audioData_.length - 1];
172
+ if (prevAudioData) {
173
+ this.audioData_[this.audioData_.length - 1] =
174
+ Uint8ArrayUtils.concat(prevAudioData, audioData);
164
175
  }
165
176
  }
166
- this.audioData_.push(audioData);
167
177
  break;
168
178
  }
169
- case this.id3Pid_:
170
- this.id3Data_.push(data.subarray(offset, start + packetLength));
179
+ case this.id3Pid_: {
180
+ const id3Data = data.subarray(offset, start + packetLength);
181
+ if (payloadUnitStartIndicator) {
182
+ this.id3Data_.push(id3Data);
183
+ } else if (this.id3Data_.length) {
184
+ const prevId3Data = this.id3Data_[this.id3Data_.length - 1];
185
+ if (prevId3Data) {
186
+ this.id3Data_[this.id3Data_.length - 1] =
187
+ Uint8ArrayUtils.concat(prevId3Data, id3Data);
188
+ }
189
+ }
171
190
  break;
191
+ }
172
192
  default:
173
193
  unknownPIDs = true;
174
194
  break;
@@ -199,8 +219,9 @@ shaka.util.TsParser = class {
199
219
  * @param {Uint8Array} data
200
220
  * @param {number} offset
201
221
  * @return {!shaka.util.TsParser.PMT}
222
+ * @private
202
223
  */
203
- parsePMT(data, offset) {
224
+ parsePMT_(data, offset) {
204
225
  const result = {
205
226
  audio: -1,
206
227
  video: -1,
@@ -218,20 +239,49 @@ shaka.util.TsParser = class {
218
239
  offset += 12 + programInfoLength;
219
240
  while (offset < tableEnd) {
220
241
  const pid = ((data[offset + 1] & 0x1f) << 8) | data[offset + 2];
242
+ const esInfoLength = ((data[offset + 3] & 0x0f) << 8) | data[offset + 4];
221
243
  switch (data[offset]) {
244
+ case 0x06:
245
+ // stream_type 6 can mean a lot of different things in case of DVB.
246
+ // We need to look at the descriptors. Right now, we're only
247
+ // interested in AC-3 and EC-3 audio, so we do the descriptor parsing
248
+ // only when we don't have an audio PID yet.
249
+ if (result.audio == -1 && esInfoLength > 0) {
250
+ let parsePos = offset + 5;
251
+ let remaining = esInfoLength;
252
+ while (remaining > 2) {
253
+ const descriptorId = data[parsePos];
254
+ switch (descriptorId) {
255
+ // DVB Descriptor for AC-3
256
+ case 0x6a:
257
+ result.audio = pid;
258
+ result.audioCodec = 'ac3';
259
+ break;
260
+ // DVB Descriptor for EC-3
261
+ case 0x7a:
262
+ result.audio = pid;
263
+ result.audioCodec = 'ec3';
264
+ break;
265
+ }
266
+ const descriptorLen = data[parsePos + 1] + 2;
267
+ parsePos += descriptorLen;
268
+ remaining -= descriptorLen;
269
+ }
270
+ }
271
+ break;
222
272
  // SAMPLE-AES AAC
223
273
  case 0xcf:
224
274
  break;
225
275
  // ISO/IEC 13818-7 ADTS AAC (MPEG-2 lower bit-rate audio)
226
276
  case 0x0f:
227
- if (result.audio === -1) {
277
+ if (result.audio == -1) {
228
278
  result.audio = pid;
229
279
  result.audioCodec = 'aac';
230
280
  }
231
281
  break;
232
282
  // Packetized metadata (ID3)
233
283
  case 0x15:
234
- if (result.id3 === -1) {
284
+ if (result.id3 == -1) {
235
285
  result.id3 = pid;
236
286
  }
237
287
  break;
@@ -240,7 +290,7 @@ shaka.util.TsParser = class {
240
290
  break;
241
291
  // ITU-T Rec. H.264 and ISO/IEC 14496-10 (lower bit-rate video)
242
292
  case 0x1b:
243
- if (result.video === -1) {
293
+ if (result.video == -1) {
244
294
  result.video = pid;
245
295
  result.videoCodec = 'avc';
246
296
  }
@@ -249,25 +299,40 @@ shaka.util.TsParser = class {
249
299
  // or ISO/IEC 13818-3 (MPEG-2 halved sample rate audio)
250
300
  case 0x03:
251
301
  case 0x04:
252
- if (result.audio === -1) {
302
+ if (result.audio == -1) {
253
303
  result.audio = pid;
254
304
  result.audioCodec = 'mp3';
255
305
  }
256
306
  break;
257
307
  // HEVC
258
308
  case 0x24:
259
- if (result.video === -1) {
309
+ if (result.video == -1) {
260
310
  result.video = pid;
261
311
  result.videoCodec = 'hvc';
262
312
  }
263
313
  break;
314
+ // AC-3
315
+ case 0x81:
316
+ if (result.audio == -1) {
317
+ result.audio = pid;
318
+ result.audioCodec = 'ac3';
319
+ }
320
+ break;
321
+ // EC-3
322
+ case 0x84:
323
+ case 0x87:
324
+ if (result.audio == -1) {
325
+ result.audio = pid;
326
+ result.audioCodec = 'ec3';
327
+ }
328
+ break;
264
329
  default:
265
330
  // shaka.log.warning('Unknown stream type:', data[offset]);
266
331
  break;
267
332
  }
268
333
  // move to the next table entry
269
334
  // skip past the elementary stream descriptors, if present
270
- offset += (((data[offset + 3] & 0x0f) << 8) | data[offset + 4]) + 5;
335
+ offset += esInfoLength + 5;
271
336
  }
272
337
  return result;
273
338
  }
@@ -276,9 +341,10 @@ shaka.util.TsParser = class {
276
341
  * Parse PES
277
342
  *
278
343
  * @param {Uint8Array} data
279
- * @return {?shaka.util.TsParser.PES}
344
+ * @return {?shaka.extern.MPEG_PES}
345
+ * @private
280
346
  */
281
- parsePES(data) {
347
+ parsePES_(data) {
282
348
  const startPrefix = (data[0] << 16) | (data[1] << 8) | data[2];
283
349
  // In certain live streams, the start of a TS fragment has ts packets
284
350
  // that are frame data that is continuing from the previous fragment. This
@@ -286,11 +352,11 @@ shaka.util.TsParser = class {
286
352
  if (startPrefix !== 1) {
287
353
  return null;
288
354
  }
289
- /** @type {shaka.util.TsParser.PES} */
355
+ /** @type {shaka.extern.MPEG_PES} */
290
356
  const pes = {
291
357
  data: new Uint8Array(0),
292
358
  // get the packet length, this will be 0 for video
293
- packetLength: 6 + ((data[4] << 8) | data[5]),
359
+ packetLength: ((data[4] << 8) | data[5]),
294
360
  pts: null,
295
361
  dts: null,
296
362
  };
@@ -337,51 +403,217 @@ shaka.util.TsParser = class {
337
403
  return pes;
338
404
  }
339
405
 
406
+ /**
407
+ * Parse AVC Nalus
408
+ *
409
+ * The code is based on hls.js
410
+ * Credit to https://github.com/video-dev/hls.js/blob/master/src/demux/tsdemuxer.ts
411
+ *
412
+ * @param {shaka.extern.MPEG_PES} pes
413
+ * @param {?shaka.extern.MPEG_PES=} nextPes
414
+ * @return {!Array.<shaka.extern.VideoNalu>}
415
+ * @export
416
+ */
417
+ parseAvcNalus(pes, nextPes) {
418
+ const timescale = shaka.util.TsParser.Timescale;
419
+ const time = pes.pts ? pes.pts / timescale : null;
420
+ let data = pes.data;
421
+ let len = data.byteLength;
422
+
423
+ // A NALU does not contain is its size.
424
+ // The Annex B specification solves this by requiring ‘Start Codes’ to
425
+ // precede each NALU. A start code is 2 or 3 0x00 bytes followed with a
426
+ // 0x01 byte. e.g. 0x000001 or 0x00000001.
427
+ // More info in: https://stackoverflow.com/questions/24884827/possible-locations-for-sequence-picture-parameter-sets-for-h-264-stream/24890903#24890903
428
+ let numZeros = 0;
429
+
430
+ /** @type {!Array.<shaka.extern.VideoNalu>} */
431
+ const nalus = [];
432
+
433
+ // Start position includes the first byte where we read the type.
434
+ // The data we extract begins at the next byte.
435
+ let lastNaluStart = -1;
436
+ // Extracted from the first byte.
437
+ let lastNaluType = 0;
438
+
439
+ let tryToFinishLastNalu = false;
440
+
441
+ /** @type {?shaka.extern.VideoNalu} */
442
+ let infoOfLastNalu;
443
+
444
+ for (let i = 0; i < len; ++i) {
445
+ const value = data[i];
446
+ if (!value) {
447
+ numZeros++;
448
+ } else if (numZeros >= 2 && value == 1 && tryToFinishLastNalu) {
449
+ // If we are scanning the next PES, we need append the data to the
450
+ // previous Nalu and don't scan for more nalus.
451
+ const startCodeSize = numZeros > 3 ? 3 : numZeros;
452
+ const lastByteToKeep = i - startCodeSize;
453
+ infoOfLastNalu.data = shaka.util.Uint8ArrayUtils.concat(
454
+ infoOfLastNalu.data, data.subarray(0, lastByteToKeep));
455
+ infoOfLastNalu.fullData = shaka.util.Uint8ArrayUtils.concat(
456
+ infoOfLastNalu.fullData, data.subarray(0, lastByteToKeep));
457
+ break;
458
+ } else if (numZeros >= 2 && value == 1) {
459
+ // We just read a start code. Consume the NALU we passed, if any.
460
+ if (lastNaluStart >= 0) {
461
+ // Because the start position includes the type, skip the first byte.
462
+ const firstByteToKeep = lastNaluStart + 1;
463
+
464
+ // Compute the last byte to keep. The start code is at most 3 zeros.
465
+ // Any earlier zeros are not part of the start code.
466
+ const startCodeSize = (numZeros > 3 ? 3 : numZeros) + 1;
467
+ const lastByteToKeep = i - startCodeSize;
468
+
469
+ /** @type {shaka.extern.VideoNalu} */
470
+ const nalu = {
471
+ // subarray's end position is exclusive, so add one.
472
+ data: data.subarray(firstByteToKeep, lastByteToKeep + 1),
473
+ fullData: data.subarray(lastNaluStart, lastByteToKeep + 1),
474
+ type: lastNaluType,
475
+ time: time,
476
+ };
477
+ nalus.push(nalu);
478
+ }
479
+
480
+ // We just read a start code, so there should be another byte here, at
481
+ // least, for the NALU type. Check just in case.
482
+ if (i >= len - 1) {
483
+ shaka.log.warning('Malformed TS, incomplete NALU, ignoring.');
484
+ return nalus;
485
+ }
486
+
487
+ // Advance and read the type of the next NALU.
488
+ i++;
489
+ lastNaluStart = i;
490
+ lastNaluType = data[i] & 0x1f;
491
+ numZeros = 0;
492
+ } else {
493
+ numZeros = 0;
494
+ }
495
+ // If we have gone through all the data from the PES and we have an
496
+ // unfinished Nalu, we will try to use the next PES to complete the
497
+ // unfinished Nalu.
498
+ if (i >= (len - 1) && lastNaluStart >= 0 && numZeros >= 0) {
499
+ if (tryToFinishLastNalu) {
500
+ infoOfLastNalu.data = shaka.util.Uint8ArrayUtils.concat(
501
+ infoOfLastNalu.data, data);
502
+ infoOfLastNalu.fullData = shaka.util.Uint8ArrayUtils.concat(
503
+ infoOfLastNalu.fullData, data);
504
+ } else {
505
+ tryToFinishLastNalu = true;
506
+ // The rest of the buffer was a NALU.
507
+ // Because the start position includes the type, skip the first byte.
508
+ const firstByteToKeep = lastNaluStart + 1;
509
+ infoOfLastNalu = {
510
+ data: data.subarray(firstByteToKeep, len),
511
+ fullData: data.subarray(lastNaluStart, len),
512
+ type: lastNaluType,
513
+ time: time,
514
+ };
515
+ if (nextPes && pes.packetLength == 0) {
516
+ data = nextPes.data;
517
+ len = data.byteLength;
518
+ i = -1;
519
+ }
520
+ }
521
+ }
522
+ }
523
+
524
+ if (infoOfLastNalu) {
525
+ nalus.push(infoOfLastNalu);
526
+ }
527
+ return nalus;
528
+ }
529
+
340
530
  /**
341
531
  * Return the ID3 metadata
342
532
  *
343
533
  * @return {!Array.<shaka.extern.ID3Metadata>}
534
+ * @export
344
535
  */
345
536
  getMetadata() {
346
- const timescale = shaka.util.TsParser.Timescale_;
347
- const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;
537
+ const timescale = shaka.util.TsParser.Timescale;
348
538
  const metadata = [];
349
- let prevId3Data = new Uint8Array(0);
350
- // parsePES() only works if the data begins on a PES boundary.
351
- // Try the last data blob first, and if it doesn't begin on a
352
- // PES boundary, prepend the previous blob and try again.
353
- // This way, a successful parse will always begin and end on
354
- // the correct boundary, and no data will be skipped.
355
- for (let i = this.id3Data_.length - 1; i >= 0; i--) {
356
- const data = this.id3Data_[i];
357
- goog.asserts.assert(data, 'We should have a data');
358
- const id3Data = Uint8ArrayUtils.concat(data, prevId3Data);
359
- const pes = this.parsePES(id3Data);
539
+ for (const id3Data of this.id3Data_) {
540
+ const pes = this.parsePES_(id3Data);
360
541
  if (pes) {
361
- metadata.unshift({
542
+ metadata.push({
362
543
  cueTime: pes.pts ? pes.pts / timescale : null,
363
544
  data: pes.data,
364
545
  frames: shaka.util.Id3Utils.getID3Frames(pes.data),
365
546
  dts: pes.dts,
366
547
  pts: pes.pts,
367
548
  });
368
- prevId3Data = new Uint8Array(0);
369
- } else {
370
- prevId3Data = id3Data;
371
549
  }
372
550
  }
373
551
  return metadata;
374
552
  }
375
553
 
554
+ /**
555
+ * Return the audio data
556
+ *
557
+ * @return {!Array.<shaka.extern.MPEG_PES>}
558
+ * @export
559
+ */
560
+ getAudioData() {
561
+ const audio = [];
562
+ for (const audioData of this.audioData_) {
563
+ const pes = this.parsePES_(audioData);
564
+ if (pes) {
565
+ audio.push(pes);
566
+ }
567
+ }
568
+ return audio;
569
+ }
570
+
571
+ /**
572
+ * Return the audio data
573
+ *
574
+ * @return {!Array.<shaka.extern.MPEG_PES>}
575
+ * @export
576
+ */
577
+ getVideoData() {
578
+ const video = [];
579
+ for (const videoData of this.videoData_) {
580
+ const pes = this.parsePES_(videoData);
581
+ if (pes) {
582
+ video.push(pes);
583
+ }
584
+ }
585
+ return video;
586
+ }
587
+
376
588
  /**
377
589
  * Return the start time for the audio and video
378
590
  *
379
591
  * @return {{audio: ?number, video: ?number}}
592
+ * @export
380
593
  */
381
594
  getStartTime() {
595
+ const timescale = shaka.util.TsParser.Timescale;
596
+ let audioStartTime = null;
597
+ for (const pes of this.getAudioData()) {
598
+ if (pes && pes.pts != null) {
599
+ const startTime = Math.min(pes.dts, pes.pts) / timescale;
600
+ if (audioStartTime == null || audioStartTime > startTime) {
601
+ audioStartTime = startTime;
602
+ }
603
+ }
604
+ }
605
+ let videoStartTime = null;
606
+ for (const pes of this.getVideoData()) {
607
+ if (pes && pes.pts != null) {
608
+ const startTime = Math.min(pes.dts, pes.pts) / timescale;
609
+ if (videoStartTime == null || videoStartTime > startTime) {
610
+ videoStartTime = startTime;
611
+ }
612
+ }
613
+ }
382
614
  return {
383
- audio: this.audioStartTime_,
384
- video: this.videoStartTime_,
615
+ audio: audioStartTime,
616
+ video: videoStartTime,
385
617
  };
386
618
  }
387
619
 
@@ -389,6 +621,7 @@ shaka.util.TsParser = class {
389
621
  * Return the audio and video codecs
390
622
  *
391
623
  * @return {{audio: ?string, video: ?string}}
624
+ * @export
392
625
  */
393
626
  getCodecs() {
394
627
  return {
@@ -397,11 +630,159 @@ shaka.util.TsParser = class {
397
630
  };
398
631
  }
399
632
 
633
+ /**
634
+ * Return the video data
635
+ *
636
+ * @return {!Array.<shaka.extern.VideoNalu>}
637
+ * @export
638
+ */
639
+ getVideoNalus() {
640
+ const nalus = [];
641
+ if (this.videoCodec_ != 'avc') {
642
+ return nalus;
643
+ }
644
+ const videoData = this.getVideoData();
645
+ for (let i = 0; i < videoData.length; i++) {
646
+ const pes = videoData[i];
647
+ let nextPes;
648
+ if (i + 1 < videoData.length) {
649
+ nextPes = videoData[i + 1];
650
+ }
651
+ nalus.push(...this.parseAvcNalus(pes, nextPes));
652
+ }
653
+ return nalus;
654
+ }
655
+
656
+ /**
657
+ * Return the video resolution
658
+ *
659
+ * @return {{height: ?string, width: ?string}}
660
+ * @export
661
+ */
662
+ getVideoResolution() {
663
+ const TsParser = shaka.util.TsParser;
664
+ const resolution = {
665
+ height: null,
666
+ width: null,
667
+ };
668
+ const videoNalus = this.getVideoNalus();
669
+ if (!videoNalus.length) {
670
+ return resolution;
671
+ }
672
+ const spsNalu = videoNalus.find((nalu) => {
673
+ return nalu.type == TsParser.H264_NALU_TYPE_SPS_;
674
+ });
675
+ if (!spsNalu) {
676
+ return resolution;
677
+ }
678
+
679
+ const expGolombDecoder = new shaka.util.ExpGolomb(spsNalu.data);
680
+ // profile_idc
681
+ const profileIdc = expGolombDecoder.readUnsignedByte();
682
+ // constraint_set[0-5]_flag
683
+ expGolombDecoder.readUnsignedByte();
684
+ // level_idc u(8)
685
+ expGolombDecoder.readUnsignedByte();
686
+ // seq_parameter_set_id
687
+ expGolombDecoder.skipExpGolomb();
688
+
689
+ // some profiles have more optional data we don't need
690
+ if (TsParser.PROFILES_WITH_OPTIONAL_SPS_DATA_.includes(profileIdc)) {
691
+ const chromaFormatIdc = expGolombDecoder.readUnsignedExpGolomb();
692
+ if (chromaFormatIdc === 3) {
693
+ // separate_colour_plane_flag
694
+ expGolombDecoder.skipBits(1);
695
+ }
696
+ // bit_depth_luma_minus8
697
+ expGolombDecoder.skipExpGolomb();
698
+ // bit_depth_chroma_minus8
699
+ expGolombDecoder.skipExpGolomb();
700
+ // qpprime_y_zero_transform_bypass_flag
701
+ expGolombDecoder.skipBits(1);
702
+ // seq_scaling_matrix_present_flag
703
+ if (expGolombDecoder.readBoolean()) {
704
+ const scalingListCount = (chromaFormatIdc !== 3) ? 8 : 12;
705
+ for (let i = 0; i < scalingListCount; i++) {
706
+ // seq_scaling_list_present_flag[ i ]
707
+ if (expGolombDecoder.readBoolean()) {
708
+ if (i < 6) {
709
+ expGolombDecoder.skipScalingList(16);
710
+ } else {
711
+ expGolombDecoder.skipScalingList(64);
712
+ }
713
+ }
714
+ }
715
+ }
716
+ }
717
+
718
+ // log2_max_frame_num_minus4
719
+ expGolombDecoder.skipExpGolomb();
720
+ const picOrderCntType = expGolombDecoder.readUnsignedExpGolomb();
721
+
722
+ if (picOrderCntType === 0) {
723
+ // log2_max_pic_order_cnt_lsb_minus4
724
+ expGolombDecoder.readUnsignedExpGolomb();
725
+ } else if (picOrderCntType === 1) {
726
+ // delta_pic_order_always_zero_flag
727
+ expGolombDecoder.skipBits(1);
728
+ // offset_for_non_ref_pic
729
+ expGolombDecoder.skipExpGolomb();
730
+ // offset_for_top_to_bottom_field
731
+ expGolombDecoder.skipExpGolomb();
732
+ const numRefFramesInPicOrderCntCycle =
733
+ expGolombDecoder.readUnsignedExpGolomb();
734
+ for (let i = 0; i < numRefFramesInPicOrderCntCycle; i++) {
735
+ // offset_for_ref_frame[ i ]
736
+ expGolombDecoder.skipExpGolomb();
737
+ }
738
+ }
739
+
740
+ // max_num_ref_frames
741
+ expGolombDecoder.skipExpGolomb();
742
+ // gaps_in_frame_num_value_allowed_flag
743
+ expGolombDecoder.skipBits(1);
744
+
745
+ const picWidthInMbsMinus1 =
746
+ expGolombDecoder.readUnsignedExpGolomb();
747
+ const picHeightInMapUnitsMinus1 =
748
+ expGolombDecoder.readUnsignedExpGolomb();
749
+
750
+ const frameMbsOnlyFlag = expGolombDecoder.readBits(1);
751
+ if (frameMbsOnlyFlag === 0) {
752
+ // mb_adaptive_frame_field_flag
753
+ expGolombDecoder.skipBits(1);
754
+ }
755
+ // direct_8x8_inference_flag
756
+ expGolombDecoder.skipBits(1);
757
+
758
+ let frameCropLeftOffset = 0;
759
+ let frameCropRightOffset = 0;
760
+ let frameCropTopOffset = 0;
761
+ let frameCropBottomOffset = 0;
762
+
763
+ // frame_cropping_flag
764
+ if (expGolombDecoder.readBoolean()) {
765
+ frameCropLeftOffset = expGolombDecoder.readUnsignedExpGolomb();
766
+ frameCropRightOffset = expGolombDecoder.readUnsignedExpGolomb();
767
+ frameCropTopOffset = expGolombDecoder.readUnsignedExpGolomb();
768
+ frameCropBottomOffset = expGolombDecoder.readUnsignedExpGolomb();
769
+ }
770
+
771
+ resolution.height = String(((2 - frameMbsOnlyFlag) *
772
+ (picHeightInMapUnitsMinus1 + 1) * 16) - (frameCropTopOffset * 2) -
773
+ (frameCropBottomOffset * 2));
774
+ resolution.width = String(((picWidthInMbsMinus1 + 1) * 16) -
775
+ frameCropLeftOffset * 2 - frameCropRightOffset * 2);
776
+
777
+ return resolution;
778
+ }
779
+
400
780
  /**
401
781
  * Check if the passed data corresponds to an MPEG2-TS
402
782
  *
403
783
  * @param {Uint8Array} data
404
784
  * @return {boolean}
785
+ * @export
405
786
  */
406
787
  static probe(data) {
407
788
  const syncOffset = shaka.util.TsParser.syncOffset(data);
@@ -421,6 +802,7 @@ shaka.util.TsParser = class {
421
802
  *
422
803
  * @param {Uint8Array} data
423
804
  * @return {number}
805
+ * @export
424
806
  */
425
807
  static syncOffset(data) {
426
808
  const packetLength = shaka.util.TsParser.PacketLength_;
@@ -430,9 +812,9 @@ shaka.util.TsParser = class {
430
812
  while (i < scanwindow) {
431
813
  // a TS fragment should contain at least 3 TS packets, a PAT, a PMT, and
432
814
  // one PID, each starting with 0x47
433
- if (data[i] === 0x47 &&
434
- data[i + packetLength] === 0x47 &&
435
- data[i + 2 * packetLength] === 0x47) {
815
+ if (data[i] == 0x47 &&
816
+ data[i + packetLength] == 0x47 &&
817
+ data[i + 2 * packetLength] == 0x47) {
436
818
  return i;
437
819
  } else {
438
820
  i++;
@@ -443,6 +825,13 @@ shaka.util.TsParser = class {
443
825
  };
444
826
 
445
827
 
828
+ /**
829
+ * @const {number}
830
+ * @export
831
+ */
832
+ shaka.util.TsParser.Timescale = 90000;
833
+
834
+
446
835
  /**
447
836
  * @const {number}
448
837
  * @private
@@ -451,10 +840,24 @@ shaka.util.TsParser.PacketLength_ = 188;
451
840
 
452
841
 
453
842
  /**
843
+ * NALU type for Sequence Parameter Set (SPS) for H.264.
454
844
  * @const {number}
455
845
  * @private
456
846
  */
457
- shaka.util.TsParser.Timescale_ = 90000;
847
+ shaka.util.TsParser.H264_NALU_TYPE_SPS_ = 0x07;
848
+
849
+
850
+ /**
851
+ * Values of profile_idc that indicate additional fields are included in the
852
+ * SPS.
853
+ * see Recommendation ITU-T H.264 (4/2013)
854
+ * 7.3.2.1.1 Sequence parameter set data syntax
855
+ *
856
+ * @const {!Array.<number>}
857
+ * @private
858
+ */
859
+ shaka.util.TsParser.PROFILES_WITH_OPTIONAL_SPS_DATA_ =
860
+ [100, 110, 122, 244, 44, 83, 86, 118, 128, 138, 139, 134];
458
861
 
459
862
 
460
863
  /**
@@ -480,20 +883,3 @@ shaka.util.TsParser.Timescale_ = 90000;
480
883
  */
481
884
  shaka.util.TsParser.PMT;
482
885
 
483
-
484
- /**
485
- * @typedef {{
486
- * data: Uint8Array,
487
- * packetLength: number,
488
- * pts: ?number,
489
- * dts: ?number
490
- * }}
491
- *
492
- * @summary PES.
493
- * @property {Uint8Array} data
494
- * @property {number} packetLength
495
- * @property {?number} pts
496
- * @property {?number} dts
497
- */
498
- shaka.util.TsParser.PES;
499
-