shaka-player 4.3.9 → 4.4.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/workflows/build-and-test.yaml +11 -18
- package/.github/workflows/compute-incremental-coverage.py +3 -0
- package/.github/workflows/release-please.yaml +7 -0
- package/.github/workflows/selenium-lab-tests.yaml +45 -10
- package/AUTHORS +9 -0
- package/CHANGELOG.md +295 -190
- package/CONTRIBUTORS +8 -0
- package/LICENSE +32 -0
- package/README.md +63 -10
- package/demo/autoTemplate.txt +40 -5
- package/demo/close_button.js +11 -0
- package/demo/common/asset.js +13 -1
- package/demo/common/assets.js +112 -28
- package/demo/common/message_ids.js +25 -1
- package/demo/config.js +69 -10
- package/demo/customWarning.txt +2 -2
- package/demo/index.html +3 -1
- package/demo/locales/en.json +26 -2
- package/demo/locales/source.json +105 -9
- package/demo/main.js +57 -9
- package/demo/search.js +3 -1
- package/demo/service_worker.js +3 -0
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +132 -118
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +132 -118
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +46 -28
- package/dist/locales.js +31 -31
- package/dist/receiver.compiled.debug.js +60 -52
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +60 -52
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +676 -391
- package/dist/shaka-player.compiled.debug.d.ts +676 -391
- package/dist/shaka-player.compiled.debug.externs.js +1188 -616
- package/dist/shaka-player.compiled.debug.js +1046 -700
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +1188 -616
- package/dist/shaka-player.compiled.js +1094 -933
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +677 -392
- package/dist/shaka-player.ui.debug.d.ts +677 -392
- package/dist/shaka-player.ui.debug.externs.js +1023 -451
- package/dist/shaka-player.ui.debug.js +1101 -738
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +1023 -451
- package/dist/shaka-player.ui.js +1244 -1071
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/ad_monetization.md +15 -1
- package/docs/tutorials/application-level-redirects.md +1 -1
- package/docs/tutorials/config.md +9 -5
- package/docs/tutorials/drm-config.md +61 -0
- package/docs/tutorials/fairplay.md +19 -4
- package/docs/tutorials/license-server-auth.md +4 -4
- package/docs/tutorials/license-wrapping.md +2 -2
- package/docs/tutorials/ui-customization.md +7 -3
- package/docs/tutorials/ui.md +7 -7
- package/docs/tutorials/upgrade.md +3 -0
- package/externs/ima.js +123 -2
- package/externs/isoboxer.js +217 -0
- package/externs/mediakeys.js +18 -0
- package/externs/mux.js +1 -105
- package/externs/pictureinpicture.js +48 -0
- package/externs/shaka/ads.js +61 -1
- package/externs/shaka/cea.js +110 -0
- package/externs/shaka/codecs.js +32 -0
- package/externs/shaka/manifest.js +101 -1
- package/externs/shaka/manifest_parser.js +0 -10
- package/externs/shaka/net.js +36 -7
- package/externs/shaka/offline.js +8 -1
- package/externs/shaka/player.js +220 -21
- package/externs/shaka/text.js +1 -382
- package/externs/shaka/transmuxer.js +59 -0
- package/karma.conf.js +15 -0
- package/lib/abr/simple_abr_manager.js +6 -3
- package/lib/ads/ad_manager.js +60 -2
- package/lib/ads/client_side_ad.js +86 -0
- package/lib/ads/client_side_ad_manager.js +93 -5
- package/lib/ads/server_side_ad.js +86 -0
- package/lib/ads/server_side_ad_manager.js +13 -0
- package/lib/cast/cast_utils.js +1 -0
- package/lib/cea/cea608_data_channel.js +24 -14
- package/lib/cea/cea608_memory.js +5 -2
- package/lib/cea/cea708_service.js +8 -9
- package/lib/cea/cea708_window.js +1 -2
- package/lib/cea/cea_decoder.js +23 -6
- package/lib/cea/cea_utils.js +25 -2
- package/lib/cea/dummy_caption_decoder.js +21 -0
- package/lib/cea/dummy_cea_parser.js +1 -3
- package/lib/cea/mp4_cea_parser.js +15 -10
- package/lib/cea/ts_cea_parser.js +69 -0
- package/lib/dash/content_protection.js +32 -2
- package/lib/dash/dash_parser.js +93 -31
- package/lib/dash/mpd_utils.js +6 -25
- package/lib/dash/segment_base.js +12 -14
- package/lib/dash/segment_list.js +10 -6
- package/lib/dash/segment_template.js +349 -32
- package/lib/dependencies/all.js +8 -0
- package/lib/hls/hls_classes.js +33 -8
- package/lib/hls/hls_parser.js +805 -191
- package/lib/hls/manifest_text_parser.js +4 -14
- package/lib/media/adaptation_set_criteria.js +43 -3
- package/lib/media/closed_caption_parser.js +74 -12
- package/lib/media/drm_engine.js +189 -49
- package/lib/media/gap_jumping_controller.js +1 -1
- package/lib/media/manifest_parser.js +34 -0
- package/lib/media/media_source_capabilities.js +10 -0
- package/lib/media/media_source_engine.js +475 -231
- package/lib/media/playhead.js +1 -1
- package/lib/media/presentation_timeline.js +62 -0
- package/lib/media/segment_index.js +50 -14
- package/lib/media/segment_prefetch.js +277 -0
- package/lib/media/segment_reference.js +70 -4
- package/lib/media/streaming_engine.js +258 -81
- package/lib/media/video_wrapper.js +15 -7
- package/lib/mss/content_protection.js +353 -0
- package/lib/mss/mss_parser.js +1081 -0
- package/lib/net/networking_engine.js +60 -10
- package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
- package/lib/offline/manifest_converter.js +6 -0
- package/lib/offline/storage.js +2 -4
- package/lib/player.js +309 -105
- package/lib/polyfill/media_capabilities.js +43 -3
- package/lib/polyfill/patchedmediakeys_apple.js +5 -0
- package/lib/polyfill/patchedmediakeys_nop.js +5 -0
- package/lib/polyfill/patchedmediakeys_webkit.js +5 -0
- package/lib/text/cue.js +208 -130
- package/lib/text/lrc_text_parser.js +2 -2
- package/lib/text/mp4_vtt_parser.js +2 -2
- package/lib/text/sbv_text_parser.js +1 -1
- package/lib/text/simple_text_displayer.js +2 -1
- package/lib/text/srt_text_parser.js +9 -1
- package/lib/text/ssa_text_parser.js +2 -2
- package/lib/text/text_engine.js +3 -21
- package/lib/text/text_utils.js +71 -20
- package/lib/text/ui_text_displayer.js +14 -14
- package/lib/text/vtt_text_parser.js +22 -14
- package/lib/transmuxer/aac_transmuxer.js +224 -0
- package/lib/transmuxer/ac3.js +142 -0
- package/lib/transmuxer/ac3_transmuxer.js +212 -0
- package/lib/transmuxer/adts.js +232 -0
- package/lib/transmuxer/ec3.js +103 -0
- package/lib/transmuxer/ec3_transmuxer.js +212 -0
- package/lib/transmuxer/h264.js +324 -0
- package/lib/transmuxer/mp3_transmuxer.js +204 -0
- package/lib/transmuxer/mpeg_audio.js +196 -0
- package/lib/transmuxer/mpeg_ts_transmuxer.js +182 -0
- package/lib/transmuxer/mss_transmuxer.js +389 -0
- package/lib/{media/transmuxer.js → transmuxer/muxjs_transmuxer.js} +34 -80
- package/lib/transmuxer/transmuxer_engine.js +161 -0
- package/lib/transmuxer/ts_transmuxer.js +738 -0
- package/lib/util/cmcd_manager.js +131 -71
- package/lib/util/error.js +62 -26
- package/lib/util/exp_golomb.js +220 -0
- package/lib/util/fairplay_utils.js +64 -13
- package/lib/util/id3_utils.js +56 -3
- package/lib/util/language_utils.js +11 -8
- package/lib/util/manifest_parser_utils.js +3 -0
- package/lib/util/mime_utils.js +44 -7
- package/lib/util/mp4_box_parsers.js +233 -5
- package/lib/util/mp4_generator.js +1381 -0
- package/lib/util/periods.js +40 -34
- package/lib/util/platform.js +25 -3
- package/lib/util/player_configuration.js +38 -1
- package/lib/util/stream_utils.js +138 -27
- package/lib/util/text_parser.js +1 -1
- package/lib/util/ts_parser.js +470 -47
- package/lib/util/xml_utils.js +16 -3
- package/maintained-branches.md +2 -2
- package/package.json +4 -2
- package/roadmap.md +21 -6
- package/shaka-player.uncompiled.js +18 -0
- package/test/abr/simple_abr_manager_unit.js +32 -4
- package/test/ads/ad_manager_unit.js +18 -2
- package/test/cast/cast_utils_unit.js +7 -2
- package/test/cea/cea608_memory_unit.js +24 -0
- package/test/cea/cea_decoder_unit.js +33 -0
- package/test/dash/dash_parser_content_protection_unit.js +93 -3
- package/test/dash/dash_parser_live_unit.js +56 -13
- package/test/dash/dash_parser_manifest_unit.js +70 -2
- package/test/dash/dash_parser_segment_base_unit.js +14 -9
- package/test/dash/dash_parser_segment_template_unit.js +286 -6
- package/test/demo/demo_unit.js +5 -1
- package/test/hls/hls_live_unit.js +188 -28
- package/test/hls/hls_parser_unit.js +250 -109
- package/test/hls/manifest_text_parser_unit.js +18 -13
- package/test/media/adaptation_set_criteria_unit.js +46 -14
- package/test/media/adaptation_set_unit.js +2 -0
- package/test/media/drm_engine_integration.js +11 -8
- package/test/media/drm_engine_unit.js +220 -7
- package/test/media/media_source_engine_integration.js +122 -38
- package/test/media/media_source_engine_unit.js +133 -153
- package/test/media/playhead_unit.js +3 -0
- package/test/media/presentation_timeline_unit.js +51 -0
- package/test/media/segment_index_unit.js +52 -0
- package/test/media/segment_prefetch_unit.js +243 -0
- package/test/media/streaming_engine_integration.js +9 -3
- package/test/media/streaming_engine_unit.js +440 -59
- package/test/mss/mss_parser_content_protection_unit.js +49 -0
- package/test/mss/mss_parser_unit.js +472 -0
- package/test/mss/mss_player_integration.js +123 -0
- package/test/offline/manifest_convert_unit.js +9 -0
- package/test/offline/storage_integration.js +6 -1
- package/test/player_integration.js +4 -1
- package/test/player_unit.js +386 -133
- package/test/polyfill/media_capabilities_unit.js +18 -0
- package/test/test/assets/hls-raw-aac/fileSequence0.aac +0 -0
- package/test/test/assets/hls-raw-aac/fileSequence1.aac +0 -0
- package/test/test/assets/hls-raw-aac/fileSequence2.aac +0 -0
- package/test/test/assets/hls-raw-aac/fileSequence3.aac +0 -0
- package/test/test/assets/hls-raw-aac/manifest.m3u8 +4 -0
- package/test/test/assets/hls-raw-aac/stream.m4a.m3u8 +14 -0
- package/test/test/assets/hls-raw-ac3/fileSequence0.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence1.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence2.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence3.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence4.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence5.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence6.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence7.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/prog_index.m3u8 +31 -0
- package/test/test/assets/hls-raw-ec3/fileSequence0.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence1.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence2.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence3.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence4.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence5.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence6.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence7.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/prog_index.m3u8 +31 -0
- package/test/test/assets/hls-raw-mp3/chunklist_w905519204.m3u8 +13 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_0.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_1.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_2.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_3.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/playlist.m3u8 +4 -0
- package/test/test/assets/hls-ts-aac/playlist.m3u8 +23 -0
- package/test/test/assets/hls-ts-aac/segment_0.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_1.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_2.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_3.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_4.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_5.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_6.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_7.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0000.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0001.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0002.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0003.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0004.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0005.ts +0 -0
- package/test/test/assets/hls-ts-ac3/prog_index.m3u8 +19 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0000.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0001.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0002.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0003.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0004.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0005.ts +0 -0
- package/test/test/assets/hls-ts-ec3/prog_index.m3u8 +19 -0
- package/test/test/assets/hls-ts-h264/fileSequence0.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence1.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence2.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence3.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence4.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence5.ts +0 -0
- package/test/test/assets/hls-ts-h264/prog_index.m3u8 +25 -0
- package/test/test/assets/hls-ts-mp3/manifest.m3u8 +13 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_0.ts +0 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_1.ts +0 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_2.ts +0 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_3.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/chunk.m3u8 +17 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_0_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_1_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_2_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_3_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_4_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_5_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/playlist.m3u8 +4 -0
- package/test/test/boot.js +7 -2
- package/test/test/util/fake_ad.js +99 -0
- package/test/test/util/fake_ad_manager.js +7 -1
- package/test/test/util/fake_networking_engine.js +41 -14
- package/test/test/util/fake_segment_prefetch.js +81 -0
- package/test/test/util/manifest_generator.js +19 -5
- package/test/test/util/mss_parser_util.js +115 -0
- package/test/test/util/offline_utils.js +1 -0
- package/test/test/util/simple_fakes.js +12 -3
- package/test/test/util/streaming_engine_util.js +14 -4
- package/test/test/util/ttml_utils.js +2 -2
- package/test/test/util/ui_utils.js +5 -1
- package/test/text/cue_integration.js +1 -1
- package/test/text/srt_text_parser_unit.js +78 -0
- package/test/text/text_engine_unit.js +17 -8
- package/test/text/ui_text_displayer_unit.js +4 -4
- package/test/text/vtt_text_parser_unit.js +59 -40
- package/test/text/web_vtt_generator_unit.js +9 -3
- package/test/{media/transmuxer_integration.js → transmuxer/muxjs_transmuxer_integration.js} +30 -33
- package/test/transmuxer/transmuxer_engine_integration.js +60 -0
- package/test/transmuxer/transmuxer_integration.js +296 -0
- package/test/util/cmcd_manager_unit.js +162 -13
- package/test/util/language_utils_unit.js +9 -2
- package/test/util/mp4_box_parsers_unit.js +39 -4
- package/test/util/periods_unit.js +34 -26
- package/test/util/stream_utils_unit.js +60 -107
- package/ui/controls.js +19 -1
- package/ui/controls.less +1 -0
- package/ui/externs/ui.js +13 -3
- package/ui/language_utils.js +15 -0
- package/ui/less/thumbnails.less +26 -0
- package/ui/locales/oc.json +42 -0
- package/ui/pip_button.js +83 -2
- package/ui/range_element.js +15 -0
- package/ui/resolution_selection.js +9 -2
- package/ui/seek_bar.js +230 -1
- package/ui/ui.js +5 -0
- package/lib/cea/i_caption_decoder.js +0 -51
- package/lib/cea/i_cea_parser.js +0 -68
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* MSS Transmuxer
|
|
3
|
+
* Copyright 2015 Dash Industry Forum
|
|
4
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* Redistribution and use in source and binary forms, with or without
|
|
9
|
+
* modification, are permitted provided that the following conditions are met:
|
|
10
|
+
*
|
|
11
|
+
* - Redistributions of source code must retain the above copyright notice,
|
|
12
|
+
* this list of conditions and the following disclaimer.
|
|
13
|
+
* - Redistributions in binary form must reproduce the above copyright notice,
|
|
14
|
+
* this list of conditions and the following disclaimer in the documentation
|
|
15
|
+
* and/or other materials provided with the distribution.
|
|
16
|
+
* - Neither the name of the Dash Industry Forum nor the names of its
|
|
17
|
+
* contributors may be used to endorse or promote products derived from this
|
|
18
|
+
* software without specific prior written permission.
|
|
19
|
+
*
|
|
20
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
|
21
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
23
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
24
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
25
|
+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
26
|
+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
27
|
+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
28
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
29
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
30
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
goog.provide('shaka.transmuxer.MssTransmuxer');
|
|
34
|
+
|
|
35
|
+
goog.require('shaka.media.Capabilities');
|
|
36
|
+
goog.require('shaka.transmuxer.TransmuxerEngine');
|
|
37
|
+
goog.require('shaka.util.BufferUtils');
|
|
38
|
+
goog.require('shaka.util.Error');
|
|
39
|
+
goog.require('shaka.util.ManifestParserUtils');
|
|
40
|
+
goog.require('shaka.dependencies');
|
|
41
|
+
|
|
42
|
+
goog.requireType('shaka.media.SegmentReference');
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @implements {shaka.extern.Transmuxer}
|
|
47
|
+
* @export
|
|
48
|
+
*/
|
|
49
|
+
shaka.transmuxer.MssTransmuxer = class {
|
|
50
|
+
/**
|
|
51
|
+
* @param {string} mimeType
|
|
52
|
+
*/
|
|
53
|
+
constructor(mimeType) {
|
|
54
|
+
/** @private {string} */
|
|
55
|
+
this.originalMimeType_ = mimeType;
|
|
56
|
+
|
|
57
|
+
/** @private {?ISOBoxer} */
|
|
58
|
+
this.isoBoxer_ = shaka.dependencies.isoBoxer();
|
|
59
|
+
|
|
60
|
+
if (this.isoBoxer_) {
|
|
61
|
+
this.addSpecificBoxProcessor_();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Add specific box processor for codem-isoboxer
|
|
67
|
+
*
|
|
68
|
+
* @private
|
|
69
|
+
*/
|
|
70
|
+
addSpecificBoxProcessor_() {
|
|
71
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
72
|
+
this.isoBoxer_.addBoxProcessor('saio', function() {
|
|
73
|
+
// eslint-disable-next-line no-invalid-this
|
|
74
|
+
const box = /** @type {!ISOBox} */(this);
|
|
75
|
+
box._procFullBox();
|
|
76
|
+
if (box.flags & 1) {
|
|
77
|
+
box._procField('aux_info_type', 'uint', 32);
|
|
78
|
+
box._procField('aux_info_type_parameter', 'uint', 32);
|
|
79
|
+
}
|
|
80
|
+
box._procField('entry_count', 'uint', 32);
|
|
81
|
+
box._procFieldArray('offset', box.entry_count, 'uint',
|
|
82
|
+
(box.version === 1) ? 64 : 32);
|
|
83
|
+
});
|
|
84
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
85
|
+
this.isoBoxer_.addBoxProcessor('saiz', function() {
|
|
86
|
+
// eslint-disable-next-line no-invalid-this
|
|
87
|
+
const box = /** @type {!ISOBox} */(this);
|
|
88
|
+
box._procFullBox();
|
|
89
|
+
if (box.flags & 1) {
|
|
90
|
+
box._procField('aux_info_type', 'uint', 32);
|
|
91
|
+
box._procField('aux_info_type_parameter', 'uint', 32);
|
|
92
|
+
}
|
|
93
|
+
box._procField('default_sample_info_size', 'uint', 8);
|
|
94
|
+
box._procField('sample_count', 'uint', 32);
|
|
95
|
+
if (box.default_sample_info_size === 0) {
|
|
96
|
+
box._procFieldArray('sample_info_size',
|
|
97
|
+
box.sample_count, 'uint', 8);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
101
|
+
const sencProcessor = function() {
|
|
102
|
+
// eslint-disable-next-line no-invalid-this
|
|
103
|
+
const box = /** @type {!ISOBox} */(this);
|
|
104
|
+
box._procFullBox();
|
|
105
|
+
if (box.flags & 1) {
|
|
106
|
+
box._procField('AlgorithmID', 'uint', 24);
|
|
107
|
+
box._procField('IV_size', 'uint', 8);
|
|
108
|
+
box._procFieldArray('KID', 16, 'uint', 8);
|
|
109
|
+
}
|
|
110
|
+
box._procField('sample_count', 'uint', 32);
|
|
111
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
112
|
+
box._procEntries('entry', box.sample_count, function(entry) {
|
|
113
|
+
// eslint-disable-next-line no-invalid-this
|
|
114
|
+
const boxEntry = /** @type {!ISOBox} */(this);
|
|
115
|
+
boxEntry._procEntryField(entry, 'InitializationVector', 'data', 8);
|
|
116
|
+
if (boxEntry.flags & 2) {
|
|
117
|
+
boxEntry._procEntryField(entry, 'NumberOfEntries', 'uint', 16);
|
|
118
|
+
boxEntry._procSubEntries(entry, 'clearAndCryptedData',
|
|
119
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
120
|
+
entry.NumberOfEntries, function(clearAndCryptedData) {
|
|
121
|
+
// eslint-disable-next-line no-invalid-this
|
|
122
|
+
const subBoxEntry = /** @type {!ISOBox} */(this);
|
|
123
|
+
subBoxEntry._procEntryField(clearAndCryptedData,
|
|
124
|
+
'BytesOfClearData', 'uint', 16);
|
|
125
|
+
subBoxEntry._procEntryField(clearAndCryptedData,
|
|
126
|
+
'BytesOfEncryptedData', 'uint', 32);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
this.isoBoxer_.addBoxProcessor('senc', sencProcessor);
|
|
132
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
133
|
+
this.isoBoxer_.addBoxProcessor('uuid', function() {
|
|
134
|
+
const MssTransmuxer = shaka.transmuxer.MssTransmuxer;
|
|
135
|
+
// eslint-disable-next-line no-invalid-this
|
|
136
|
+
const box = /** @type {!ISOBox} */(this);
|
|
137
|
+
let isSENC = true;
|
|
138
|
+
for (let i = 0; i < 16; i++) {
|
|
139
|
+
if (box.usertype[i] !== MssTransmuxer.UUID_SENC_[i]) {
|
|
140
|
+
isSENC = false;
|
|
141
|
+
}
|
|
142
|
+
// Add support for other user types here
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (isSENC) {
|
|
146
|
+
if (box._parsing) {
|
|
147
|
+
// Convert this box to sepiff for later processing.
|
|
148
|
+
// See processMediaSegment_ function.
|
|
149
|
+
box.type = 'sepiff';
|
|
150
|
+
}
|
|
151
|
+
// eslint-disable-next-line no-restricted-syntax, no-invalid-this
|
|
152
|
+
sencProcessor.call(/** @type {!ISOBox} */(this));
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* @override
|
|
160
|
+
* @export
|
|
161
|
+
*/
|
|
162
|
+
destroy() {
|
|
163
|
+
// Nothing
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Check if the mime type and the content type is supported.
|
|
169
|
+
* @param {string} mimeType
|
|
170
|
+
* @param {string=} contentType
|
|
171
|
+
* @return {boolean}
|
|
172
|
+
* @override
|
|
173
|
+
* @export
|
|
174
|
+
*/
|
|
175
|
+
isSupported(mimeType, contentType) {
|
|
176
|
+
const Capabilities = shaka.media.Capabilities;
|
|
177
|
+
|
|
178
|
+
const isMss = mimeType.startsWith('mss/');
|
|
179
|
+
|
|
180
|
+
if (!this.isoBoxer_ || !isMss) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (contentType) {
|
|
185
|
+
return Capabilities.isTypeSupported(
|
|
186
|
+
this.convertCodecs(contentType, mimeType));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
190
|
+
|
|
191
|
+
const audioMime = this.convertCodecs(ContentType.AUDIO, mimeType);
|
|
192
|
+
const videoMime = this.convertCodecs(ContentType.VIDEO, mimeType);
|
|
193
|
+
return Capabilities.isTypeSupported(audioMime) ||
|
|
194
|
+
Capabilities.isTypeSupported(videoMime);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* @override
|
|
200
|
+
* @export
|
|
201
|
+
*/
|
|
202
|
+
convertCodecs(contentType, mimeType) {
|
|
203
|
+
return mimeType.replace('mss/', '');
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* @override
|
|
209
|
+
* @export
|
|
210
|
+
*/
|
|
211
|
+
getOrginalMimeType() {
|
|
212
|
+
return this.originalMimeType_;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* @override
|
|
218
|
+
* @export
|
|
219
|
+
*/
|
|
220
|
+
transmux(data, stream, reference) {
|
|
221
|
+
if (!reference) {
|
|
222
|
+
// Init segment doesn't need transmux
|
|
223
|
+
return Promise.resolve(shaka.util.BufferUtils.toUint8(data));
|
|
224
|
+
}
|
|
225
|
+
if (!stream.mssPrivateData) {
|
|
226
|
+
return Promise.reject(new shaka.util.Error(
|
|
227
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
228
|
+
shaka.util.Error.Category.MEDIA,
|
|
229
|
+
shaka.util.Error.Code.MSS_MISSING_DATA_FOR_TRANSMUXING));
|
|
230
|
+
}
|
|
231
|
+
try {
|
|
232
|
+
const transmuxedData = this.processMediaSegment_(
|
|
233
|
+
data, stream, reference);
|
|
234
|
+
return Promise.resolve(transmuxedData);
|
|
235
|
+
} catch (exception) {
|
|
236
|
+
if (exception instanceof shaka.util.Error) {
|
|
237
|
+
return Promise.reject(exception);
|
|
238
|
+
}
|
|
239
|
+
return Promise.reject(new shaka.util.Error(
|
|
240
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
241
|
+
shaka.util.Error.Category.MEDIA,
|
|
242
|
+
shaka.util.Error.Code.MSS_TRANSMUXING_FAILED));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Process a media segment from a data and stream.
|
|
248
|
+
* @param {BufferSource} data
|
|
249
|
+
* @param {shaka.extern.Stream} stream
|
|
250
|
+
* @param {shaka.media.SegmentReference} reference
|
|
251
|
+
* @return {!Uint8Array}
|
|
252
|
+
* @private
|
|
253
|
+
*/
|
|
254
|
+
processMediaSegment_(data, stream, reference) {
|
|
255
|
+
let i;
|
|
256
|
+
const isoFile = this.isoBoxer_.parseBuffer(data);
|
|
257
|
+
// Update track_Id in tfhd box
|
|
258
|
+
const tfhd = isoFile.fetch('tfhd');
|
|
259
|
+
tfhd.track_ID = stream.id + 1;
|
|
260
|
+
// Add tfdt box
|
|
261
|
+
let tfdt = isoFile.fetch('tfdt');
|
|
262
|
+
const traf = isoFile.fetch('traf');
|
|
263
|
+
if (tfdt === null) {
|
|
264
|
+
tfdt = this.isoBoxer_.createFullBox('tfdt', traf, tfhd);
|
|
265
|
+
tfdt.version = 1;
|
|
266
|
+
tfdt.flags = 0;
|
|
267
|
+
const timescale = stream.mssPrivateData.timescale;
|
|
268
|
+
const startTime = reference.startTime;
|
|
269
|
+
tfdt.baseMediaDecodeTime = Math.floor(startTime * timescale);
|
|
270
|
+
}
|
|
271
|
+
const trun = isoFile.fetch('trun');
|
|
272
|
+
// Process tfxd boxes
|
|
273
|
+
// This box provide absolute timestamp but we take the segment start
|
|
274
|
+
// time for tfdt
|
|
275
|
+
let tfxd = isoFile.fetch('tfxd');
|
|
276
|
+
if (tfxd) {
|
|
277
|
+
tfxd._parent.boxes.splice(tfxd._parent.boxes.indexOf(tfxd), 1);
|
|
278
|
+
tfxd = null;
|
|
279
|
+
}
|
|
280
|
+
let tfrf = isoFile.fetch('tfrf');
|
|
281
|
+
if (tfrf) {
|
|
282
|
+
tfrf._parent.boxes.splice(tfrf._parent.boxes.indexOf(tfrf), 1);
|
|
283
|
+
tfrf = null;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// If protected content in PIFF1.1 format
|
|
287
|
+
// (sepiff box = Sample Encryption PIFF)
|
|
288
|
+
// => convert sepiff box it into a senc box
|
|
289
|
+
// => create saio and saiz boxes (if not already present)
|
|
290
|
+
const sepiff = isoFile.fetch('sepiff');
|
|
291
|
+
if (sepiff !== null) {
|
|
292
|
+
sepiff.type = 'senc';
|
|
293
|
+
sepiff.usertype = undefined;
|
|
294
|
+
|
|
295
|
+
let saio = isoFile.fetch('saio');
|
|
296
|
+
if (saio === null) {
|
|
297
|
+
// Create Sample Auxiliary Information Offsets Box box (saio)
|
|
298
|
+
saio = this.isoBoxer_.createFullBox('saio', traf);
|
|
299
|
+
saio.version = 0;
|
|
300
|
+
saio.flags = 0;
|
|
301
|
+
saio.entry_count = 1;
|
|
302
|
+
saio.offset = [0];
|
|
303
|
+
const saiz = this.isoBoxer_.createFullBox('saiz', traf);
|
|
304
|
+
saiz.version = 0;
|
|
305
|
+
saiz.flags = 0;
|
|
306
|
+
saiz.sample_count = sepiff.sample_count;
|
|
307
|
+
saiz.default_sample_info_size = 0;
|
|
308
|
+
saiz.sample_info_size = [];
|
|
309
|
+
if (sepiff.flags & 0x02) {
|
|
310
|
+
// Sub-sample encryption => set sample_info_size for each sample
|
|
311
|
+
for (i = 0; i < sepiff.sample_count; i += 1) {
|
|
312
|
+
// 10 = 8 (InitializationVector field size) + 2
|
|
313
|
+
// (subsample_count field size)
|
|
314
|
+
// 6 = 2 (BytesOfClearData field size) + 4
|
|
315
|
+
// (BytesOfEncryptedData field size)
|
|
316
|
+
saiz.sample_info_size[i] =
|
|
317
|
+
10 + (6 * sepiff.entry[i].NumberOfEntries);
|
|
318
|
+
}
|
|
319
|
+
} else {
|
|
320
|
+
// No sub-sample encryption => set default
|
|
321
|
+
// sample_info_size = InitializationVector field size (8)
|
|
322
|
+
saiz.default_sample_info_size = 8;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// set tfhd.base-data-offset-present to false
|
|
328
|
+
tfhd.flags &= 0xFFFFFE;
|
|
329
|
+
// set tfhd.default-base-is-moof to true
|
|
330
|
+
tfhd.flags |= 0x020000;
|
|
331
|
+
// set trun.data-offset-present to true
|
|
332
|
+
trun.flags |= 0x000001;
|
|
333
|
+
|
|
334
|
+
// Update trun.data_offset field that corresponds to first data byte
|
|
335
|
+
// (inside mdat box)
|
|
336
|
+
const moof = isoFile.fetch('moof');
|
|
337
|
+
const length = moof.getLength();
|
|
338
|
+
trun.data_offset = length + 8;
|
|
339
|
+
|
|
340
|
+
// Update saio box offset field according to new senc box offset
|
|
341
|
+
const saio = isoFile.fetch('saio');
|
|
342
|
+
if (saio !== null) {
|
|
343
|
+
const trafPosInMoof = this.getBoxOffset_(moof, 'traf');
|
|
344
|
+
const sencPosInTraf = this.getBoxOffset_(traf, 'senc');
|
|
345
|
+
// Set offset from begin fragment to the first IV field in senc box
|
|
346
|
+
// 16 = box header (12) + sample_count field size (4)
|
|
347
|
+
saio.offset[0] = trafPosInMoof + sencPosInTraf + 16;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return shaka.util.BufferUtils.toUint8(isoFile.write());
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* This function returns the offset of the 1st byte of a child box within
|
|
355
|
+
* a container box.
|
|
356
|
+
*
|
|
357
|
+
* @param {ISOBox} parent
|
|
358
|
+
* @param {string} type
|
|
359
|
+
* @return {number}
|
|
360
|
+
* @private
|
|
361
|
+
*/
|
|
362
|
+
getBoxOffset_(parent, type) {
|
|
363
|
+
let offset = 8;
|
|
364
|
+
for (let i = 0; i < parent.boxes.length; i++) {
|
|
365
|
+
if (parent.boxes[i].type === type) {
|
|
366
|
+
return offset;
|
|
367
|
+
}
|
|
368
|
+
offset += parent.boxes[i].size;
|
|
369
|
+
}
|
|
370
|
+
return offset;
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* @private {!Uint8Array}
|
|
376
|
+
*/
|
|
377
|
+
shaka.transmuxer.MssTransmuxer.UUID_SENC_ = new Uint8Array([
|
|
378
|
+
0xA2, 0x39, 0x4F, 0x52, 0x5A, 0x9B, 0x4F, 0x14,
|
|
379
|
+
0xA2, 0x44, 0x6C, 0x42, 0x7C, 0x64, 0x8D, 0xF4,
|
|
380
|
+
]);
|
|
381
|
+
|
|
382
|
+
shaka.transmuxer.TransmuxerEngine.registerTransmuxer(
|
|
383
|
+
'mss/audio/mp4',
|
|
384
|
+
() => new shaka.transmuxer.MssTransmuxer('mss/audio/mp4'),
|
|
385
|
+
shaka.transmuxer.TransmuxerEngine.PluginPriority.FALLBACK);
|
|
386
|
+
shaka.transmuxer.TransmuxerEngine.registerTransmuxer(
|
|
387
|
+
'mss/video/mp4',
|
|
388
|
+
() => new shaka.transmuxer.MssTransmuxer('mss/video/mp4'),
|
|
389
|
+
shaka.transmuxer.TransmuxerEngine.PluginPriority.FALLBACK);
|
|
@@ -4,26 +4,24 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
goog.provide('shaka.
|
|
7
|
+
goog.provide('shaka.transmuxer.MuxjsTransmuxer');
|
|
8
8
|
|
|
9
9
|
goog.require('goog.asserts');
|
|
10
|
+
goog.require('shaka.dependencies');
|
|
10
11
|
goog.require('shaka.media.Capabilities');
|
|
12
|
+
goog.require('shaka.transmuxer.TransmuxerEngine');
|
|
11
13
|
goog.require('shaka.util.BufferUtils');
|
|
12
14
|
goog.require('shaka.util.Error');
|
|
13
|
-
goog.require('shaka.util.IDestroyable');
|
|
14
15
|
goog.require('shaka.util.ManifestParserUtils');
|
|
15
16
|
goog.require('shaka.util.PublicPromise');
|
|
16
17
|
goog.require('shaka.util.Uint8ArrayUtils');
|
|
17
|
-
goog.require('shaka.dependencies');
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* Transmuxer
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* @implements {shaka.util.IDestroyable}
|
|
21
|
+
* @implements {shaka.extern.Transmuxer}
|
|
22
|
+
* @export
|
|
25
23
|
*/
|
|
26
|
-
shaka.
|
|
24
|
+
shaka.transmuxer.MuxjsTransmuxer = class {
|
|
27
25
|
/**
|
|
28
26
|
* @param {string} mimeType
|
|
29
27
|
*/
|
|
@@ -43,9 +41,6 @@ shaka.media.Transmuxer = class {
|
|
|
43
41
|
/** @private {!Array.<!Uint8Array>} */
|
|
44
42
|
this.transmuxedData_ = [];
|
|
45
43
|
|
|
46
|
-
/** @private {!Array.<muxjs.mp4.ClosedCaption>} */
|
|
47
|
-
this.captions_ = [];
|
|
48
|
-
|
|
49
44
|
/** @private {boolean} */
|
|
50
45
|
this.isTransmuxing_ = false;
|
|
51
46
|
|
|
@@ -58,103 +53,73 @@ shaka.media.Transmuxer = class {
|
|
|
58
53
|
}
|
|
59
54
|
}
|
|
60
55
|
|
|
56
|
+
|
|
61
57
|
/**
|
|
62
58
|
* @override
|
|
59
|
+
* @export
|
|
63
60
|
*/
|
|
64
61
|
destroy() {
|
|
65
62
|
if (this.muxTransmuxer_) {
|
|
66
63
|
this.muxTransmuxer_.dispose();
|
|
67
64
|
}
|
|
68
65
|
this.muxTransmuxer_ = null;
|
|
69
|
-
return Promise.resolve();
|
|
70
66
|
}
|
|
71
67
|
|
|
72
68
|
|
|
73
69
|
/**
|
|
74
|
-
* Check if the
|
|
75
|
-
* loaded.
|
|
70
|
+
* Check if the mime type and the content type is supported.
|
|
76
71
|
* @param {string} mimeType
|
|
77
72
|
* @param {string=} contentType
|
|
78
73
|
* @return {boolean}
|
|
74
|
+
* @override
|
|
75
|
+
* @export
|
|
79
76
|
*/
|
|
80
|
-
|
|
81
|
-
const Transmuxer = shaka.media.Transmuxer;
|
|
77
|
+
isSupported(mimeType, contentType) {
|
|
82
78
|
const Capabilities = shaka.media.Capabilities;
|
|
83
79
|
|
|
84
|
-
const isTs =
|
|
85
|
-
const isAac = Transmuxer.isAacContainer_(mimeType);
|
|
80
|
+
const isTs = this.isTsContainer_(mimeType);
|
|
86
81
|
|
|
87
|
-
if (!
|
|
82
|
+
if (!this.muxjs_ || !isTs) {
|
|
88
83
|
return false;
|
|
89
84
|
}
|
|
90
85
|
|
|
91
|
-
if (isAac) {
|
|
92
|
-
return Capabilities.isTypeSupported(Transmuxer.convertAacCodecs_());
|
|
93
|
-
}
|
|
94
|
-
|
|
95
86
|
if (contentType) {
|
|
96
87
|
return Capabilities.isTypeSupported(
|
|
97
|
-
|
|
88
|
+
this.convertTsCodecs_(contentType, mimeType));
|
|
98
89
|
}
|
|
99
90
|
|
|
100
91
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
101
92
|
|
|
102
|
-
const audioMime =
|
|
103
|
-
const videoMime =
|
|
93
|
+
const audioMime = this.convertTsCodecs_(ContentType.AUDIO, mimeType);
|
|
94
|
+
const videoMime = this.convertTsCodecs_(ContentType.VIDEO, mimeType);
|
|
104
95
|
return Capabilities.isTypeSupported(audioMime) ||
|
|
105
96
|
Capabilities.isTypeSupported(videoMime);
|
|
106
97
|
}
|
|
107
98
|
|
|
108
99
|
|
|
109
|
-
/**
|
|
110
|
-
* Check if the mimetype is 'audio/aac'.
|
|
111
|
-
* @param {string} mimeType
|
|
112
|
-
* @return {boolean}
|
|
113
|
-
* @private
|
|
114
|
-
*/
|
|
115
|
-
static isAacContainer_(mimeType) {
|
|
116
|
-
return mimeType.toLowerCase().split(';')[0] == 'audio/aac';
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
|
|
120
100
|
/**
|
|
121
101
|
* Check if the mimetype contains 'mp2t'.
|
|
122
102
|
* @param {string} mimeType
|
|
123
103
|
* @return {boolean}
|
|
124
104
|
* @private
|
|
125
105
|
*/
|
|
126
|
-
|
|
106
|
+
isTsContainer_(mimeType) {
|
|
127
107
|
return mimeType.toLowerCase().split(';')[0].split('/')[1] == 'mp2t';
|
|
128
108
|
}
|
|
129
109
|
|
|
130
110
|
|
|
131
111
|
/**
|
|
132
|
-
*
|
|
133
|
-
* @
|
|
134
|
-
* @param {string} mimeType
|
|
135
|
-
* @return {string}
|
|
112
|
+
* @override
|
|
113
|
+
* @export
|
|
136
114
|
*/
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
return Transmuxer.convertAacCodecs_();
|
|
141
|
-
} else if (Transmuxer.isTsContainer_(mimeType)) {
|
|
142
|
-
return Transmuxer.convertTsCodecs_(contentType, mimeType);
|
|
115
|
+
convertCodecs(contentType, mimeType) {
|
|
116
|
+
if (this.isTsContainer_(mimeType)) {
|
|
117
|
+
return this.convertTsCodecs_(contentType, mimeType);
|
|
143
118
|
}
|
|
144
119
|
return mimeType;
|
|
145
120
|
}
|
|
146
121
|
|
|
147
122
|
|
|
148
|
-
/**
|
|
149
|
-
* For aac stream, convert its codecs to MP4 codecs.
|
|
150
|
-
* @return {string}
|
|
151
|
-
* @private
|
|
152
|
-
*/
|
|
153
|
-
static convertAacCodecs_() {
|
|
154
|
-
return 'audio/mp4; codecs="mp4a.40.2"';
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
|
|
158
123
|
/**
|
|
159
124
|
* For transport stream, convert its codecs to MP4 codecs.
|
|
160
125
|
* @param {string} contentType
|
|
@@ -162,7 +127,7 @@ shaka.media.Transmuxer = class {
|
|
|
162
127
|
* @return {string}
|
|
163
128
|
* @private
|
|
164
129
|
*/
|
|
165
|
-
|
|
130
|
+
convertTsCodecs_(contentType, tsMimeType) {
|
|
166
131
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
167
132
|
let mp4MimeType = tsMimeType.replace(/mp2t/i, 'mp4');
|
|
168
133
|
if (contentType == ContentType.AUDIO) {
|
|
@@ -205,8 +170,8 @@ shaka.media.Transmuxer = class {
|
|
|
205
170
|
|
|
206
171
|
|
|
207
172
|
/**
|
|
208
|
-
*
|
|
209
|
-
* @
|
|
173
|
+
* @override
|
|
174
|
+
* @export
|
|
210
175
|
*/
|
|
211
176
|
getOrginalMimeType() {
|
|
212
177
|
return this.originalMimeType_;
|
|
@@ -214,10 +179,8 @@ shaka.media.Transmuxer = class {
|
|
|
214
179
|
|
|
215
180
|
|
|
216
181
|
/**
|
|
217
|
-
*
|
|
218
|
-
* @
|
|
219
|
-
* @return {!Promise.<{data: !Uint8Array,
|
|
220
|
-
* captions: !Array.<!muxjs.mp4.ClosedCaption>}>}
|
|
182
|
+
* @override
|
|
183
|
+
* @export
|
|
221
184
|
*/
|
|
222
185
|
transmux(data) {
|
|
223
186
|
goog.asserts.assert(this.muxTransmuxer_,
|
|
@@ -227,7 +190,6 @@ shaka.media.Transmuxer = class {
|
|
|
227
190
|
this.isTransmuxing_ = true;
|
|
228
191
|
this.transmuxPromise_ = new shaka.util.PublicPromise();
|
|
229
192
|
this.transmuxedData_ = [];
|
|
230
|
-
this.captions_ = [];
|
|
231
193
|
|
|
232
194
|
const dataArray = shaka.util.BufferUtils.toUint8(data);
|
|
233
195
|
this.muxTransmuxer_.push(dataArray);
|
|
@@ -247,13 +209,6 @@ shaka.media.Transmuxer = class {
|
|
|
247
209
|
return this.transmuxPromise_;
|
|
248
210
|
}
|
|
249
211
|
|
|
250
|
-
/**
|
|
251
|
-
* Reset captions from Transport stream to MP4, using the mux.js library.
|
|
252
|
-
*/
|
|
253
|
-
resetCaptions() {
|
|
254
|
-
this.muxTransmuxer_.resetCaptions();
|
|
255
|
-
}
|
|
256
|
-
|
|
257
212
|
/**
|
|
258
213
|
* Handles the 'data' event of the transmuxer.
|
|
259
214
|
* Extracts the cues from the transmuxed segment, and adds them to an array.
|
|
@@ -264,7 +219,6 @@ shaka.media.Transmuxer = class {
|
|
|
264
219
|
* @private
|
|
265
220
|
*/
|
|
266
221
|
onTransmuxed_(segment) {
|
|
267
|
-
this.captions_ = segment.captions;
|
|
268
222
|
this.transmuxedData_.push(
|
|
269
223
|
shaka.util.Uint8ArrayUtils.concat(segment.initSegment, segment.data));
|
|
270
224
|
}
|
|
@@ -276,13 +230,13 @@ shaka.media.Transmuxer = class {
|
|
|
276
230
|
* @private
|
|
277
231
|
*/
|
|
278
232
|
onTransmuxDone_() {
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
captions: this.captions_,
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
this.transmuxPromise_.resolve(output);
|
|
233
|
+
const data = shaka.util.Uint8ArrayUtils.concat(...this.transmuxedData_);
|
|
234
|
+
this.transmuxPromise_.resolve(data);
|
|
285
235
|
this.isTransmuxing_ = false;
|
|
286
236
|
}
|
|
287
237
|
};
|
|
288
238
|
|
|
239
|
+
shaka.transmuxer.TransmuxerEngine.registerTransmuxer(
|
|
240
|
+
'video/mp2t',
|
|
241
|
+
() => new shaka.transmuxer.MuxjsTransmuxer('video/mp2t'),
|
|
242
|
+
shaka.transmuxer.TransmuxerEngine.PluginPriority.FALLBACK);
|