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
|
@@ -8,6 +8,7 @@ goog.provide('shaka.media.MediaSourceEngine');
|
|
|
8
8
|
|
|
9
9
|
goog.require('goog.asserts');
|
|
10
10
|
goog.require('shaka.log');
|
|
11
|
+
goog.require('shaka.config.CodecSwitchingStrategy');
|
|
11
12
|
goog.require('shaka.media.Capabilities');
|
|
12
13
|
goog.require('shaka.media.ContentWorkarounds');
|
|
13
14
|
goog.require('shaka.media.ClosedCaptionParser');
|
|
@@ -31,7 +32,7 @@ goog.require('shaka.util.Mp4Parser');
|
|
|
31
32
|
goog.require('shaka.util.Platform');
|
|
32
33
|
goog.require('shaka.util.PublicPromise');
|
|
33
34
|
goog.require('shaka.util.TsParser');
|
|
34
|
-
goog.require('shaka.lcevc.
|
|
35
|
+
goog.require('shaka.lcevc.Dec');
|
|
35
36
|
|
|
36
37
|
|
|
37
38
|
/**
|
|
@@ -53,10 +54,10 @@ shaka.media.MediaSourceEngine = class {
|
|
|
53
54
|
* MediaSourceEngine is destroyed, it will destroy the displayer.
|
|
54
55
|
* @param {!function(!Array.<shaka.extern.ID3Metadata>, number, ?number)=}
|
|
55
56
|
* onMetadata
|
|
56
|
-
* @param {?shaka.lcevc.
|
|
57
|
+
* @param {?shaka.lcevc.Dec} [lcevcDec] Optional - LCEVC Decoder Object
|
|
57
58
|
*
|
|
58
59
|
*/
|
|
59
|
-
constructor(video, textDisplayer, onMetadata,
|
|
60
|
+
constructor(video, textDisplayer, onMetadata, lcevcDec) {
|
|
60
61
|
/** @private {HTMLMediaElement} */
|
|
61
62
|
this.video_ = video;
|
|
62
63
|
|
|
@@ -91,8 +92,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
91
92
|
number, ?number)} */
|
|
92
93
|
this.onMetadata_ = onMetadata || onMetadataNoOp;
|
|
93
94
|
|
|
94
|
-
/** @private {?shaka.lcevc.
|
|
95
|
-
this.
|
|
95
|
+
/** @private {?shaka.lcevc.Dec} */
|
|
96
|
+
this.lcevcDec_ = lcevcDec || null;
|
|
96
97
|
|
|
97
98
|
/**
|
|
98
99
|
* @private {!Object.<string,
|
|
@@ -115,7 +116,10 @@ shaka.media.MediaSourceEngine = class {
|
|
|
115
116
|
/** @private {string} */
|
|
116
117
|
this.url_ = '';
|
|
117
118
|
|
|
118
|
-
/** @private {
|
|
119
|
+
/** @private {boolean} */
|
|
120
|
+
this.playbackHasBegun_ = false;
|
|
121
|
+
|
|
122
|
+
/** @private {(MediaSource|ManagedMediaSource)} */
|
|
119
123
|
this.mediaSource_ = this.createMediaSource(this.mediaSourceOpen_);
|
|
120
124
|
|
|
121
125
|
/** @private {boolean} */
|
|
@@ -138,6 +142,12 @@ shaka.media.MediaSourceEngine = class {
|
|
|
138
142
|
|
|
139
143
|
/** @private {!shaka.util.PublicPromise.<number>} */
|
|
140
144
|
this.textSequenceModeOffset_ = new shaka.util.PublicPromise();
|
|
145
|
+
|
|
146
|
+
/** @private {boolean} */
|
|
147
|
+
this.needSplitMuxedContent_ = false;
|
|
148
|
+
|
|
149
|
+
/** @private {boolean} */
|
|
150
|
+
this.streamingAllowed_ = true;
|
|
141
151
|
}
|
|
142
152
|
|
|
143
153
|
/**
|
|
@@ -147,25 +157,60 @@ shaka.media.MediaSourceEngine = class {
|
|
|
147
157
|
* Replaced by unit tests.
|
|
148
158
|
*
|
|
149
159
|
* @param {!shaka.util.PublicPromise} p
|
|
150
|
-
* @return {!MediaSource}
|
|
160
|
+
* @return {!(MediaSource|ManagedMediaSource)}
|
|
151
161
|
*/
|
|
152
162
|
createMediaSource(p) {
|
|
153
|
-
|
|
163
|
+
if (window.ManagedMediaSource) {
|
|
164
|
+
this.video_.disableRemotePlayback = true;
|
|
165
|
+
|
|
166
|
+
const mediaSource = new ManagedMediaSource();
|
|
167
|
+
|
|
168
|
+
this.eventManager_.listenOnce(
|
|
169
|
+
mediaSource, 'sourceopen', () => this.onSourceOpen_(p));
|
|
154
170
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
171
|
+
this.eventManager_.listen(
|
|
172
|
+
mediaSource, 'startstreaming', () => {
|
|
173
|
+
this.streamingAllowed_ = true;
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
this.eventManager_.listen(
|
|
177
|
+
mediaSource, 'endstreaming', () => {
|
|
178
|
+
this.streamingAllowed_ = false;
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Correctly set when playback has begun.
|
|
182
|
+
this.eventManager_.listenOnce(this.video_, 'playing', () => {
|
|
183
|
+
this.playbackHasBegun_ = true;
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
this.url_ = shaka.media.MediaSourceEngine.createObjectURL(mediaSource);
|
|
158
187
|
|
|
159
|
-
|
|
160
|
-
|
|
188
|
+
this.video_.src = this.url_;
|
|
189
|
+
|
|
190
|
+
return mediaSource;
|
|
191
|
+
} else {
|
|
192
|
+
const mediaSource = new MediaSource();
|
|
161
193
|
|
|
162
|
-
|
|
194
|
+
// Set up MediaSource on the video element.
|
|
195
|
+
this.eventManager_.listenOnce(
|
|
196
|
+
mediaSource, 'sourceopen', () => this.onSourceOpen_(p));
|
|
163
197
|
|
|
164
|
-
|
|
198
|
+
// Correctly set when playback has begun.
|
|
199
|
+
this.eventManager_.listenOnce(this.video_, 'playing', () => {
|
|
200
|
+
this.playbackHasBegun_ = true;
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Store the object URL for releasing it later.
|
|
204
|
+
this.url_ = shaka.media.MediaSourceEngine.createObjectURL(mediaSource);
|
|
205
|
+
|
|
206
|
+
this.video_.src = this.url_;
|
|
207
|
+
|
|
208
|
+
return mediaSource;
|
|
209
|
+
}
|
|
165
210
|
}
|
|
166
211
|
|
|
167
212
|
/**
|
|
168
|
-
* @param {
|
|
213
|
+
* @param {shaka.util.PublicPromise} p
|
|
169
214
|
* @private
|
|
170
215
|
*/
|
|
171
216
|
onSourceOpen_(p) {
|
|
@@ -217,9 +262,11 @@ shaka.media.MediaSourceEngine = class {
|
|
|
217
262
|
'video/mp4; codecs="vp9"',
|
|
218
263
|
'video/mp4; codecs="vp09.00.10.08"',
|
|
219
264
|
'video/mp4; codecs="av01.0.01M.08"',
|
|
265
|
+
'video/mp4; codecs="dvh1.20.01"',
|
|
220
266
|
'audio/mp4; codecs="mp4a.40.2"',
|
|
221
267
|
'audio/mp4; codecs="ac-3"',
|
|
222
268
|
'audio/mp4; codecs="ec-3"',
|
|
269
|
+
'audio/mp4; codecs="ac-4"',
|
|
223
270
|
'audio/mp4; codecs="opus"',
|
|
224
271
|
'audio/mp4; codecs="flac"',
|
|
225
272
|
'audio/mp4; codecs="dtsc"', // DTS Digital Surround
|
|
@@ -341,7 +388,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
341
388
|
this.queues_ = {};
|
|
342
389
|
|
|
343
390
|
// This object is owned by Player
|
|
344
|
-
this.
|
|
391
|
+
this.lcevcDec_ = null;
|
|
345
392
|
}
|
|
346
393
|
|
|
347
394
|
/**
|
|
@@ -379,6 +426,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
379
426
|
async init(streamsByType, sequenceMode=false,
|
|
380
427
|
manifestType=shaka.media.ManifestParser.UNKNOWN,
|
|
381
428
|
ignoreManifestTimestampsInSegmentsMode=false) {
|
|
429
|
+
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
430
|
+
|
|
382
431
|
await this.mediaSourceOpen_;
|
|
383
432
|
|
|
384
433
|
this.sequenceMode_ = sequenceMode;
|
|
@@ -392,8 +441,13 @@ shaka.media.MediaSourceEngine = class {
|
|
|
392
441
|
|
|
393
442
|
for (const contentType of streamsByType.keys()) {
|
|
394
443
|
const stream = streamsByType.get(contentType);
|
|
395
|
-
this.initSourceBuffer_(contentType, stream);
|
|
396
|
-
this.
|
|
444
|
+
this.initSourceBuffer_(contentType, stream, stream.codecs);
|
|
445
|
+
if (this.needSplitMuxedContent_) {
|
|
446
|
+
this.queues_[ContentType.AUDIO] = [];
|
|
447
|
+
this.queues_[ContentType.VIDEO] = [];
|
|
448
|
+
} else {
|
|
449
|
+
this.queues_[contentType] = [];
|
|
450
|
+
}
|
|
397
451
|
}
|
|
398
452
|
}
|
|
399
453
|
|
|
@@ -402,9 +456,10 @@ shaka.media.MediaSourceEngine = class {
|
|
|
402
456
|
*
|
|
403
457
|
* @param {shaka.util.ManifestParserUtils.ContentType} contentType
|
|
404
458
|
* @param {shaka.extern.Stream} stream
|
|
459
|
+
* @param {string} codecs
|
|
405
460
|
* @private
|
|
406
461
|
*/
|
|
407
|
-
initSourceBuffer_(contentType, stream) {
|
|
462
|
+
initSourceBuffer_(contentType, stream, codecs) {
|
|
408
463
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
409
464
|
|
|
410
465
|
goog.asserts.assert(
|
|
@@ -412,7 +467,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
412
467
|
'Type negotiation should happen before MediaSourceEngine.init!');
|
|
413
468
|
|
|
414
469
|
let mimeType = shaka.util.MimeUtils.getFullType(
|
|
415
|
-
stream.mimeType,
|
|
470
|
+
stream.mimeType, codecs);
|
|
416
471
|
if (contentType == ContentType.TEXT) {
|
|
417
472
|
this.reinitText(mimeType, this.sequenceMode_, stream.external);
|
|
418
473
|
} else {
|
|
@@ -424,9 +479,19 @@ shaka.media.MediaSourceEngine = class {
|
|
|
424
479
|
}
|
|
425
480
|
const mimeTypeWithAllCodecs =
|
|
426
481
|
shaka.util.MimeUtils.getFullTypeWithAllCodecs(
|
|
427
|
-
stream.mimeType,
|
|
482
|
+
stream.mimeType, codecs);
|
|
428
483
|
const TransmuxerEngine = shaka.transmuxer.TransmuxerEngine;
|
|
429
484
|
if (needTransmux) {
|
|
485
|
+
const audioCodec = shaka.util.ManifestParserUtils.guessCodecsSafe(
|
|
486
|
+
ContentType.AUDIO, (codecs || '').split(','));
|
|
487
|
+
const videoCodec = shaka.util.ManifestParserUtils.guessCodecsSafe(
|
|
488
|
+
ContentType.VIDEO, (codecs || '').split(','));
|
|
489
|
+
if (audioCodec && videoCodec) {
|
|
490
|
+
this.needSplitMuxedContent_ = true;
|
|
491
|
+
this.initSourceBuffer_(ContentType.AUDIO, stream, audioCodec);
|
|
492
|
+
this.initSourceBuffer_(ContentType.VIDEO, stream, videoCodec);
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
430
495
|
const transmuxerPlugin =
|
|
431
496
|
TransmuxerEngine.findTransmuxer(mimeTypeWithAllCodecs);
|
|
432
497
|
if (transmuxerPlugin) {
|
|
@@ -450,8 +515,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
450
515
|
shaka.util.Error.Category.MEDIA,
|
|
451
516
|
shaka.util.Error.Code.MEDIA_SOURCE_OPERATION_THREW,
|
|
452
517
|
exception,
|
|
453
|
-
'The mediaSource_ status was' + this.mediaSource_.readyState +
|
|
454
|
-
'expected \'open\'');
|
|
518
|
+
'The mediaSource_ status was ' + this.mediaSource_.readyState +
|
|
519
|
+
' expected \'open\'');
|
|
455
520
|
}
|
|
456
521
|
|
|
457
522
|
if (this.sequenceMode_) {
|
|
@@ -481,6 +546,16 @@ shaka.media.MediaSourceEngine = class {
|
|
|
481
546
|
this.config_ = config;
|
|
482
547
|
}
|
|
483
548
|
|
|
549
|
+
/**
|
|
550
|
+
* Indicate if the streaming is allowed by MediaSourceEngine.
|
|
551
|
+
* If we using MediaSource we allways returns true.
|
|
552
|
+
*
|
|
553
|
+
* @return {boolean}
|
|
554
|
+
*/
|
|
555
|
+
isStreamingAllowed() {
|
|
556
|
+
return this.streamingAllowed_;
|
|
557
|
+
}
|
|
558
|
+
|
|
484
559
|
/**
|
|
485
560
|
* Reinitialize the TextEngine for a new text type.
|
|
486
561
|
* @param {string} mimeType
|
|
@@ -513,7 +588,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
513
588
|
* @return {?number} The timestamp in seconds, or null if nothing is buffered.
|
|
514
589
|
*/
|
|
515
590
|
bufferStart(contentType) {
|
|
516
|
-
if (this.reloadingMediaSource_
|
|
591
|
+
if (this.reloadingMediaSource_ ||
|
|
592
|
+
!Object.keys(this.sourceBuffers_).length) {
|
|
517
593
|
return null;
|
|
518
594
|
}
|
|
519
595
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
@@ -708,7 +784,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
708
784
|
} else if (!mimeType.includes('/mp4') && !mimeType.includes('/webm') &&
|
|
709
785
|
shaka.util.TsParser.probe(uint8ArrayData)) {
|
|
710
786
|
const tsParser = new shaka.util.TsParser().parse(uint8ArrayData);
|
|
711
|
-
const startTime = tsParser.getStartTime()
|
|
787
|
+
const startTime = tsParser.getStartTime(contentType);
|
|
712
788
|
if (startTime != null) {
|
|
713
789
|
timestamp = startTime;
|
|
714
790
|
}
|
|
@@ -743,7 +819,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
743
819
|
*/
|
|
744
820
|
async appendBuffer(
|
|
745
821
|
contentType, data, reference, stream, hasClosedCaptions, seeked = false,
|
|
746
|
-
adaptation = false, isChunkedData = false) {
|
|
822
|
+
adaptation = false, isChunkedData = false, fromSplit = false) {
|
|
747
823
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
748
824
|
|
|
749
825
|
if (contentType == ContentType.TEXT) {
|
|
@@ -755,7 +831,23 @@ shaka.media.MediaSourceEngine = class {
|
|
|
755
831
|
await this.textEngine_.appendBuffer(
|
|
756
832
|
data,
|
|
757
833
|
reference ? reference.startTime : null,
|
|
758
|
-
reference ? reference.endTime : null
|
|
834
|
+
reference ? reference.endTime : null,
|
|
835
|
+
reference ? reference.getUris()[0] : null);
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
if (!fromSplit && this.needSplitMuxedContent_) {
|
|
840
|
+
await this.appendBuffer(ContentType.AUDIO, data, reference, stream,
|
|
841
|
+
hasClosedCaptions, seeked, adaptation, isChunkedData,
|
|
842
|
+
/* fromSplit= */ true);
|
|
843
|
+
await this.appendBuffer(ContentType.VIDEO, data, reference, stream,
|
|
844
|
+
hasClosedCaptions, seeked, adaptation, isChunkedData,
|
|
845
|
+
/* fromSplit= */ true);
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
if (!this.sourceBuffers_[contentType]) {
|
|
850
|
+
shaka.log.warning('Attempted to restore a non-existent source buffer');
|
|
759
851
|
return;
|
|
760
852
|
}
|
|
761
853
|
|
|
@@ -763,7 +855,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
763
855
|
|
|
764
856
|
let mimeType = this.sourceBufferTypes_[contentType];
|
|
765
857
|
if (this.transmuxers_[contentType]) {
|
|
766
|
-
mimeType = this.transmuxers_[contentType].
|
|
858
|
+
mimeType = this.transmuxers_[contentType].getOriginalMimeType();
|
|
767
859
|
}
|
|
768
860
|
if (reference) {
|
|
769
861
|
const timestamp = this.getTimestampAndDispatchMetadata_(
|
|
@@ -772,7 +864,9 @@ shaka.media.MediaSourceEngine = class {
|
|
|
772
864
|
const calculatedTimestampOffset = reference.startTime - timestamp;
|
|
773
865
|
const timestampOffsetDifference =
|
|
774
866
|
Math.abs(timestampOffset - calculatedTimestampOffset);
|
|
775
|
-
if (timestampOffsetDifference >= 0.1 || seeked || adaptation)
|
|
867
|
+
if ((timestampOffsetDifference >= 0.1 || seeked || adaptation) &&
|
|
868
|
+
(!isChunkedData || calculatedTimestampOffset > 0 ||
|
|
869
|
+
!timestampOffset)) {
|
|
776
870
|
timestampOffset = calculatedTimestampOffset;
|
|
777
871
|
if (this.attemptTimestampOffsetCalculation_) {
|
|
778
872
|
this.enqueueOperation_(
|
|
@@ -850,7 +944,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
850
944
|
if (goog.DEBUG && reference && !reference.isPreload() && !isChunkedData) {
|
|
851
945
|
bufferedBefore = this.getBuffered_(contentType);
|
|
852
946
|
}
|
|
853
|
-
this.append_(contentType, data);
|
|
947
|
+
this.append_(contentType, data, timestampOffset);
|
|
854
948
|
});
|
|
855
949
|
|
|
856
950
|
if (goog.DEBUG && reference && !reference.isPreload() && !isChunkedData) {
|
|
@@ -910,6 +1004,11 @@ shaka.media.MediaSourceEngine = class {
|
|
|
910
1004
|
await this.enqueueOperation_(
|
|
911
1005
|
contentType,
|
|
912
1006
|
() => this.remove_(contentType, startTime, endTime));
|
|
1007
|
+
if (this.needSplitMuxedContent_) {
|
|
1008
|
+
await this.enqueueOperation_(
|
|
1009
|
+
ContentType.AUDIO,
|
|
1010
|
+
() => this.remove_(ContentType.AUDIO, startTime, endTime));
|
|
1011
|
+
}
|
|
913
1012
|
}
|
|
914
1013
|
}
|
|
915
1014
|
|
|
@@ -931,6 +1030,12 @@ shaka.media.MediaSourceEngine = class {
|
|
|
931
1030
|
await this.enqueueOperation_(
|
|
932
1031
|
contentType,
|
|
933
1032
|
() => this.remove_(contentType, 0, this.mediaSource_.duration));
|
|
1033
|
+
if (this.needSplitMuxedContent_) {
|
|
1034
|
+
await this.enqueueOperation_(
|
|
1035
|
+
ContentType.AUDIO,
|
|
1036
|
+
() => this.remove_(
|
|
1037
|
+
ContentType.AUDIO, 0, this.mediaSource_.duration));
|
|
1038
|
+
}
|
|
934
1039
|
}
|
|
935
1040
|
}
|
|
936
1041
|
|
|
@@ -961,6 +1066,11 @@ shaka.media.MediaSourceEngine = class {
|
|
|
961
1066
|
await this.enqueueOperation_(
|
|
962
1067
|
contentType,
|
|
963
1068
|
() => this.flush_(contentType));
|
|
1069
|
+
if (this.needSplitMuxedContent_) {
|
|
1070
|
+
await this.enqueueOperation_(
|
|
1071
|
+
ContentType.AUDIO,
|
|
1072
|
+
() => this.flush_(ContentType.AUDIO));
|
|
1073
|
+
}
|
|
964
1074
|
}
|
|
965
1075
|
|
|
966
1076
|
/**
|
|
@@ -1014,16 +1124,33 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1014
1124
|
operations.push(this.enqueueOperation_(
|
|
1015
1125
|
contentType,
|
|
1016
1126
|
() => this.abort_(contentType)));
|
|
1127
|
+
if (this.needSplitMuxedContent_) {
|
|
1128
|
+
operations.push(this.enqueueOperation_(
|
|
1129
|
+
ContentType.AUDIO,
|
|
1130
|
+
() => this.abort_(ContentType.AUDIO)));
|
|
1131
|
+
}
|
|
1017
1132
|
}
|
|
1018
1133
|
if (!ignoreTimestampOffset) {
|
|
1019
1134
|
operations.push(this.enqueueOperation_(
|
|
1020
1135
|
contentType,
|
|
1021
1136
|
() => this.setTimestampOffset_(contentType, timestampOffset)));
|
|
1137
|
+
if (this.needSplitMuxedContent_) {
|
|
1138
|
+
operations.push(this.enqueueOperation_(
|
|
1139
|
+
ContentType.AUDIO,
|
|
1140
|
+
() => this.setTimestampOffset_(
|
|
1141
|
+
ContentType.AUDIO, timestampOffset)));
|
|
1142
|
+
}
|
|
1022
1143
|
}
|
|
1023
1144
|
operations.push(this.enqueueOperation_(
|
|
1024
1145
|
contentType,
|
|
1025
1146
|
() => this.setAppendWindow_(
|
|
1026
1147
|
contentType, appendWindowStart, appendWindowEnd)));
|
|
1148
|
+
if (this.needSplitMuxedContent_) {
|
|
1149
|
+
operations.push(this.enqueueOperation_(
|
|
1150
|
+
ContentType.AUDIO,
|
|
1151
|
+
() => this.setAppendWindow_(
|
|
1152
|
+
ContentType.AUDIO, appendWindowStart, appendWindowEnd)));
|
|
1153
|
+
}
|
|
1027
1154
|
|
|
1028
1155
|
await Promise.all(operations);
|
|
1029
1156
|
}
|
|
@@ -1054,9 +1181,19 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1054
1181
|
this.enqueueOperation_(
|
|
1055
1182
|
contentType,
|
|
1056
1183
|
() => this.abort_(contentType));
|
|
1184
|
+
if (this.needSplitMuxedContent_) {
|
|
1185
|
+
this.enqueueOperation_(
|
|
1186
|
+
ContentType.AUDIO,
|
|
1187
|
+
() => this.abort_(ContentType.AUDIO));
|
|
1188
|
+
}
|
|
1057
1189
|
await this.enqueueOperation_(
|
|
1058
1190
|
contentType,
|
|
1059
1191
|
() => this.setTimestampOffset_(contentType, timestampOffset));
|
|
1192
|
+
if (this.needSplitMuxedContent_) {
|
|
1193
|
+
await this.enqueueOperation_(
|
|
1194
|
+
ContentType.AUDIO,
|
|
1195
|
+
() => this.setTimestampOffset_(ContentType.AUDIO, timestampOffset));
|
|
1196
|
+
}
|
|
1060
1197
|
}
|
|
1061
1198
|
|
|
1062
1199
|
/**
|
|
@@ -1120,16 +1257,17 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1120
1257
|
* Append data to the SourceBuffer.
|
|
1121
1258
|
* @param {shaka.util.ManifestParserUtils.ContentType} contentType
|
|
1122
1259
|
* @param {BufferSource} data
|
|
1260
|
+
* @param {number} timestampOffset
|
|
1123
1261
|
* @private
|
|
1124
1262
|
*/
|
|
1125
|
-
append_(contentType, data) {
|
|
1263
|
+
append_(contentType, data, timestampOffset) {
|
|
1126
1264
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
1127
1265
|
|
|
1128
|
-
// Append only video data to the LCEVC
|
|
1129
|
-
if (contentType == ContentType.VIDEO && this.
|
|
1130
|
-
// Append video buffers to the LCEVC
|
|
1266
|
+
// Append only video data to the LCEVC Dec.
|
|
1267
|
+
if (contentType == ContentType.VIDEO && this.lcevcDec_) {
|
|
1268
|
+
// Append video buffers to the LCEVC Dec for parsing and storing
|
|
1131
1269
|
// of LCEVC data.
|
|
1132
|
-
this.
|
|
1270
|
+
this.lcevcDec_.appendBuffer(data, timestampOffset);
|
|
1133
1271
|
}
|
|
1134
1272
|
|
|
1135
1273
|
// This will trigger an 'updateend' event.
|
|
@@ -1292,7 +1430,6 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1292
1430
|
*/
|
|
1293
1431
|
enqueueOperation_(contentType, start) {
|
|
1294
1432
|
this.destroyer_.ensureNotDestroyed();
|
|
1295
|
-
|
|
1296
1433
|
const operation = {
|
|
1297
1434
|
start: start,
|
|
1298
1435
|
p: new shaka.util.PublicPromise(),
|
|
@@ -1563,8 +1700,24 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1563
1700
|
*/
|
|
1564
1701
|
async reset_(streamsByType) {
|
|
1565
1702
|
const Functional = shaka.util.Functional;
|
|
1703
|
+
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
1566
1704
|
this.reloadingMediaSource_ = true;
|
|
1705
|
+
this.needSplitMuxedContent_ = false;
|
|
1567
1706
|
const currentTime = this.video_.currentTime;
|
|
1707
|
+
|
|
1708
|
+
// When codec switching if the user is currently paused we don't want
|
|
1709
|
+
// to trigger a play when switching codec.
|
|
1710
|
+
// Playing can also end up in a paused state after a codec switch
|
|
1711
|
+
// so we need to remember the current states.
|
|
1712
|
+
const previousAutoPlayState = this.video_.autoplay;
|
|
1713
|
+
const previousPausedState = this.video_.paused;
|
|
1714
|
+
if (this.playbackHasBegun_) {
|
|
1715
|
+
// Only set autoplay to false if the video playback has already begun.
|
|
1716
|
+
// When a codec switch happens before playback has begun this can cause
|
|
1717
|
+
// autoplay not to work as expected.
|
|
1718
|
+
this.video_.autoplay = false;
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1568
1721
|
try {
|
|
1569
1722
|
this.eventManager_.removeAll();
|
|
1570
1723
|
|
|
@@ -1598,7 +1751,6 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1598
1751
|
}
|
|
1599
1752
|
await Promise.all(cleanup);
|
|
1600
1753
|
this.transmuxers_ = {};
|
|
1601
|
-
this.queues_ = {};
|
|
1602
1754
|
this.sourceBuffers_ = {};
|
|
1603
1755
|
|
|
1604
1756
|
const previousDuration = this.mediaSource_.duration;
|
|
@@ -1622,7 +1774,13 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1622
1774
|
|
|
1623
1775
|
for (const contentType of streamsByType.keys()) {
|
|
1624
1776
|
const stream = streamsByType.get(contentType);
|
|
1625
|
-
this.initSourceBuffer_(contentType, stream);
|
|
1777
|
+
this.initSourceBuffer_(contentType, stream, stream.codecs);
|
|
1778
|
+
if (this.needSplitMuxedContent_) {
|
|
1779
|
+
this.queues_[ContentType.AUDIO] = [];
|
|
1780
|
+
this.queues_[ContentType.VIDEO] = [];
|
|
1781
|
+
} else {
|
|
1782
|
+
this.queues_[contentType] = [];
|
|
1783
|
+
}
|
|
1626
1784
|
}
|
|
1627
1785
|
|
|
1628
1786
|
// Fake a seek to catchup the playhead.
|
|
@@ -1631,6 +1789,17 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1631
1789
|
await sourceBufferAdded;
|
|
1632
1790
|
} finally {
|
|
1633
1791
|
this.reloadingMediaSource_ = false;
|
|
1792
|
+
|
|
1793
|
+
this.destroyer_.ensureNotDestroyed();
|
|
1794
|
+
|
|
1795
|
+
this.eventManager_.listenOnce(this.video_, 'canplay', () => {
|
|
1796
|
+
this.destroyer_.ensureNotDestroyed();
|
|
1797
|
+
|
|
1798
|
+
this.video_.autoplay = previousAutoPlayState;
|
|
1799
|
+
if (!previousPausedState) {
|
|
1800
|
+
this.video_.play();
|
|
1801
|
+
}
|
|
1802
|
+
});
|
|
1634
1803
|
}
|
|
1635
1804
|
}
|
|
1636
1805
|
|
|
@@ -1657,6 +1826,9 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1657
1826
|
* @private
|
|
1658
1827
|
*/
|
|
1659
1828
|
async codecSwitchIfNecessary_(contentType, stream, streamsByType) {
|
|
1829
|
+
if (contentType == shaka.util.ManifestParserUtils.ContentType.TEXT) {
|
|
1830
|
+
return false;
|
|
1831
|
+
}
|
|
1660
1832
|
const MimeUtils = shaka.util.MimeUtils;
|
|
1661
1833
|
const currentCodec = MimeUtils.getCodecBase(
|
|
1662
1834
|
MimeUtils.getCodecs(this.sourceBufferTypes_[contentType]));
|
|
@@ -1696,7 +1868,10 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1696
1868
|
return false;
|
|
1697
1869
|
}
|
|
1698
1870
|
|
|
1699
|
-
if (
|
|
1871
|
+
if (this.config_.codecSwitchingStrategy ===
|
|
1872
|
+
shaka.config.CodecSwitchingStrategy.SMOOTH &&
|
|
1873
|
+
shaka.media.Capabilities.isChangeTypeSupported() &&
|
|
1874
|
+
!this.needSplitMuxedContent_) {
|
|
1700
1875
|
await this.changeType(contentType, newMimeType, transmuxer);
|
|
1701
1876
|
} else {
|
|
1702
1877
|
if (transmuxer) {
|
|
@@ -1708,11 +1883,78 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1708
1883
|
}
|
|
1709
1884
|
|
|
1710
1885
|
/**
|
|
1711
|
-
*
|
|
1712
|
-
*
|
|
1886
|
+
* Returns true if it's necessary codec switch to load the new stream.
|
|
1887
|
+
*
|
|
1888
|
+
* @param {shaka.util.ManifestParserUtils.ContentType} contentType
|
|
1889
|
+
* @param {shaka.extern.Stream} stream
|
|
1890
|
+
* @return {boolean}
|
|
1891
|
+
* @private
|
|
1892
|
+
*/
|
|
1893
|
+
isCodecSwitchNecessary_(contentType, stream) {
|
|
1894
|
+
if (contentType == shaka.util.ManifestParserUtils.ContentType.TEXT) {
|
|
1895
|
+
return false;
|
|
1896
|
+
}
|
|
1897
|
+
const MimeUtils = shaka.util.MimeUtils;
|
|
1898
|
+
const currentCodec = MimeUtils.getCodecBase(
|
|
1899
|
+
MimeUtils.getCodecs(this.sourceBufferTypes_[contentType]));
|
|
1900
|
+
const currentBasicType = MimeUtils.getBasicType(
|
|
1901
|
+
this.sourceBufferTypes_[contentType]);
|
|
1902
|
+
|
|
1903
|
+
let newMimeType = shaka.util.MimeUtils.getFullType(
|
|
1904
|
+
stream.mimeType, stream.codecs);
|
|
1905
|
+
let needTransmux = this.config_.forceTransmux;
|
|
1906
|
+
if (!shaka.media.Capabilities.isTypeSupported(newMimeType) ||
|
|
1907
|
+
(!this.sequenceMode_ &&
|
|
1908
|
+
shaka.util.MimeUtils.RAW_FORMATS.includes(newMimeType))) {
|
|
1909
|
+
needTransmux = true;
|
|
1910
|
+
}
|
|
1911
|
+
const newMimeTypeWithAllCodecs =
|
|
1912
|
+
shaka.util.MimeUtils.getFullTypeWithAllCodecs(
|
|
1913
|
+
stream.mimeType, stream.codecs);
|
|
1914
|
+
const TransmuxerEngine = shaka.transmuxer.TransmuxerEngine;
|
|
1915
|
+
if (needTransmux) {
|
|
1916
|
+
const transmuxerPlugin =
|
|
1917
|
+
TransmuxerEngine.findTransmuxer(newMimeTypeWithAllCodecs);
|
|
1918
|
+
if (transmuxerPlugin) {
|
|
1919
|
+
const transmuxer = transmuxerPlugin();
|
|
1920
|
+
newMimeType =
|
|
1921
|
+
transmuxer.convertCodecs(contentType, newMimeTypeWithAllCodecs);
|
|
1922
|
+
transmuxer.destroy();
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
const newCodec = MimeUtils.getCodecBase(
|
|
1927
|
+
MimeUtils.getCodecs(newMimeType));
|
|
1928
|
+
const newBasicType = MimeUtils.getBasicType(newMimeType);
|
|
1929
|
+
|
|
1930
|
+
return currentCodec !== newCodec || currentBasicType !== newBasicType;
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1933
|
+
/**
|
|
1934
|
+
* Returns true if it's necessary reset the media source to load the
|
|
1935
|
+
* new stream.
|
|
1936
|
+
*
|
|
1937
|
+
* @param {shaka.util.ManifestParserUtils.ContentType} contentType
|
|
1938
|
+
* @param {shaka.extern.Stream} stream
|
|
1939
|
+
* @return {boolean}
|
|
1940
|
+
*/
|
|
1941
|
+
isResetMediaSourceNecessary(contentType, stream) {
|
|
1942
|
+
if (!this.isCodecSwitchNecessary_(contentType, stream)) {
|
|
1943
|
+
return false;
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
return this.config_.codecSwitchingStrategy !==
|
|
1947
|
+
shaka.config.CodecSwitchingStrategy.SMOOTH ||
|
|
1948
|
+
!shaka.media.Capabilities.isChangeTypeSupported() ||
|
|
1949
|
+
this.needSplitMuxedContent_;
|
|
1950
|
+
}
|
|
1951
|
+
|
|
1952
|
+
/**
|
|
1953
|
+
* Update LCEVC Decoder object when ready for LCEVC Decode.
|
|
1954
|
+
* @param {?shaka.lcevc.Dec} lcevcDec
|
|
1713
1955
|
*/
|
|
1714
|
-
|
|
1715
|
-
this.
|
|
1956
|
+
updateLcevcDec(lcevcDec) {
|
|
1957
|
+
this.lcevcDec_ = lcevcDec;
|
|
1716
1958
|
}
|
|
1717
1959
|
};
|
|
1718
1960
|
|