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
package/lib/hls/hls_utils.js
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
goog.provide('shaka.hls.Utils');
|
|
8
8
|
|
|
9
|
+
goog.require('shaka.log');
|
|
10
|
+
goog.require('shaka.util.Error');
|
|
9
11
|
goog.require('shaka.util.ManifestParserUtils');
|
|
10
12
|
goog.requireType('shaka.hls.Tag');
|
|
11
13
|
|
|
@@ -68,17 +70,74 @@ shaka.hls.Utils = class {
|
|
|
68
70
|
return value;
|
|
69
71
|
}
|
|
70
72
|
|
|
73
|
+
/**
|
|
74
|
+
* @param {!Array.<string>} baseUris
|
|
75
|
+
* @param {?string} relativeUri
|
|
76
|
+
* @param {?Map.<string, string>=} variables
|
|
77
|
+
* @return {!Array.<string>}
|
|
78
|
+
*/
|
|
79
|
+
static constructSegmentUris(baseUris, relativeUri, variables) {
|
|
80
|
+
if (!relativeUri) {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
return shaka.hls.Utils.constructUris(baseUris, [relativeUri], variables);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @param {!Array.<string>} baseUris
|
|
89
|
+
* @param {!Array.<string>} relativeUris
|
|
90
|
+
* @param {?Map.<string, string>=} variables
|
|
91
|
+
* @return {!Array.<string>}
|
|
92
|
+
*/
|
|
93
|
+
static constructUris(baseUris, relativeUris, variables) {
|
|
94
|
+
if (!relativeUris.length) {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
const resolvedUris = shaka.util.ManifestParserUtils.resolveUris(
|
|
98
|
+
baseUris, relativeUris);
|
|
99
|
+
|
|
100
|
+
const uris = [];
|
|
101
|
+
for (const uri of resolvedUris) {
|
|
102
|
+
uris.push(shaka.hls.Utils.variableSubstitution(uri, variables));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return uris;
|
|
106
|
+
}
|
|
71
107
|
|
|
72
108
|
/**
|
|
73
|
-
*
|
|
109
|
+
* Replaces the variables of a given URI.
|
|
110
|
+
*
|
|
74
111
|
* @param {string} uri
|
|
112
|
+
* @param {?Map.<string, string>=} variables
|
|
75
113
|
* @return {string}
|
|
76
114
|
*/
|
|
77
|
-
static
|
|
78
|
-
|
|
79
|
-
|
|
115
|
+
static variableSubstitution(uri, variables) {
|
|
116
|
+
if (!variables || !variables.size) {
|
|
117
|
+
return uri;
|
|
118
|
+
}
|
|
119
|
+
let newUri = String(uri).replace(/%7B/g, '{').replace(/%7D/g, '}');
|
|
80
120
|
|
|
81
|
-
|
|
121
|
+
const uriVariables = newUri.match(/{\$\w*}/g);
|
|
122
|
+
if (uriVariables) {
|
|
123
|
+
for (const variable of uriVariables) {
|
|
124
|
+
// Note: All variables have the structure {$...}
|
|
125
|
+
const variableName = variable.slice(2, variable.length - 1);
|
|
126
|
+
const replaceValue = variables.get(variableName);
|
|
127
|
+
if (replaceValue) {
|
|
128
|
+
newUri = newUri.replace(variable, replaceValue);
|
|
129
|
+
} else {
|
|
130
|
+
shaka.log.error('A variable has been found that is not declared',
|
|
131
|
+
variableName);
|
|
132
|
+
throw new shaka.util.Error(
|
|
133
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
134
|
+
shaka.util.Error.Category.MANIFEST,
|
|
135
|
+
shaka.util.Error.Code.HLS_VARIABLE_NOT_FOUND,
|
|
136
|
+
variableName);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return newUri;
|
|
82
141
|
}
|
|
83
142
|
|
|
84
143
|
|
|
@@ -29,10 +29,9 @@ shaka.hls.ManifestTextParser = class {
|
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* @param {BufferSource} data
|
|
32
|
-
* @param {string} absolutePlaylistUri An absolute, final URI after redirects.
|
|
33
32
|
* @return {!shaka.hls.Playlist}
|
|
34
33
|
*/
|
|
35
|
-
parsePlaylist(data
|
|
34
|
+
parsePlaylist(data) {
|
|
36
35
|
const MEDIA_PLAYLIST_TAGS =
|
|
37
36
|
shaka.hls.ManifestTextParser.MEDIA_PLAYLIST_TAGS;
|
|
38
37
|
const SEGMENT_TAGS = shaka.hls.ManifestTextParser.SEGMENT_TAGS;
|
|
@@ -101,10 +100,8 @@ shaka.hls.ManifestTextParser = class {
|
|
|
101
100
|
}
|
|
102
101
|
|
|
103
102
|
const segmentsData = lines.splice(i, lines.length - i);
|
|
104
|
-
const segments = this.parseSegments_(
|
|
105
|
-
|
|
106
|
-
return new shaka.hls.Playlist(
|
|
107
|
-
absolutePlaylistUri, playlistType, tags, segments);
|
|
103
|
+
const segments = this.parseSegments_(segmentsData, tags);
|
|
104
|
+
return new shaka.hls.Playlist(playlistType, tags, segments);
|
|
108
105
|
}
|
|
109
106
|
|
|
110
107
|
tags.push(tag);
|
|
@@ -118,19 +115,18 @@ shaka.hls.ManifestTextParser = class {
|
|
|
118
115
|
}
|
|
119
116
|
}
|
|
120
117
|
|
|
121
|
-
return new shaka.hls.Playlist(
|
|
118
|
+
return new shaka.hls.Playlist(playlistType, tags);
|
|
122
119
|
}
|
|
123
120
|
|
|
124
121
|
/**
|
|
125
122
|
* Parses an array of strings into an array of HLS Segment objects.
|
|
126
123
|
*
|
|
127
|
-
* @param {string} absoluteMediaPlaylistUri
|
|
128
124
|
* @param {!Array.<string>} lines
|
|
129
125
|
* @param {!Array.<!shaka.hls.Tag>} playlistTags
|
|
130
126
|
* @return {!Array.<shaka.hls.Segment>}
|
|
131
127
|
* @private
|
|
132
128
|
*/
|
|
133
|
-
parseSegments_(
|
|
129
|
+
parseSegments_(lines, playlistTags) {
|
|
134
130
|
/** @type {!Array.<shaka.hls.Segment>} */
|
|
135
131
|
const segments = [];
|
|
136
132
|
/** @type {!Array.<shaka.hls.Tag>} */
|
|
@@ -177,7 +173,7 @@ shaka.hls.ManifestTextParser = class {
|
|
|
177
173
|
segmentTags.push(currentMapTag);
|
|
178
174
|
}
|
|
179
175
|
// The URI appears after all of the tags describing the segment.
|
|
180
|
-
const segment = new shaka.hls.Segment(
|
|
176
|
+
const segment = new shaka.hls.Segment(
|
|
181
177
|
verbatimSegmentUri, segmentTags, partialSegmentTags);
|
|
182
178
|
segments.push(segment);
|
|
183
179
|
segmentTags = [];
|
|
@@ -193,7 +189,7 @@ shaka.hls.ManifestTextParser = class {
|
|
|
193
189
|
if (currentMapTag) {
|
|
194
190
|
segmentTags.push(currentMapTag);
|
|
195
191
|
}
|
|
196
|
-
const segment = new shaka.hls.Segment('',
|
|
192
|
+
const segment = new shaka.hls.Segment('', segmentTags,
|
|
197
193
|
partialSegmentTags);
|
|
198
194
|
segments.push(segment);
|
|
199
195
|
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
goog.provide('shaka.lcevc.Dec');
|
|
8
|
+
goog.require('shaka.log');
|
|
9
|
+
goog.require('shaka.Deprecate');
|
|
10
|
+
goog.require('shaka.util.IReleasable');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @summary
|
|
14
|
+
* lcevcDec - (MPEG-5 Part 2 LCEVC - Decoder) provides
|
|
15
|
+
* all the operations related to the enhancement and rendering
|
|
16
|
+
* of LCEVC enabled streams and on to a canvas.
|
|
17
|
+
* @implements {shaka.util.IReleasable}
|
|
18
|
+
* @export
|
|
19
|
+
*/
|
|
20
|
+
shaka.lcevc.Dec = class {
|
|
21
|
+
/**
|
|
22
|
+
* @param {HTMLVideoElement} media The video element that will be attached to
|
|
23
|
+
* LCEVC Decoder for input.
|
|
24
|
+
* @param {HTMLCanvasElement} canvas The canvas element that will be attached
|
|
25
|
+
* to LCEVC Decoder to render the enhanced frames.
|
|
26
|
+
* @param {shaka.extern.LcevcConfiguration} lcevcConfig LCEVC configuration
|
|
27
|
+
* object to initialize the LCEVC Decoder.
|
|
28
|
+
*/
|
|
29
|
+
constructor(media, canvas, lcevcConfig) {
|
|
30
|
+
/**
|
|
31
|
+
* LCEVC Decoder library based on availability, to check if either
|
|
32
|
+
* lcevc_dil or lcevc_dec is present.
|
|
33
|
+
* @private {LCEVCmodule}
|
|
34
|
+
*/
|
|
35
|
+
this.lcevcLib_;
|
|
36
|
+
|
|
37
|
+
/** @private {?LCEVCdec.LCEVCdec} */
|
|
38
|
+
this.dec_ = null;
|
|
39
|
+
|
|
40
|
+
/** @private {number} */
|
|
41
|
+
this.variantId_ = -1;
|
|
42
|
+
|
|
43
|
+
/** @private {HTMLVideoElement} */
|
|
44
|
+
this.media_ = media;
|
|
45
|
+
|
|
46
|
+
/** @private {HTMLCanvasElement} */
|
|
47
|
+
this.canvas_ = canvas;
|
|
48
|
+
|
|
49
|
+
/** @private {shaka.extern.LcevcConfiguration} */
|
|
50
|
+
this.decConfig_ = lcevcConfig;
|
|
51
|
+
|
|
52
|
+
/** @private {boolean} */
|
|
53
|
+
this.toBeDeprecated_ = false;
|
|
54
|
+
|
|
55
|
+
this.create_();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Append data to the LCEVC Dec.
|
|
60
|
+
* @param {BufferSource} data
|
|
61
|
+
* @param {number} timestampOffset
|
|
62
|
+
*/
|
|
63
|
+
appendBuffer(data, timestampOffset) {
|
|
64
|
+
if (this.dec_) {
|
|
65
|
+
// Timestamp offset describes how much offset should be applied to the
|
|
66
|
+
// LCEVC enhancement to match the decoded video frame, as such it needs
|
|
67
|
+
// to be negated.
|
|
68
|
+
this.dec_.appendBuffer(data, 'video', this.variantId_, -timestampOffset);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Hide the canvas specifically in the case of a DRM Content
|
|
74
|
+
*/
|
|
75
|
+
hideCanvas() {
|
|
76
|
+
if (this.dec_) {
|
|
77
|
+
this.canvas_.classList.add('shaka-hidden');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Create LCEVC Decoder.
|
|
83
|
+
* @private
|
|
84
|
+
*/
|
|
85
|
+
create_() {
|
|
86
|
+
if (this.isSupported_() && !this.dec_) {
|
|
87
|
+
if (this.lcevcLib_.SupportObject.webGLSupport(this.canvas_)) {
|
|
88
|
+
// Make sure the canvas is not hidden from a previous playback session.
|
|
89
|
+
this.canvas_.classList.remove('shaka-hidden');
|
|
90
|
+
// Initiate LCEVC Dec Library based on the type of module available.
|
|
91
|
+
if (this.toBeDeprecated_) {
|
|
92
|
+
this.dec_ = new this.lcevcLib_.LcevcDil(
|
|
93
|
+
this.media_,
|
|
94
|
+
this.canvas_,
|
|
95
|
+
this.decConfig_);
|
|
96
|
+
} else {
|
|
97
|
+
this.dec_ = new this.lcevcLib_.LCEVCdec(
|
|
98
|
+
this.media_,
|
|
99
|
+
this.canvas_,
|
|
100
|
+
this.decConfig_);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Close LCEVC Decoder.
|
|
108
|
+
* @override
|
|
109
|
+
* @export
|
|
110
|
+
*/
|
|
111
|
+
release() {
|
|
112
|
+
if (this.dec_) {
|
|
113
|
+
this.dec_.close();
|
|
114
|
+
this.dec_ = null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Check if the LCEVC Decoder lib is present and is supported by the browser.
|
|
120
|
+
* @return {boolean}
|
|
121
|
+
* @private
|
|
122
|
+
*/
|
|
123
|
+
isSupported_() {
|
|
124
|
+
if (typeof libDPIModule === 'undefined') {
|
|
125
|
+
shaka.log.alwaysWarn(
|
|
126
|
+
'Could not find LCEVC Library dependencies on this page');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// This is a check to make the LCEVC Dec Integration is backwards compatible
|
|
130
|
+
// with previous Integration. This logic checks for both implementations
|
|
131
|
+
// and uses the one available.
|
|
132
|
+
if (typeof LCEVCdec !== 'undefined') {
|
|
133
|
+
this.lcevcLib_ = LCEVCdec;
|
|
134
|
+
} else {
|
|
135
|
+
if (typeof LcevcDil !== 'undefined') {
|
|
136
|
+
this.lcevcLib_ = LcevcDil;
|
|
137
|
+
this.toBeDeprecated_ = true;
|
|
138
|
+
shaka.Deprecate.deprecateFeature(5,
|
|
139
|
+
'LcevcDil',
|
|
140
|
+
'lcevc_dil.js is deprecated, please use lcevc_dec.js instead');
|
|
141
|
+
} else {
|
|
142
|
+
shaka.log.alwaysWarn('Could not find LCEVC Library on this page');
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Making Sure if there is a valid LCEVC Dec Library exists.
|
|
148
|
+
if (typeof this.lcevcLib_.SupportObject === 'undefined') {
|
|
149
|
+
shaka.log.alwaysWarn('Could not find LCEVC Library on this page');
|
|
150
|
+
return false;
|
|
151
|
+
} else {
|
|
152
|
+
if (!this.lcevcLib_.SupportObject.SupportStatus) {
|
|
153
|
+
shaka.log.alwaysWarn(this.lcevcLib_.SupportObject.SupportError);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return typeof this.lcevcLib_ !== 'undefined' &&
|
|
158
|
+
typeof libDPIModule !== 'undefined' &&
|
|
159
|
+
this.canvas_ instanceof HTMLCanvasElement &&
|
|
160
|
+
this.lcevcLib_.SupportObject.SupportStatus;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Update current active variant
|
|
165
|
+
* @param {shaka.extern.Track} track
|
|
166
|
+
*/
|
|
167
|
+
updateVariant(track, manifestType) {
|
|
168
|
+
let containerFormat = shaka.lcevc.Dec.ContainerFormat.MPEG2_TS;
|
|
169
|
+
let streamingFormat = shaka.lcevc.Dec.StreamingFormat.OTHER;
|
|
170
|
+
switch (track.mimeType) {
|
|
171
|
+
case 'video/webm': {
|
|
172
|
+
containerFormat = shaka.lcevc.Dec.ContainerFormat.WEBM;
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
case 'video/mp4': {
|
|
176
|
+
containerFormat = shaka.lcevc.Dec.ContainerFormat.MP4;
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
switch (manifestType) {
|
|
181
|
+
case 'DASH': {
|
|
182
|
+
streamingFormat = shaka.lcevc.Dec.StreamingFormat.DASH;
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
case 'HLS': {
|
|
186
|
+
streamingFormat = shaka.lcevc.Dec.StreamingFormat.HLS;
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (this.dec_) {
|
|
191
|
+
this.variantId_ = track.id;
|
|
192
|
+
this.dec_.setLevelSwitching(track.id, true);
|
|
193
|
+
this.dec_.setContainerFormat(containerFormat);
|
|
194
|
+
// This functionality is only available on the LCEVC Dec Library.
|
|
195
|
+
if (!this.toBeDeprecated_) {
|
|
196
|
+
this.dec_.setStreamingFormat(streamingFormat);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Container Formats.
|
|
204
|
+
* @const @enum {number}
|
|
205
|
+
*/
|
|
206
|
+
shaka.lcevc.Dec.ContainerFormat = {
|
|
207
|
+
MPEG2_TS: 0,
|
|
208
|
+
WEBM: 1,
|
|
209
|
+
MP4: 2,
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Streaming Formats.
|
|
214
|
+
* @const @enum {number}
|
|
215
|
+
*/
|
|
216
|
+
shaka.lcevc.Dec.StreamingFormat = {
|
|
217
|
+
HLS: 0,
|
|
218
|
+
DASH: 1,
|
|
219
|
+
OTHER: -1,
|
|
220
|
+
};
|
|
@@ -26,8 +26,11 @@ shaka.media.AdaptationSet = class {
|
|
|
26
26
|
* Variants that may be compatible with the root and should be added if
|
|
27
27
|
* compatible. If a candidate is not compatible, it will not end up in the
|
|
28
28
|
* adaptation set.
|
|
29
|
+
* @param {boolean=} compareCodecs
|
|
30
|
+
* @param {boolean=} enableAudioGroups
|
|
29
31
|
*/
|
|
30
|
-
constructor(root, candidates
|
|
32
|
+
constructor(root, candidates, compareCodecs = true,
|
|
33
|
+
enableAudioGroups = false) {
|
|
31
34
|
/** @private {shaka.extern.Variant} */
|
|
32
35
|
this.root_ = root;
|
|
33
36
|
/** @private {!Set.<shaka.extern.Variant>} */
|
|
@@ -37,16 +40,18 @@ shaka.media.AdaptationSet = class {
|
|
|
37
40
|
// are not compatible with the root, they will be rejected by |add|.
|
|
38
41
|
candidates = candidates || [];
|
|
39
42
|
for (const candidate of candidates) {
|
|
40
|
-
this.add(candidate);
|
|
43
|
+
this.add(candidate, compareCodecs, enableAudioGroups);
|
|
41
44
|
}
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
/**
|
|
45
48
|
* @param {shaka.extern.Variant} variant
|
|
49
|
+
* @param {boolean} compareCodecs
|
|
50
|
+
* @param {boolean} enableAudioGroups
|
|
46
51
|
* @return {boolean}
|
|
47
52
|
*/
|
|
48
|
-
add(variant) {
|
|
49
|
-
if (this.canInclude(variant)) {
|
|
53
|
+
add(variant, compareCodecs, enableAudioGroups) {
|
|
54
|
+
if (this.canInclude(variant, compareCodecs, enableAudioGroups)) {
|
|
50
55
|
this.variants_.add(variant);
|
|
51
56
|
return true;
|
|
52
57
|
}
|
|
@@ -62,18 +67,23 @@ shaka.media.AdaptationSet = class {
|
|
|
62
67
|
* |false|, calling |add| will result in it being ignored.
|
|
63
68
|
*
|
|
64
69
|
* @param {shaka.extern.Variant} variant
|
|
70
|
+
* @param {boolean=} compareCodecs
|
|
71
|
+
* @param {boolean=} enableAudioGroups
|
|
65
72
|
* @return {boolean}
|
|
66
73
|
*/
|
|
67
|
-
canInclude(variant) {
|
|
68
|
-
return shaka.media.AdaptationSet
|
|
74
|
+
canInclude(variant, compareCodecs = true, enableAudioGroups = false) {
|
|
75
|
+
return shaka.media.AdaptationSet
|
|
76
|
+
.areAdaptable(this.root_, variant, compareCodecs, enableAudioGroups);
|
|
69
77
|
}
|
|
70
78
|
|
|
71
79
|
/**
|
|
72
80
|
* @param {shaka.extern.Variant} a
|
|
73
81
|
* @param {shaka.extern.Variant} b
|
|
82
|
+
* @param {boolean} compareCodecs
|
|
83
|
+
* @param {boolean} enableAudioGroups
|
|
74
84
|
* @return {boolean}
|
|
75
85
|
*/
|
|
76
|
-
static areAdaptable(a, b) {
|
|
86
|
+
static areAdaptable(a, b, compareCodecs, enableAudioGroups) {
|
|
77
87
|
const AdaptationSet = shaka.media.AdaptationSet;
|
|
78
88
|
|
|
79
89
|
// All variants should have audio or should all not have audio.
|
|
@@ -94,8 +104,8 @@ shaka.media.AdaptationSet = class {
|
|
|
94
104
|
goog.asserts.assert(
|
|
95
105
|
!!a.audio == !!b.audio,
|
|
96
106
|
'Both should either have audio or not have audio.');
|
|
97
|
-
if (a.audio && b.audio &&
|
|
98
|
-
|
|
107
|
+
if (a.audio && b.audio && !AdaptationSet.areAudiosCompatible_(
|
|
108
|
+
a.audio, b.audio, compareCodecs, enableAudioGroups)) {
|
|
99
109
|
return false;
|
|
100
110
|
}
|
|
101
111
|
|
|
@@ -103,7 +113,7 @@ shaka.media.AdaptationSet = class {
|
|
|
103
113
|
!!a.video == !!b.video,
|
|
104
114
|
'Both should either have video or not have video.');
|
|
105
115
|
if (a.video && b.video &&
|
|
106
|
-
!AdaptationSet.areVideosCompatible_(a.video, b.video)) {
|
|
116
|
+
!AdaptationSet.areVideosCompatible_(a.video, b.video, compareCodecs)) {
|
|
107
117
|
return false;
|
|
108
118
|
}
|
|
109
119
|
|
|
@@ -122,10 +132,12 @@ shaka.media.AdaptationSet = class {
|
|
|
122
132
|
*
|
|
123
133
|
* @param {shaka.extern.Stream} a
|
|
124
134
|
* @param {shaka.extern.Stream} b
|
|
135
|
+
* @param {boolean} compareCodecs
|
|
136
|
+
* @param {boolean} enableAudioGroups
|
|
125
137
|
* @return {boolean}
|
|
126
138
|
* @private
|
|
127
139
|
*/
|
|
128
|
-
static areAudiosCompatible_(a, b) {
|
|
140
|
+
static areAudiosCompatible_(a, b, compareCodecs, enableAudioGroups) {
|
|
129
141
|
const AdaptationSet = shaka.media.AdaptationSet;
|
|
130
142
|
|
|
131
143
|
// Don't adapt between channel counts, which could annoy the user
|
|
@@ -139,7 +151,7 @@ shaka.media.AdaptationSet = class {
|
|
|
139
151
|
}
|
|
140
152
|
|
|
141
153
|
// We can only adapt between base-codecs.
|
|
142
|
-
if (!AdaptationSet.canTransitionBetween_(a, b)) {
|
|
154
|
+
if (compareCodecs && !AdaptationSet.canTransitionBetween_(a, b)) {
|
|
143
155
|
return false;
|
|
144
156
|
}
|
|
145
157
|
|
|
@@ -148,6 +160,11 @@ shaka.media.AdaptationSet = class {
|
|
|
148
160
|
return false;
|
|
149
161
|
}
|
|
150
162
|
|
|
163
|
+
// We can only adapt between the same groupId.
|
|
164
|
+
if (enableAudioGroups && a.groupId !== b.groupId) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
|
|
151
168
|
return true;
|
|
152
169
|
}
|
|
153
170
|
|
|
@@ -156,14 +173,15 @@ shaka.media.AdaptationSet = class {
|
|
|
156
173
|
*
|
|
157
174
|
* @param {shaka.extern.Stream} a
|
|
158
175
|
* @param {shaka.extern.Stream} b
|
|
176
|
+
* @param {boolean} compareCodecs
|
|
159
177
|
* @return {boolean}
|
|
160
178
|
* @private
|
|
161
179
|
*/
|
|
162
|
-
static areVideosCompatible_(a, b) {
|
|
180
|
+
static areVideosCompatible_(a, b, compareCodecs) {
|
|
163
181
|
const AdaptationSet = shaka.media.AdaptationSet;
|
|
164
182
|
|
|
165
183
|
// We can only adapt between base-codecs.
|
|
166
|
-
if (!AdaptationSet.canTransitionBetween_(a, b)) {
|
|
184
|
+
if (compareCodecs && !AdaptationSet.canTransitionBetween_(a, b)) {
|
|
167
185
|
return false;
|
|
168
186
|
}
|
|
169
187
|
|