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.
- package/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
- package/.github/workflows/release-please.yaml +2 -27
- package/AUTHORS +2 -0
- package/CHANGELOG.md +156 -39
- package/CODE_OF_CONDUCT.md +1 -1
- package/CONTRIBUTORS +2 -0
- package/README.md +54 -42
- package/demo/asset_card.js +18 -21
- package/demo/cast_receiver/index.html +0 -1
- package/demo/close_button.js +0 -3
- package/demo/common/asset.js +33 -22
- package/demo/common/assets.js +249 -60
- package/demo/config.js +219 -253
- package/demo/custom.js +88 -133
- package/demo/front.js +7 -10
- package/demo/index.html +19 -22
- package/demo/input.js +6 -11
- package/demo/input_container.js +8 -9
- package/demo/main.js +62 -126
- package/demo/search.js +29 -34
- package/demo/service_worker.js +0 -3
- package/demo/tooltip.js +3 -5
- package/demo/visualizer.js +3 -5
- package/demo/visualizer_button.js +1 -20
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +211 -228
- package/dist/demo.compiled.debug.map +4 -4
- package/dist/demo.compiled.js +211 -228
- package/dist/demo.compiled.map +4 -4
- package/dist/deps.js +42 -37
- package/dist/locales.js +34 -30
- package/dist/receiver.compiled.debug.js +64 -77
- package/dist/receiver.compiled.debug.map +4 -4
- package/dist/receiver.compiled.js +64 -77
- package/dist/receiver.compiled.map +4 -4
- package/dist/shaka-player.compiled.d.ts +343 -151
- package/dist/shaka-player.compiled.debug.d.ts +343 -151
- package/dist/shaka-player.compiled.debug.externs.js +356 -117
- package/dist/shaka-player.compiled.debug.js +952 -811
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +356 -117
- package/dist/shaka-player.compiled.js +1165 -1078
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +359 -153
- package/dist/shaka-player.ui.debug.d.ts +359 -153
- package/dist/shaka-player.ui.debug.externs.js +382 -117
- package/dist/shaka-player.ui.debug.js +1084 -918
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +382 -117
- package/dist/shaka-player.ui.js +1377 -1274
- package/dist/shaka-player.ui.map +4 -4
- package/docs/design/lcevc-integration.md +14 -14
- package/docs/tutorials/ad_monetization.md +54 -0
- package/docs/tutorials/basic-usage.md +2 -1
- package/docs/tutorials/errors.md +2 -1
- package/docs/tutorials/faq.md +27 -55
- package/docs/tutorials/index.json +2 -1
- package/docs/tutorials/lcevc.md +118 -0
- package/docs/tutorials/offline.md +10 -8
- package/docs/tutorials/plugins.md +5 -0
- package/docs/tutorials/ui-customization.md +17 -0
- package/docs/tutorials/ui.md +2 -1
- package/docs/tutorials/upgrade.md +3 -0
- package/externs/css_style_declaration.js +19 -0
- package/externs/lcevc.js +37 -13
- package/externs/managedmediasource.js +24 -0
- package/externs/media_remote.js +68 -0
- package/externs/mediatailor.js +193 -0
- package/externs/pictureinpicture.js +11 -0
- package/externs/shaka/abr_manager.js +6 -2
- package/externs/shaka/ads.js +27 -0
- package/externs/shaka/cea.js +7 -0
- package/externs/shaka/codecs.js +5 -3
- package/externs/shaka/manifest.js +31 -10
- package/externs/shaka/manifest_parser.js +24 -1
- package/externs/shaka/net.js +2 -2
- package/externs/shaka/offline.js +13 -2
- package/externs/shaka/player.js +65 -8
- package/externs/shaka/text.js +3 -1
- package/externs/shaka/transmuxer.js +1 -1
- package/karma.conf.js +7 -3
- package/lib/abr/simple_abr_manager.js +66 -9
- package/lib/ads/ad_manager.js +104 -50
- package/lib/ads/media_tailor_ad.js +297 -0
- package/lib/ads/media_tailor_ad_manager.js +839 -0
- package/lib/cast/cast_receiver.js +1 -1
- package/lib/cea/cea_decoder.js +28 -0
- package/lib/cea/dummy_caption_decoder.js +5 -0
- package/lib/cea/ts_cea_parser.js +15 -2
- package/lib/config/codec_switching_strategy.js +24 -0
- package/lib/dash/content_protection.js +120 -2
- package/lib/dash/dash_parser.js +322 -93
- package/lib/dash/mpd_utils.js +62 -37
- package/lib/dash/segment_base.js +17 -10
- package/lib/dash/segment_list.js +18 -9
- package/lib/dash/segment_template.js +122 -107
- package/lib/dependencies/all.js +8 -7
- package/lib/hls/hls_classes.js +28 -43
- package/lib/hls/hls_parser.js +798 -658
- package/lib/hls/hls_utils.js +64 -5
- package/lib/hls/manifest_text_parser.js +7 -11
- package/lib/lcevc/lcevc_dec.js +220 -0
- package/lib/media/adaptation_set.js +32 -14
- package/lib/media/adaptation_set_criteria.js +86 -16
- package/lib/media/closed_caption_parser.js +13 -0
- package/lib/media/content_workarounds.js +6 -0
- package/lib/media/drm_engine.js +8 -13
- package/lib/media/manifest_parser.js +8 -113
- package/lib/media/media_source_capabilities.js +10 -3
- package/lib/media/media_source_engine.js +286 -44
- package/lib/media/play_rate_controller.js +8 -38
- package/lib/media/presentation_timeline.js +7 -1
- package/lib/media/quality_observer.js +1 -1
- package/lib/media/segment_index.js +6 -6
- package/lib/media/segment_prefetch.js +92 -24
- package/lib/media/segment_reference.js +73 -7
- package/lib/media/segment_utils.js +343 -0
- package/lib/media/stall_detector.js +0 -3
- package/lib/media/streaming_engine.js +73 -38
- package/lib/mss/mss_parser.js +19 -2
- package/lib/net/networking_engine.js +67 -12
- package/lib/net/networking_utils.js +95 -0
- package/lib/offline/indexeddb/v1_storage_cell.js +3 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +3 -0
- package/lib/offline/manifest_converter.js +3 -0
- package/lib/offline/offline_manifest_parser.js +10 -0
- package/lib/offline/storage.js +14 -7
- package/lib/player.js +1098 -1537
- package/lib/polyfill/mediasource.js +22 -1
- package/lib/text/cue.js +15 -0
- package/lib/text/mp4_ttml_parser.js +2 -2
- package/lib/text/srt_text_parser.js +2 -2
- package/lib/text/stub_text_displayer.js +51 -0
- package/lib/text/text_engine.js +3 -2
- package/lib/text/ttml_text_parser.js +45 -5
- package/lib/text/ui_text_displayer.js +8 -0
- package/lib/text/vtt_text_parser.js +40 -22
- package/lib/transmuxer/aac_transmuxer.js +1 -1
- package/lib/transmuxer/ac3_transmuxer.js +1 -1
- package/lib/transmuxer/ec3_transmuxer.js +1 -1
- package/lib/transmuxer/h264.js +5 -4
- package/lib/transmuxer/h265.js +863 -0
- package/lib/transmuxer/mp3_transmuxer.js +1 -1
- package/lib/transmuxer/mpeg_ts_transmuxer.js +4 -3
- package/lib/transmuxer/mss_transmuxer.js +1 -1
- package/lib/transmuxer/ts_transmuxer.js +187 -22
- package/lib/util/buffer_utils.js +26 -4
- package/lib/util/content_steering_manager.js +358 -0
- package/lib/util/error.js +30 -15
- package/lib/util/exp_golomb.js +30 -2
- package/lib/util/fairplay_utils.js +1 -1
- package/lib/util/fake_event.js +8 -1
- package/lib/util/id3_utils.js +50 -1
- package/lib/util/manifest_parser_utils.js +12 -8
- package/lib/util/mp4_generator.js +6 -8
- package/lib/util/mutex.js +59 -0
- package/lib/util/object_utils.js +1 -1
- package/lib/util/periods.js +156 -179
- package/lib/util/platform.js +44 -3
- package/lib/util/player_configuration.js +43 -6
- package/lib/util/state_history.js +6 -2
- package/lib/util/stream_utils.js +206 -283
- package/lib/util/ts_parser.js +335 -98
- package/lib/util/uint8array_utils.js +5 -1
- package/lib/util/xml_utils.js +5 -0
- package/maintained-branches.md +3 -2
- package/package.json +4 -6
- package/roadmap.md +25 -5
- package/shaka-player.uncompiled.js +2 -2
- package/support.html +0 -1
- package/test/abr/simple_abr_manager_unit.js +33 -33
- package/test/ads/ad_manager_unit.js +3 -2
- package/test/cast/cast_receiver_integration.js +50 -4
- package/test/cast/cast_utils_unit.js +2 -0
- package/test/cea/cea_decoder_unit.js +7 -0
- package/test/codec_switching/codec_switching_integration.js +182 -0
- package/test/dash/dash_parser_content_protection_unit.js +2 -0
- package/test/dash/dash_parser_integration.js +74 -0
- package/test/dash/dash_parser_live_unit.js +2 -19
- package/test/dash/dash_parser_manifest_unit.js +536 -2
- package/test/dash/dash_parser_segment_base_unit.js +2 -0
- package/test/dash/dash_parser_segment_list_unit.js +2 -0
- package/test/dash/dash_parser_segment_template_unit.js +2 -0
- package/test/dash/mpd_utils_unit.js +61 -30
- package/test/demo/demo_unit.js +0 -16
- package/test/hls/hls_live_unit.js +14 -3
- package/test/hls/hls_parser_unit.js +385 -33
- package/test/hls/manifest_text_parser_unit.js +32 -99
- package/test/media/adaptation_set_criteria_unit.js +284 -15
- package/test/media/adaptation_set_unit.js +2 -0
- package/test/media/content_workarounds_unit.js +1 -1
- package/test/media/drm_engine_unit.js +3 -3
- package/test/media/media_source_engine_unit.js +166 -2
- package/test/media/play_rate_controller_unit.js +0 -48
- package/test/media/segment_index_unit.js +5 -4
- package/test/media/segment_prefetch_unit.js +1 -1
- package/test/media/streaming_engine_unit.js +17 -17
- package/test/mss/mss_parser_unit.js +2 -0
- package/test/mss/mss_player_integration.js +3 -2
- package/test/net/networking_engine_unit.js +3 -3
- package/test/{media/manifest_parser_unit.js → net/networking_utils_unit.js} +2 -2
- package/test/offline/manifest_convert_unit.js +14 -0
- package/test/offline/offline_integration.js +2 -1
- package/test/offline/storage_integration.js +22 -13
- package/test/player_external.js +4 -2
- package/test/player_integration.js +15 -4
- package/test/player_load_graph_integration.js +47 -151
- package/test/player_src_equals_external.js +1 -0
- package/test/player_src_equals_integration.js +71 -4
- package/test/player_unit.js +182 -158
- package/test/test/assets/dash-aes-128/Fragments(video=0,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=20000000,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=40000000,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=60000000,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/Fragments(video=i,format=mpd-time-csf) +0 -0
- package/test/test/assets/dash-aes-128/dash.mpd +18 -0
- package/test/test/assets/dash-aes-128/license +1 -0
- package/test/test/assets/dash-multi-codec/audio_en_2c_128k_aac.mp4 +0 -0
- package/test/test/assets/dash-multi-codec/audio_es_2c_64k_opus.webm +0 -0
- package/test/test/assets/dash-multi-codec/dash.mpd +32 -0
- package/test/test/assets/dash-multi-codec/video_144p_108k_h264.mp4 +0 -0
- package/test/test/assets/hls-ts-h265/0.ts +0 -0
- package/test/test/assets/hls-ts-h265/hevc.m3u8 +6 -0
- package/test/test/assets/hls-ts-h265/index.m3u8 +7 -0
- package/test/test/assets/hls-ts-muxed-aac-h265/0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h265/1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h265/media.m3u8 +9 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/media.m3u8 +24 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00000.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00001.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00002.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00003.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00004.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ac3-h264/s_00005.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0000.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0001.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0002.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/ChID_voices_1280x720p_25fps_h264_6ch_256kbps_ddp_sub_0003.ts +0 -0
- package/test/test/assets/hls-ts-muxed-ec3-h264/prog_index.m3u8 +14 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/index.m3u8 +23 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-1-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-2-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-3-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-4-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-5-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-6-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-7-v1-a1.ts +0 -0
- package/test/test/assets/hls-ts-muxed-mp3-h264/seg-8-v1-a1.ts +0 -0
- package/test/test/util/dash_parser_util.js +4 -0
- package/test/test/util/fake_ad_manager.js +20 -0
- package/test/test/util/fake_media_source_engine.js +13 -2
- package/test/test/util/fake_networking_engine.js +9 -1
- package/test/test/util/fake_segment_prefetch.js +3 -0
- package/test/test/util/manifest_generator.js +11 -3
- package/test/test/util/manifest_parser_util.js +14 -2
- package/test/test/util/mss_parser_util.js +4 -0
- package/test/test/util/offline_utils.js +2 -0
- package/test/test/util/simple_fakes.js +2 -2
- package/test/test/util/streaming_engine_util.js +10 -4
- package/test/test/util/test_scheme.js +6 -0
- package/test/test/util/ui_utils.js +4 -3
- package/test/text/mp4_ttml_parser_unit.js +4 -4
- package/test/text/srt_text_parser_unit.js +1 -1
- package/test/text/text_displayer_layout_unit.js +1 -1
- package/test/text/text_engine_unit.js +6 -0
- package/test/text/ttml_text_parser_unit.js +85 -2
- package/test/text/vtt_text_parser_unit.js +103 -31
- package/test/transmuxer/transmuxer_engine_integration.js +9 -0
- package/test/transmuxer/transmuxer_integration.js +150 -3
- package/test/ui/ad_ui_unit.js +2 -2
- package/test/ui/ui_customization_unit.js +17 -16
- package/test/ui/ui_integration.js +30 -20
- package/test/ui/ui_unit.js +28 -29
- package/test/util/buffer_utils_unit.js +1 -1
- package/test/util/content_steering_manager_unit.js +427 -0
- package/test/util/id3_utils_unit.js +52 -0
- package/test/util/stream_utils_unit.js +207 -169
- package/test/util/ts_parser_unit.js +3 -3
- package/third_party/closure-uri/uri.js +13 -1
- package/ui/audio_language_selection.js +9 -2
- package/ui/controls.js +125 -0
- package/ui/externs/ui.js +24 -2
- package/ui/language_utils.js +43 -8
- package/ui/less/range_elements.less +33 -0
- package/ui/locales/en.json +1 -0
- package/ui/locales/es-419.json +1 -0
- package/ui/locales/es.json +1 -0
- package/ui/locales/source.json +4 -0
- package/ui/localization.js +10 -0
- package/ui/pip_button.js +22 -120
- package/ui/remote_button.js +203 -0
- package/ui/resolution_selection.js +47 -10
- package/ui/seek_bar.js +296 -3
- package/ui/text_selection.js +2 -1
- package/ui/ui.js +11 -4
- package/demo/common/message_ids.js +0 -309
- package/demo/locales/en.json +0 -288
- package/demo/locales/source.json +0 -1146
- package/externs/mux.js +0 -69
- package/lib/lcevc/lcevc_dil.js +0 -152
- package/lib/routing/node.js +0 -23
- package/lib/routing/payload.js +0 -43
- package/lib/routing/walker.js +0 -587
- package/lib/transmuxer/muxjs_transmuxer.js +0 -242
- package/test/routing/walker_unit.js +0 -504
- package/test/transmuxer/muxjs_transmuxer_integration.js +0 -177
|
@@ -119,7 +119,7 @@ shaka.transmuxer.MpegTsTransmuxer = class {
|
|
|
119
119
|
* @override
|
|
120
120
|
* @export
|
|
121
121
|
*/
|
|
122
|
-
|
|
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' ||
|
|
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,
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
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
|
-
|
|
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
|
|
package/lib/util/buffer_utils.js
CHANGED
|
@@ -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
|
};
|