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
@@ -93,7 +93,7 @@ shaka.transmuxer.Mp3Transmuxer = class {
93
93
  * @override
94
94
  * @export
95
95
  */
96
- getOrginalMimeType() {
96
+ getOriginalMimeType() {
97
97
  return this.originalMimeType_;
98
98
  }
99
99
 
@@ -119,7 +119,7 @@ shaka.transmuxer.MpegTsTransmuxer = class {
119
119
  * @override
120
120
  * @export
121
121
  */
122
- getOrginalMimeType() {
122
+ getOriginalMimeType() {
123
123
  return this.originalMimeType_;
124
124
  }
125
125
 
@@ -128,8 +128,9 @@ shaka.transmuxer.MpegTsTransmuxer = class {
128
128
  * @override
129
129
  * @export
130
130
  */
131
- transmux(data) {
131
+ transmux(data, stream, reference, duration, contentType) {
132
132
  const MpegAudio = shaka.transmuxer.MpegAudio;
133
+ const ContentType = shaka.util.ManifestParserUtils.ContentType;
133
134
  const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;
134
135
 
135
136
  if (!this.tsParser_) {
@@ -142,7 +143,7 @@ shaka.transmuxer.MpegTsTransmuxer = class {
142
143
 
143
144
  const tsParser = this.tsParser_.parse(uint8ArrayData);
144
145
  const codecs = tsParser.getCodecs();
145
- if (codecs.audio != 'mp3' || codecs.video) {
146
+ if (codecs.audio != 'mp3' || contentType != ContentType.AUDIO) {
146
147
  return Promise.reject(new shaka.util.Error(
147
148
  shaka.util.Error.Severity.CRITICAL,
148
149
  shaka.util.Error.Category.MEDIA,
@@ -208,7 +208,7 @@ shaka.transmuxer.MssTransmuxer = class {
208
208
  * @override
209
209
  * @export
210
210
  */
211
- getOrginalMimeType() {
211
+ getOriginalMimeType() {
212
212
  return this.originalMimeType_;
213
213
  }
214
214
 
@@ -11,6 +11,7 @@ goog.require('shaka.transmuxer.Ac3');
11
11
  goog.require('shaka.transmuxer.ADTS');
12
12
  goog.require('shaka.transmuxer.Ec3');
13
13
  goog.require('shaka.transmuxer.H264');
14
+ goog.require('shaka.transmuxer.H265');
14
15
  goog.require('shaka.transmuxer.MpegAudio');
15
16
  goog.require('shaka.transmuxer.TransmuxerEngine');
16
17
  goog.require('shaka.util.BufferUtils');
@@ -21,6 +22,8 @@ goog.require('shaka.util.Mp4Generator');
21
22
  goog.require('shaka.util.TsParser');
22
23
  goog.require('shaka.util.Uint8ArrayUtils');
23
24
 
25
+ goog.requireType('shaka.media.SegmentReference');
26
+
24
27
 
25
28
  /**
26
29
  * @implements {shaka.extern.Transmuxer}
@@ -72,7 +75,11 @@ shaka.transmuxer.TsTransmuxer = class {
72
75
  const ContentType = shaka.util.ManifestParserUtils.ContentType;
73
76
  const MimeUtils = shaka.util.MimeUtils;
74
77
 
75
- const codecs = MimeUtils.getCodecs(mimeType);
78
+ let convertedMimeType = mimeType;
79
+ if (contentType) {
80
+ convertedMimeType = this.convertCodecs(contentType, mimeType);
81
+ }
82
+ const codecs = MimeUtils.getCodecs(convertedMimeType);
76
83
  const allCodecs = MimeUtils.splitCodecs(codecs);
77
84
 
78
85
  const audioCodec = shaka.util.ManifestParserUtils.guessCodecsSafe(
@@ -80,11 +87,6 @@ shaka.transmuxer.TsTransmuxer = class {
80
87
  const videoCodec = shaka.util.ManifestParserUtils.guessCodecsSafe(
81
88
  ContentType.VIDEO, allCodecs);
82
89
 
83
- // We don't support muxed content yet.
84
- if (audioCodec && videoCodec) {
85
- return false;
86
- }
87
-
88
90
  const TsTransmuxer = shaka.transmuxer.TsTransmuxer;
89
91
 
90
92
  if (audioCodec) {
@@ -136,7 +138,8 @@ shaka.transmuxer.TsTransmuxer = class {
136
138
  // MediaSource.isTypeSupported('audio/mp4; codecs="mp4a.40.34"') -> false
137
139
  // MediaSource.isTypeSupported('audio/mp4; codecs="mp3"') -> true
138
140
  const codecs = shaka.util.MimeUtils.getCodecs(mimeType)
139
- .replace('mp4a.40.34', 'mp3');
141
+ .replace('mp4a.40.34', 'mp3').split(',')
142
+ .map(this.getCorrectVideoCodecs_).join(',');
140
143
  if (contentType == ContentType.AUDIO) {
141
144
  return `audio/mp4; codecs="${codecs}"`;
142
145
  }
@@ -146,11 +149,34 @@ shaka.transmuxer.TsTransmuxer = class {
146
149
  }
147
150
 
148
151
 
152
+ /**
153
+ * @param {string} codec
154
+ * @return {string}
155
+ * @private
156
+ */
157
+ getCorrectVideoCodecs_(codec) {
158
+ if (codec.includes('avc1')) {
159
+ // Convert avc1 codec string from RFC-4281 to RFC-6381 for
160
+ // MediaSource.isTypeSupported
161
+ // Example, convert avc1.66.30 to avc1.42001e (0x42 == 66 and 0x1e == 30)
162
+ const avcdata = codec.split('.');
163
+ if (avcdata.length == 3) {
164
+ let result = avcdata.shift() + '.';
165
+ result += parseInt(avcdata.shift(), 10).toString(16);
166
+ result +=
167
+ ('000' + parseInt(avcdata.shift(), 10).toString(16)).slice(-4);
168
+ return result;
169
+ }
170
+ }
171
+ return codec;
172
+ }
173
+
174
+
149
175
  /**
150
176
  * @override
151
177
  * @export
152
178
  */
153
- getOrginalMimeType() {
179
+ getOriginalMimeType() {
154
180
  return this.originalMimeType_;
155
181
  }
156
182
 
@@ -179,7 +205,11 @@ shaka.transmuxer.TsTransmuxer = class {
179
205
  switch (codecs.video) {
180
206
  case 'avc':
181
207
  streamInfo =
182
- this.getAvcStreamInfo_(tsParser, stream, duration);
208
+ this.getAvcStreamInfo_(tsParser, stream, duration, reference);
209
+ break;
210
+ case 'hvc':
211
+ streamInfo =
212
+ this.getHvcStreamInfo_(tsParser, stream, duration, reference);
183
213
  break;
184
214
  }
185
215
  if (streamInfo) {
@@ -191,7 +221,7 @@ shaka.transmuxer.TsTransmuxer = class {
191
221
  switch (codecs.audio) {
192
222
  case 'aac':
193
223
  streamInfo =
194
- this.getAacStreamInfo_(tsParser, stream, duration);
224
+ this.getAacStreamInfo_(tsParser, stream, duration, reference);
195
225
  break;
196
226
  case 'ac3':
197
227
  streamInfo =
@@ -242,10 +272,11 @@ shaka.transmuxer.TsTransmuxer = class {
242
272
  * @param {shaka.util.TsParser} tsParser
243
273
  * @param {shaka.extern.Stream} stream
244
274
  * @param {number} duration
275
+ * @param {?shaka.media.SegmentReference} reference
245
276
  * @return {shaka.util.Mp4Generator.StreamInfo}
246
277
  * @private
247
278
  */
248
- getAacStreamInfo_(tsParser, stream, duration) {
279
+ getAacStreamInfo_(tsParser, stream, duration, reference) {
249
280
  const ADTS = shaka.transmuxer.ADTS;
250
281
  const timescale = shaka.util.TsParser.Timescale;
251
282
 
@@ -306,10 +337,58 @@ shaka.transmuxer.TsTransmuxer = class {
306
337
  }
307
338
 
308
339
  if (!info || firstPts == null) {
309
- throw new shaka.util.Error(
310
- shaka.util.Error.Severity.CRITICAL,
311
- shaka.util.Error.Category.MEDIA,
312
- shaka.util.Error.Code.TRANSMUXING_FAILED);
340
+ if (!tsParser.getVideoData().length) {
341
+ throw new shaka.util.Error(
342
+ shaka.util.Error.Severity.CRITICAL,
343
+ shaka.util.Error.Category.MEDIA,
344
+ shaka.util.Error.Code.TRANSMUXING_FAILED);
345
+ }
346
+
347
+ firstPts = reference.startTime * timescale;
348
+
349
+ const allCodecs = shaka.util.MimeUtils.splitCodecs(stream.codecs);
350
+ const audioCodec = shaka.util.ManifestParserUtils.guessCodecsSafe(
351
+ shaka.util.ManifestParserUtils.ContentType.AUDIO, allCodecs);
352
+ if (!audioCodec || !stream.channelsCount || !stream.audioSamplingRate) {
353
+ throw new shaka.util.Error(
354
+ shaka.util.Error.Severity.CRITICAL,
355
+ shaka.util.Error.Category.MEDIA,
356
+ shaka.util.Error.Code.TRANSMUXING_FAILED);
357
+ }
358
+ info = {
359
+ sampleRate: stream.audioSamplingRate,
360
+ channelCount: stream.channelsCount,
361
+ codec: audioCodec,
362
+ };
363
+ const silenceFrame =
364
+ ADTS.getSilentFrame(audioCodec, stream.channelsCount);
365
+ if (!silenceFrame) {
366
+ throw new shaka.util.Error(
367
+ shaka.util.Error.Severity.CRITICAL,
368
+ shaka.util.Error.Category.MEDIA,
369
+ shaka.util.Error.Code.TRANSMUXING_FAILED);
370
+ }
371
+ const segmentDuration =
372
+ (reference.endTime - reference.startTime) * timescale;
373
+ const finalPTs = firstPts + segmentDuration;
374
+ let currentPts = firstPts;
375
+ while (currentPts < finalPTs) {
376
+ samples.push({
377
+ data: silenceFrame,
378
+ size: silenceFrame.byteLength,
379
+ duration: ADTS.AAC_SAMPLES_PER_FRAME,
380
+ cts: 0,
381
+ flags: {
382
+ isLeading: 0,
383
+ isDependedOn: 0,
384
+ hasRedundancy: 0,
385
+ degradPrio: 0,
386
+ dependsOn: 2,
387
+ isNonSync: 0,
388
+ },
389
+ });
390
+ currentPts += ADTS.AAC_SAMPLES_PER_FRAME / info.sampleRate * timescale;
391
+ }
313
392
  }
314
393
 
315
394
  /** @type {number} */
@@ -609,10 +688,11 @@ shaka.transmuxer.TsTransmuxer = class {
609
688
  * @param {shaka.util.TsParser} tsParser
610
689
  * @param {shaka.extern.Stream} stream
611
690
  * @param {number} duration
691
+ * @param {?shaka.media.SegmentReference} reference
612
692
  * @return {shaka.util.Mp4Generator.StreamInfo}
613
693
  * @private
614
694
  */
615
- getAvcStreamInfo_(tsParser, stream, duration) {
695
+ getAvcStreamInfo_(tsParser, stream, duration, reference) {
616
696
  const H264 = shaka.transmuxer.H264;
617
697
  const timescale = shaka.util.TsParser.Timescale;
618
698
 
@@ -626,11 +706,7 @@ shaka.transmuxer.TsTransmuxer = class {
626
706
  const videoData = tsParser.getVideoData();
627
707
  for (let i = 0; i < videoData.length; i++) {
628
708
  const pes = videoData[i];
629
- let nextPes;
630
- if (i + 1 < videoData.length) {
631
- nextPes = videoData[i + 1];
632
- }
633
- const dataNalus = tsParser.parseAvcNalus(pes, nextPes);
709
+ const dataNalus = pes.nalus;
634
710
  nalus = nalus.concat(dataNalus);
635
711
  const frame = H264.parseFrame(dataNalus);
636
712
  if (!frame) {
@@ -642,8 +718,10 @@ shaka.transmuxer.TsTransmuxer = class {
642
718
  let duration;
643
719
  if (i + 1 < videoData.length) {
644
720
  duration = (videoData[i + 1].dts || 0) - (pes.dts || 0);
645
- } else {
721
+ } else if (videoData.length > 1) {
646
722
  duration = (pes.dts || 0) - (videoData[i - 1].dts || 0);
723
+ } else {
724
+ duration = (reference.endTime - reference.startTime) * timescale;
647
725
  }
648
726
  samples.push({
649
727
  data: frame.data,
@@ -690,6 +768,92 @@ shaka.transmuxer.TsTransmuxer = class {
690
768
  stream: stream,
691
769
  };
692
770
  }
771
+
772
+
773
+ /**
774
+ * @param {shaka.util.TsParser} tsParser
775
+ * @param {shaka.extern.Stream} stream
776
+ * @param {number} duration
777
+ * @param {?shaka.media.SegmentReference} reference
778
+ * @return {shaka.util.Mp4Generator.StreamInfo}
779
+ * @private
780
+ */
781
+ getHvcStreamInfo_(tsParser, stream, duration, reference) {
782
+ const H265 = shaka.transmuxer.H265;
783
+ const timescale = shaka.util.TsParser.Timescale;
784
+
785
+ /** @type {!Array.<shaka.util.Mp4Generator.Mp4Sample>} */
786
+ const samples = [];
787
+
788
+ /** @type {?number} */
789
+ let baseMediaDecodeTime = null;
790
+
791
+ let nalus = [];
792
+ const videoData = tsParser.getVideoData();
793
+ for (let i = 0; i < videoData.length; i++) {
794
+ const pes = videoData[i];
795
+ const dataNalus = pes.nalus;
796
+ nalus = nalus.concat(dataNalus);
797
+ const frame = H265.parseFrame(dataNalus);
798
+ if (!frame) {
799
+ continue;
800
+ }
801
+ if (baseMediaDecodeTime == null && pes.dts != null) {
802
+ baseMediaDecodeTime = pes.dts;
803
+ }
804
+ let duration;
805
+ if (i + 1 < videoData.length) {
806
+ duration = (videoData[i + 1].dts || 0) - (pes.dts || 0);
807
+ } else if (videoData.length > 1) {
808
+ duration = (pes.dts || 0) - (videoData[i - 1].dts || 0);
809
+ } else {
810
+ duration = (reference.endTime - reference.startTime) * timescale;
811
+ }
812
+ samples.push({
813
+ data: frame.data,
814
+ size: frame.data.byteLength,
815
+ duration: duration,
816
+ cts: Math.round((pes.pts || 0) - (pes.dts || 0)),
817
+ flags: {
818
+ isLeading: 0,
819
+ isDependedOn: 0,
820
+ hasRedundancy: 0,
821
+ degradPrio: 0,
822
+ dependsOn: frame.isKeyframe ? 2 : 1,
823
+ isNonSync: frame.isKeyframe ? 0 : 1,
824
+ },
825
+ });
826
+ }
827
+
828
+ const info = H265.parseInfo(nalus);
829
+
830
+ if (!info || baseMediaDecodeTime == null) {
831
+ throw new shaka.util.Error(
832
+ shaka.util.Error.Severity.CRITICAL,
833
+ shaka.util.Error.Category.MEDIA,
834
+ shaka.util.Error.Code.TRANSMUXING_FAILED);
835
+ }
836
+ stream.height = info.height;
837
+ stream.width = info.width;
838
+
839
+ return {
840
+ id: stream.id,
841
+ type: shaka.util.ManifestParserUtils.ContentType.VIDEO,
842
+ codecs: 'hvc1',
843
+ encrypted: stream.encrypted && stream.drmInfos.length > 0,
844
+ timescale: timescale,
845
+ duration: duration,
846
+ videoNalus: [],
847
+ audioConfig: new Uint8Array([]),
848
+ videoConfig: info.videoConfig,
849
+ data: {
850
+ sequenceNumber: this.frameIndex_,
851
+ baseMediaDecodeTime: baseMediaDecodeTime,
852
+ samples: samples,
853
+ },
854
+ stream: stream,
855
+ };
856
+ }
693
857
  };
694
858
 
695
859
  /**
@@ -713,6 +877,7 @@ shaka.transmuxer.TsTransmuxer.SUPPORTED_AUDIO_CODECS_ = [
713
877
  */
714
878
  shaka.transmuxer.TsTransmuxer.SUPPORTED_VIDEO_CODECS_ = [
715
879
  'avc',
880
+ 'hevc',
716
881
  ];
717
882
 
718
883
 
@@ -110,6 +110,23 @@ shaka.util.BufferUtils = class {
110
110
  return shaka.util.BufferUtils.view_(data, offset, length, Uint8Array);
111
111
  }
112
112
 
113
+ /**
114
+ * Creates a new Uint16Array view on the same buffer. This clamps the values
115
+ * to be within the same view (i.e. you can't use this to move past the end
116
+ * of the view, even if the underlying buffer is larger). However, you can
117
+ * pass a negative offset to access the data before the view.
118
+ *
119
+ * @param {BufferSource} data
120
+ * @param {number=} offset The offset from the beginning of this data's view
121
+ * to start the new view at.
122
+ * @param {number=} length The byte length of the new view.
123
+ * @return {!Uint16Array}
124
+ * @export
125
+ */
126
+ static toUint16(data, offset = 0, length = Infinity) {
127
+ return shaka.util.BufferUtils.view_(data, offset, length, Uint16Array);
128
+ }
129
+
113
130
  /**
114
131
  * Creates a DataView over the given buffer.
115
132
  *
@@ -135,15 +152,20 @@ shaka.util.BufferUtils = class {
135
152
  */
136
153
  static view_(data, offset, length, Type) {
137
154
  const buffer = shaka.util.BufferUtils.unsafeGetArrayBuffer_(data);
155
+ let bytesPerElement = 1;
156
+ if ('BYTES_PER_ELEMENT' in Type) {
157
+ bytesPerElement = Type.BYTES_PER_ELEMENT;
158
+ }
138
159
  // Absolute end of the |data| view within |buffer|.
139
160
  /** @suppress {strictMissingProperties} */
140
- const dataEnd = (data.byteOffset || 0) + data.byteLength;
161
+ const dataEnd = ((data.byteOffset || 0) + data.byteLength) /
162
+ bytesPerElement;
141
163
  // Absolute start of the result within |buffer|.
142
164
  /** @suppress {strictMissingProperties} */
143
- const rawStart = (data.byteOffset || 0) + offset;
144
- const start = Math.max(0, Math.min(rawStart, dataEnd));
165
+ const rawStart = ((data.byteOffset || 0) + offset) / bytesPerElement;
166
+ const start = Math.floor(Math.max(0, Math.min(rawStart, dataEnd)));
145
167
  // Absolute end of the result within |buffer|.
146
- const end = Math.min(start + Math.max(length, 0), dataEnd);
168
+ const end = Math.floor(Math.min(start + Math.max(length, 0), dataEnd));
147
169
  return new Type(buffer, start, end - start);
148
170
  }
149
171
  };