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
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
goog.provide('shaka.media.SegmentUtils');
|
|
8
|
+
|
|
9
|
+
goog.require('goog.asserts');
|
|
10
|
+
goog.require('shaka.log');
|
|
11
|
+
goog.require('shaka.media.ClosedCaptionParser');
|
|
12
|
+
goog.require('shaka.util.BufferUtils');
|
|
13
|
+
goog.require('shaka.util.MimeUtils');
|
|
14
|
+
goog.require('shaka.util.Mp4BoxParsers');
|
|
15
|
+
goog.require('shaka.util.Mp4Parser');
|
|
16
|
+
goog.require('shaka.util.TsParser');
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @summary Utility functions for segment parsing.
|
|
21
|
+
*/
|
|
22
|
+
shaka.media.SegmentUtils = class {
|
|
23
|
+
/**
|
|
24
|
+
* @param {string} mimeType
|
|
25
|
+
* @return {shaka.media.SegmentUtils.BasicInfo}
|
|
26
|
+
*/
|
|
27
|
+
static getBasicInfoFromMimeType(mimeType) {
|
|
28
|
+
const baseMimeType = shaka.util.MimeUtils.getBasicType(mimeType);
|
|
29
|
+
const type = baseMimeType.split('/')[0];
|
|
30
|
+
const codecs = shaka.util.MimeUtils.getCodecs(mimeType);
|
|
31
|
+
return {
|
|
32
|
+
type: type,
|
|
33
|
+
mimeType: baseMimeType,
|
|
34
|
+
codecs: codecs,
|
|
35
|
+
language: null,
|
|
36
|
+
height: null,
|
|
37
|
+
width: null,
|
|
38
|
+
channelCount: null,
|
|
39
|
+
sampleRate: null,
|
|
40
|
+
closedCaptions: new Map(),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @param {!BufferSource} data
|
|
46
|
+
* @return {?shaka.media.SegmentUtils.BasicInfo}
|
|
47
|
+
*/
|
|
48
|
+
static getBasicInfoFromTs(data) {
|
|
49
|
+
const uint8ArrayData = shaka.util.BufferUtils.toUint8(data);
|
|
50
|
+
const tsParser = new shaka.util.TsParser().parse(uint8ArrayData);
|
|
51
|
+
const tsCodecs = tsParser.getCodecs();
|
|
52
|
+
const videoInfo = tsParser.getVideoInfo();
|
|
53
|
+
const codecs = [];
|
|
54
|
+
let hasAudio = false;
|
|
55
|
+
let hasVideo = false;
|
|
56
|
+
switch (tsCodecs.audio) {
|
|
57
|
+
case 'aac':
|
|
58
|
+
codecs.push('mp4a.40.2');
|
|
59
|
+
hasAudio = true;
|
|
60
|
+
break;
|
|
61
|
+
case 'mp3':
|
|
62
|
+
codecs.push('mp4a.40.34');
|
|
63
|
+
hasAudio = true;
|
|
64
|
+
break;
|
|
65
|
+
case 'ac3':
|
|
66
|
+
codecs.push('ac-3');
|
|
67
|
+
hasAudio = true;
|
|
68
|
+
break;
|
|
69
|
+
case 'ec3':
|
|
70
|
+
codecs.push('ec-3');
|
|
71
|
+
hasAudio = true;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
switch (tsCodecs.video) {
|
|
75
|
+
case 'avc':
|
|
76
|
+
if (videoInfo.codec) {
|
|
77
|
+
codecs.push(videoInfo.codec);
|
|
78
|
+
} else {
|
|
79
|
+
codecs.push('avc1.42E01E');
|
|
80
|
+
}
|
|
81
|
+
hasVideo = true;
|
|
82
|
+
break;
|
|
83
|
+
case 'hvc':
|
|
84
|
+
if (videoInfo.codec) {
|
|
85
|
+
codecs.push(videoInfo.codec);
|
|
86
|
+
} else {
|
|
87
|
+
codecs.push('hvc1.1.6.L93.90');
|
|
88
|
+
}
|
|
89
|
+
hasVideo = true;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
if (!codecs.length) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const onlyAudio = hasAudio && !hasVideo;
|
|
96
|
+
const closedCaptions = new Map();
|
|
97
|
+
if (hasVideo) {
|
|
98
|
+
const captionParser = new shaka.media.ClosedCaptionParser('video/mp2t');
|
|
99
|
+
captionParser.parseFrom(data);
|
|
100
|
+
for (const stream of captionParser.getStreams()) {
|
|
101
|
+
closedCaptions.set(stream, stream);
|
|
102
|
+
}
|
|
103
|
+
captionParser.reset();
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
type: onlyAudio ? 'audio' : 'video',
|
|
107
|
+
mimeType: 'video/mp2t',
|
|
108
|
+
codecs: codecs.join(', '),
|
|
109
|
+
language: null,
|
|
110
|
+
height: videoInfo.height,
|
|
111
|
+
width: videoInfo.width,
|
|
112
|
+
channelCount: null,
|
|
113
|
+
sampleRate: null,
|
|
114
|
+
closedCaptions: closedCaptions,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @param {?BufferSource} initData
|
|
120
|
+
* @param {!BufferSource} data
|
|
121
|
+
* @return {?shaka.media.SegmentUtils.BasicInfo}
|
|
122
|
+
*/
|
|
123
|
+
static getBasicInfoFromMp4(initData, data) {
|
|
124
|
+
const Mp4Parser = shaka.util.Mp4Parser;
|
|
125
|
+
const SegmentUtils = shaka.media.SegmentUtils;
|
|
126
|
+
|
|
127
|
+
const codecs = [];
|
|
128
|
+
|
|
129
|
+
let hasAudio = false;
|
|
130
|
+
let hasVideo = false;
|
|
131
|
+
|
|
132
|
+
const addCodec = (codec) => {
|
|
133
|
+
const codecLC = codec.toLowerCase();
|
|
134
|
+
switch (codecLC) {
|
|
135
|
+
case 'avc1':
|
|
136
|
+
case 'avc3':
|
|
137
|
+
codecs.push(codecLC + '.42E01E');
|
|
138
|
+
hasVideo = true;
|
|
139
|
+
break;
|
|
140
|
+
case 'hev1':
|
|
141
|
+
case 'hvc1':
|
|
142
|
+
codecs.push(codecLC + '.1.6.L93.90');
|
|
143
|
+
hasVideo = true;
|
|
144
|
+
break;
|
|
145
|
+
case 'dvh1':
|
|
146
|
+
case 'dvhe':
|
|
147
|
+
codecs.push(codecLC + '.05.04');
|
|
148
|
+
hasVideo = true;
|
|
149
|
+
break;
|
|
150
|
+
case 'vp09':
|
|
151
|
+
codecs.push(codecLC + '.00.10.08');
|
|
152
|
+
hasVideo = true;
|
|
153
|
+
break;
|
|
154
|
+
case 'av01':
|
|
155
|
+
codecs.push(codecLC + '.0.01M.08');
|
|
156
|
+
hasVideo = true;
|
|
157
|
+
break;
|
|
158
|
+
case 'mp4a':
|
|
159
|
+
// We assume AAC, but this can be wrong since mp4a supports
|
|
160
|
+
// others codecs
|
|
161
|
+
codecs.push('mp4a.40.2');
|
|
162
|
+
hasAudio = true;
|
|
163
|
+
break;
|
|
164
|
+
case 'ac-3':
|
|
165
|
+
case 'ec-3':
|
|
166
|
+
case 'opus':
|
|
167
|
+
case 'flac':
|
|
168
|
+
codecs.push(codecLC);
|
|
169
|
+
hasAudio = true;
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const codecBoxParser = (box) => addCodec(box.name);
|
|
175
|
+
|
|
176
|
+
/** @type {?string} */
|
|
177
|
+
let language = null;
|
|
178
|
+
/** @type {?string} */
|
|
179
|
+
let height = null;
|
|
180
|
+
/** @type {?string} */
|
|
181
|
+
let width = null;
|
|
182
|
+
/** @type {?number} */
|
|
183
|
+
let channelCount = null;
|
|
184
|
+
/** @type {?number} */
|
|
185
|
+
let sampleRate = null;
|
|
186
|
+
|
|
187
|
+
new Mp4Parser()
|
|
188
|
+
.box('moov', Mp4Parser.children)
|
|
189
|
+
.box('trak', Mp4Parser.children)
|
|
190
|
+
.fullBox('tkhd', (box) => {
|
|
191
|
+
goog.asserts.assert(
|
|
192
|
+
box.version != null,
|
|
193
|
+
'TKHD is a full box and should have a valid version.');
|
|
194
|
+
const parsedTKHDBox = shaka.util.Mp4BoxParsers.parseTKHD(
|
|
195
|
+
box.reader, box.version);
|
|
196
|
+
height = String(parsedTKHDBox.height);
|
|
197
|
+
width = String(parsedTKHDBox.width);
|
|
198
|
+
})
|
|
199
|
+
.box('mdia', Mp4Parser.children)
|
|
200
|
+
.fullBox('mdhd', (box) => {
|
|
201
|
+
goog.asserts.assert(
|
|
202
|
+
box.version != null,
|
|
203
|
+
'MDHD is a full box and should have a valid version.');
|
|
204
|
+
const parsedMDHDBox = shaka.util.Mp4BoxParsers.parseMDHD(
|
|
205
|
+
box.reader, box.version);
|
|
206
|
+
language = parsedMDHDBox.language;
|
|
207
|
+
})
|
|
208
|
+
.box('minf', Mp4Parser.children)
|
|
209
|
+
.box('stbl', Mp4Parser.children)
|
|
210
|
+
.fullBox('stsd', Mp4Parser.sampleDescription)
|
|
211
|
+
|
|
212
|
+
// AUDIO
|
|
213
|
+
// These are the various boxes that signal a codec.
|
|
214
|
+
.box('mp4a', (box) => {
|
|
215
|
+
const parsedMP4ABox = shaka.util.Mp4BoxParsers.parseMP4A(box.reader);
|
|
216
|
+
channelCount = parsedMP4ABox.channelCount;
|
|
217
|
+
sampleRate = parsedMP4ABox.sampleRate;
|
|
218
|
+
if (box.reader.hasMoreData()) {
|
|
219
|
+
Mp4Parser.children(box);
|
|
220
|
+
} else {
|
|
221
|
+
codecBoxParser(box);
|
|
222
|
+
}
|
|
223
|
+
})
|
|
224
|
+
.box('esds', (box) => {
|
|
225
|
+
const parsedESDSBox = shaka.util.Mp4BoxParsers.parseESDS(box.reader);
|
|
226
|
+
codecs.push(parsedESDSBox.codec);
|
|
227
|
+
hasAudio = true;
|
|
228
|
+
})
|
|
229
|
+
.box('ac-3', codecBoxParser)
|
|
230
|
+
.box('ec-3', codecBoxParser)
|
|
231
|
+
.box('opus', codecBoxParser)
|
|
232
|
+
.box('Opus', codecBoxParser)
|
|
233
|
+
.box('fLaC', codecBoxParser)
|
|
234
|
+
|
|
235
|
+
// VIDEO
|
|
236
|
+
// These are the various boxes that signal a codec.
|
|
237
|
+
.box('avc1', (box) => {
|
|
238
|
+
const parsedAVCBox =
|
|
239
|
+
shaka.util.Mp4BoxParsers.parseAVC(box.reader, box.name);
|
|
240
|
+
codecs.push(parsedAVCBox.codec);
|
|
241
|
+
hasVideo = true;
|
|
242
|
+
})
|
|
243
|
+
.box('avc3', (box) => {
|
|
244
|
+
const parsedAVCBox =
|
|
245
|
+
shaka.util.Mp4BoxParsers.parseAVC(box.reader, box.name);
|
|
246
|
+
codecs.push(parsedAVCBox.codec);
|
|
247
|
+
hasVideo = true;
|
|
248
|
+
})
|
|
249
|
+
.box('hev1', codecBoxParser)
|
|
250
|
+
.box('hvc1', codecBoxParser)
|
|
251
|
+
.box('dvh1', codecBoxParser)
|
|
252
|
+
.box('dvhe', codecBoxParser)
|
|
253
|
+
.box('vp09', codecBoxParser)
|
|
254
|
+
.box('av01', codecBoxParser)
|
|
255
|
+
|
|
256
|
+
// This signals an encrypted sample, which we can go inside of to
|
|
257
|
+
// find the codec used.
|
|
258
|
+
// Note: If encrypted, you can only have audio or video, not both.
|
|
259
|
+
.box('enca', Mp4Parser.visualSampleEntry)
|
|
260
|
+
.box('encv', Mp4Parser.visualSampleEntry)
|
|
261
|
+
.box('sinf', Mp4Parser.children)
|
|
262
|
+
.box('frma', (box) => {
|
|
263
|
+
const {codec} = shaka.util.Mp4BoxParsers.parseFRMA(box.reader);
|
|
264
|
+
addCodec(codec);
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
.parse(initData || data, /* partialOkay= */ true);
|
|
268
|
+
if (!codecs.length) {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
const onlyAudio = hasAudio && !hasVideo;
|
|
272
|
+
const closedCaptions = new Map();
|
|
273
|
+
if (hasVideo) {
|
|
274
|
+
const captionParser = new shaka.media.ClosedCaptionParser('video/mp4');
|
|
275
|
+
if (initData) {
|
|
276
|
+
captionParser.init(initData);
|
|
277
|
+
}
|
|
278
|
+
captionParser.parseFrom(data);
|
|
279
|
+
for (const stream of captionParser.getStreams()) {
|
|
280
|
+
closedCaptions.set(stream, stream);
|
|
281
|
+
}
|
|
282
|
+
captionParser.reset();
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
type: onlyAudio ? 'audio' : 'video',
|
|
286
|
+
mimeType: onlyAudio ? 'audio/mp4' : 'video/mp4',
|
|
287
|
+
codecs: SegmentUtils.filterDuplicateCodecs_(codecs).join(', '),
|
|
288
|
+
language: language,
|
|
289
|
+
height: height,
|
|
290
|
+
width: width,
|
|
291
|
+
channelCount: channelCount,
|
|
292
|
+
sampleRate: sampleRate,
|
|
293
|
+
closedCaptions: closedCaptions,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* @param {!Array.<string>} codecs
|
|
299
|
+
* @return {!Array.<string>} codecs
|
|
300
|
+
* @private
|
|
301
|
+
*/
|
|
302
|
+
static filterDuplicateCodecs_(codecs) {
|
|
303
|
+
// Filter out duplicate codecs.
|
|
304
|
+
const seen = new Set();
|
|
305
|
+
const ret = [];
|
|
306
|
+
for (const codec of codecs) {
|
|
307
|
+
const shortCodec = shaka.util.MimeUtils.getCodecBase(codec);
|
|
308
|
+
if (!seen.has(shortCodec)) {
|
|
309
|
+
ret.push(codec);
|
|
310
|
+
seen.add(shortCodec);
|
|
311
|
+
} else {
|
|
312
|
+
shaka.log.debug('Ignoring duplicate codec');
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return ret;
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* @typedef {{
|
|
322
|
+
* type: string,
|
|
323
|
+
* mimeType: string,
|
|
324
|
+
* codecs: string,
|
|
325
|
+
* language: ?string,
|
|
326
|
+
* height: ?string,
|
|
327
|
+
* width: ?string,
|
|
328
|
+
* channelCount: ?number,
|
|
329
|
+
* sampleRate: ?number,
|
|
330
|
+
* closedCaptions: Map.<string, string>
|
|
331
|
+
* }}
|
|
332
|
+
*
|
|
333
|
+
* @property {string} type
|
|
334
|
+
* @property {string} mimeType
|
|
335
|
+
* @property {string} codecs
|
|
336
|
+
* @property {?string} language
|
|
337
|
+
* @property {?string} height
|
|
338
|
+
* @property {?string} width
|
|
339
|
+
* @property {?number} channelCount
|
|
340
|
+
* @property {?number} sampleRate
|
|
341
|
+
* @property {Map.<string, string>} closedCaptions
|
|
342
|
+
*/
|
|
343
|
+
shaka.media.SegmentUtils.BasicInfo;
|
|
@@ -174,9 +174,6 @@ shaka.media.StallDetector.MediaElementImplementation = class {
|
|
|
174
174
|
if (this.mediaElement_.paused) {
|
|
175
175
|
return false;
|
|
176
176
|
}
|
|
177
|
-
if (this.mediaElement_.playbackRate == 0) {
|
|
178
|
-
return false;
|
|
179
|
-
}
|
|
180
177
|
|
|
181
178
|
// If we have don't have enough content, we are not stalled, we are
|
|
182
179
|
// buffering.
|
|
@@ -1054,6 +1054,14 @@ shaka.media.StreamingEngine = class {
|
|
|
1054
1054
|
this.playerInterface_.mediaSourceEngine.clearSelectedClosedCaptionId();
|
|
1055
1055
|
}
|
|
1056
1056
|
|
|
1057
|
+
if (!this.playerInterface_.mediaSourceEngine.isStreamingAllowed() &&
|
|
1058
|
+
mediaState.type != ContentType.TEXT) {
|
|
1059
|
+
// It is not allowed to add segments yet, so we schedule an update to
|
|
1060
|
+
// check again later. So any prediction we make now could be terribly
|
|
1061
|
+
// invalid soon.
|
|
1062
|
+
return this.config_.updateIntervalSeconds / 2;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1057
1065
|
const logPrefix = shaka.media.StreamingEngine.logPrefix_(mediaState);
|
|
1058
1066
|
|
|
1059
1067
|
// Compute how far we've buffered ahead of the playhead.
|
|
@@ -1163,6 +1171,12 @@ shaka.media.StreamingEngine = class {
|
|
|
1163
1171
|
}
|
|
1164
1172
|
|
|
1165
1173
|
if (mediaState.segmentPrefetch && mediaState.segmentIterator) {
|
|
1174
|
+
const initSegmentReference = reference.initSegmentReference;
|
|
1175
|
+
if (initSegmentReference && (!mediaState.lastSegmentReference ||
|
|
1176
|
+
!shaka.media.InitSegmentReference.equal(
|
|
1177
|
+
initSegmentReference, mediaState.lastInitSegmentReference))) {
|
|
1178
|
+
mediaState.segmentPrefetch.prefetchInitSegment(initSegmentReference);
|
|
1179
|
+
}
|
|
1166
1180
|
mediaState.segmentPrefetch.prefetchSegments(reference);
|
|
1167
1181
|
}
|
|
1168
1182
|
|
|
@@ -1373,6 +1387,11 @@ shaka.media.StreamingEngine = class {
|
|
|
1373
1387
|
await this.append_(
|
|
1374
1388
|
mediaState, presentationTime, stream, reference, dataToAppend,
|
|
1375
1389
|
/* isChunkedData= */ true);
|
|
1390
|
+
|
|
1391
|
+
if (mediaState.segmentPrefetch && mediaState.segmentIterator) {
|
|
1392
|
+
mediaState.segmentPrefetch.prefetchSegments(
|
|
1393
|
+
reference, /* skipFirst= */ true);
|
|
1394
|
+
}
|
|
1376
1395
|
}
|
|
1377
1396
|
};
|
|
1378
1397
|
|
|
@@ -1403,6 +1422,11 @@ shaka.media.StreamingEngine = class {
|
|
|
1403
1422
|
await this.append_(
|
|
1404
1423
|
mediaState, presentationTime, stream, reference, result);
|
|
1405
1424
|
}
|
|
1425
|
+
|
|
1426
|
+
if (mediaState.segmentPrefetch && mediaState.segmentIterator) {
|
|
1427
|
+
mediaState.segmentPrefetch.prefetchSegments(
|
|
1428
|
+
reference, /* skipFirst= */ true);
|
|
1429
|
+
}
|
|
1406
1430
|
} else {
|
|
1407
1431
|
if (this.config_.lowLatencyMode && !isReadableStreamSupported) {
|
|
1408
1432
|
shaka.log.warning('Low latency streaming mode is enabled, but ' +
|
|
@@ -1498,12 +1522,12 @@ shaka.media.StreamingEngine = class {
|
|
|
1498
1522
|
|
|
1499
1523
|
/**
|
|
1500
1524
|
* @param {!BufferSource} rawResult
|
|
1501
|
-
* @param {shaka.extern.
|
|
1502
|
-
* @param {
|
|
1525
|
+
* @param {shaka.extern.aes128Key} aes128Key
|
|
1526
|
+
* @param {number} position
|
|
1503
1527
|
* @return {!Promise.<!BufferSource>} finalResult
|
|
1504
1528
|
* @private
|
|
1505
1529
|
*/
|
|
1506
|
-
async aes128Decrypt_(rawResult, aes128Key,
|
|
1530
|
+
async aes128Decrypt_(rawResult, aes128Key, position) {
|
|
1507
1531
|
const key = aes128Key;
|
|
1508
1532
|
if (!key.cryptoKey) {
|
|
1509
1533
|
goog.asserts.assert(key.fetchKey, 'If AES-128 cryptoKey was not ' +
|
|
@@ -1514,7 +1538,7 @@ shaka.media.StreamingEngine = class {
|
|
|
1514
1538
|
let iv = key.iv;
|
|
1515
1539
|
if (!iv) {
|
|
1516
1540
|
iv = shaka.util.BufferUtils.toUint8(new ArrayBuffer(16));
|
|
1517
|
-
let sequence = key.firstMediaSequenceNumber +
|
|
1541
|
+
let sequence = key.firstMediaSequenceNumber + position;
|
|
1518
1542
|
for (let i = iv.byteLength - 1; i >= 0; i--) {
|
|
1519
1543
|
iv[i] = sequence & 0xff;
|
|
1520
1544
|
sequence >>= 8;
|
|
@@ -1684,22 +1708,21 @@ shaka.media.StreamingEngine = class {
|
|
|
1684
1708
|
shaka.log.v1(logPrefix,
|
|
1685
1709
|
'setting append window end to ' + appendWindowEnd);
|
|
1686
1710
|
|
|
1687
|
-
|
|
1688
|
-
|
|
1711
|
+
const isResetMediaSourceNecessary =
|
|
1712
|
+
mediaState.lastCodecs && mediaState.lastMimeType &&
|
|
1713
|
+
this.playerInterface_.mediaSourceEngine.isResetMediaSourceNecessary(
|
|
1714
|
+
mediaState.type, mediaState.stream);
|
|
1715
|
+
if (isResetMediaSourceNecessary) {
|
|
1716
|
+
let otherState = null;
|
|
1689
1717
|
if (mediaState.type === ContentType.VIDEO) {
|
|
1690
|
-
|
|
1691
|
-
const audioState = this.mediaStates_.get(ContentType.AUDIO);
|
|
1692
|
-
if (audioState) {
|
|
1693
|
-
audioState.lastInitSegmentReference = null;
|
|
1694
|
-
this.abortOperations_(audioState);
|
|
1695
|
-
}
|
|
1718
|
+
otherState = this.mediaStates_.get(ContentType.AUDIO);
|
|
1696
1719
|
} else if (mediaState.type === ContentType.AUDIO) {
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
}
|
|
1720
|
+
otherState = this.mediaStates_.get(ContentType.VIDEO);
|
|
1721
|
+
}
|
|
1722
|
+
if (otherState) {
|
|
1723
|
+
otherState.lastInitSegmentReference = null;
|
|
1724
|
+
this.forceClearBuffer_(otherState);
|
|
1725
|
+
this.abortOperations_(otherState).catch(() => {});
|
|
1703
1726
|
}
|
|
1704
1727
|
}
|
|
1705
1728
|
|
|
@@ -1729,6 +1752,19 @@ shaka.media.StreamingEngine = class {
|
|
|
1729
1752
|
mediaState.type, timestampOffset, appendWindowStart,
|
|
1730
1753
|
appendWindowEnd, ignoreTimestampOffset,
|
|
1731
1754
|
mediaState.stream, streamsByType);
|
|
1755
|
+
if (isResetMediaSourceNecessary) {
|
|
1756
|
+
let otherState = null;
|
|
1757
|
+
if (mediaState.type === ContentType.VIDEO) {
|
|
1758
|
+
otherState = this.mediaStates_.get(ContentType.AUDIO);
|
|
1759
|
+
} else if (mediaState.type === ContentType.AUDIO) {
|
|
1760
|
+
otherState = this.mediaStates_.get(ContentType.VIDEO);
|
|
1761
|
+
}
|
|
1762
|
+
if (otherState) {
|
|
1763
|
+
otherState.waitingToClearBuffer = false;
|
|
1764
|
+
otherState.performingUpdate = false;
|
|
1765
|
+
this.forceClearBuffer_(otherState);
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1732
1768
|
} catch (error) {
|
|
1733
1769
|
mediaState.lastAppendWindowStart = null;
|
|
1734
1770
|
mediaState.lastAppendWindowEnd = null;
|
|
@@ -1738,7 +1774,10 @@ shaka.media.StreamingEngine = class {
|
|
|
1738
1774
|
throw error;
|
|
1739
1775
|
}
|
|
1740
1776
|
};
|
|
1741
|
-
|
|
1777
|
+
// Dispatching init asynchronously causes the sourceBuffers in
|
|
1778
|
+
// the MediaSourceEngine to become detached do to race conditions
|
|
1779
|
+
// with mediaSource and sourceBuffers being created simultaneously.
|
|
1780
|
+
await setProperties();
|
|
1742
1781
|
}
|
|
1743
1782
|
|
|
1744
1783
|
if (!shaka.media.InitSegmentReference.equal(
|
|
@@ -1749,8 +1788,7 @@ shaka.media.StreamingEngine = class {
|
|
|
1749
1788
|
shaka.log.v1(logPrefix, 'fetching init segment');
|
|
1750
1789
|
|
|
1751
1790
|
const fetchInit =
|
|
1752
|
-
this.fetch_(mediaState, reference.initSegmentReference
|
|
1753
|
-
/* streamDataCallback= */ undefined, /* isInit= */ true);
|
|
1791
|
+
this.fetch_(mediaState, reference.initSegmentReference);
|
|
1754
1792
|
const append = async () => {
|
|
1755
1793
|
try {
|
|
1756
1794
|
const initSegment = await fetchInit;
|
|
@@ -2154,13 +2192,12 @@ shaka.media.StreamingEngine = class {
|
|
|
2154
2192
|
* @param {(!shaka.media.InitSegmentReference|!shaka.media.SegmentReference)}
|
|
2155
2193
|
* reference
|
|
2156
2194
|
* @param {?function(BufferSource):!Promise=} streamDataCallback
|
|
2157
|
-
* @param {boolean=} isInit
|
|
2158
2195
|
*
|
|
2159
2196
|
* @return {!Promise.<BufferSource>}
|
|
2160
2197
|
* @private
|
|
2161
2198
|
* @suppress {strictMissingProperties}
|
|
2162
2199
|
*/
|
|
2163
|
-
async fetch_(mediaState, reference, streamDataCallback
|
|
2200
|
+
async fetch_(mediaState, reference, streamDataCallback) {
|
|
2164
2201
|
if (reference instanceof shaka.media.InitSegmentReference) {
|
|
2165
2202
|
const segmentData = reference.getSegmentData();
|
|
2166
2203
|
if (segmentData) {
|
|
@@ -2168,27 +2205,26 @@ shaka.media.StreamingEngine = class {
|
|
|
2168
2205
|
}
|
|
2169
2206
|
}
|
|
2170
2207
|
let op = null;
|
|
2171
|
-
if (
|
|
2172
|
-
mediaState.segmentPrefetch &&
|
|
2173
|
-
reference instanceof shaka.media.SegmentReference
|
|
2174
|
-
) {
|
|
2208
|
+
if (mediaState.segmentPrefetch) {
|
|
2175
2209
|
op = mediaState.segmentPrefetch.getPrefetchedSegment(
|
|
2176
2210
|
reference, streamDataCallback);
|
|
2177
2211
|
}
|
|
2178
2212
|
if (!op) {
|
|
2179
2213
|
op = this.dispatchFetch_(
|
|
2180
|
-
reference, mediaState.stream, streamDataCallback
|
|
2181
|
-
|
|
2214
|
+
reference, mediaState.stream, streamDataCallback);
|
|
2215
|
+
}
|
|
2216
|
+
|
|
2217
|
+
let position = 0;
|
|
2218
|
+
if (mediaState.segmentIterator) {
|
|
2219
|
+
position = mediaState.segmentIterator.currentPosition();
|
|
2182
2220
|
}
|
|
2183
2221
|
|
|
2184
2222
|
mediaState.operation = op;
|
|
2185
2223
|
const response = await op.promise;
|
|
2186
2224
|
mediaState.operation = null;
|
|
2187
2225
|
let result = response.data;
|
|
2188
|
-
if (reference.
|
|
2189
|
-
|
|
2190
|
-
goog.asserts.assert(iter, 'mediaState.segmentIterator should exist');
|
|
2191
|
-
result = await this.aes128Decrypt_(result, reference.hlsAes128Key, iter);
|
|
2226
|
+
if (reference.aes128Key) {
|
|
2227
|
+
result = await this.aes128Decrypt_(result, reference.aes128Key, position);
|
|
2192
2228
|
}
|
|
2193
2229
|
return result;
|
|
2194
2230
|
}
|
|
@@ -2200,18 +2236,17 @@ shaka.media.StreamingEngine = class {
|
|
|
2200
2236
|
* @param {(!shaka.media.InitSegmentReference|!shaka.media.SegmentReference)}
|
|
2201
2237
|
* reference
|
|
2202
2238
|
* @param {?function(BufferSource):!Promise=} streamDataCallback
|
|
2203
|
-
* @param {boolean=} isInit
|
|
2204
2239
|
*
|
|
2205
2240
|
* @return {!shaka.net.NetworkingEngine.PendingRequest}
|
|
2206
2241
|
* @private
|
|
2207
2242
|
*/
|
|
2208
|
-
dispatchFetch_(reference, stream, streamDataCallback
|
|
2243
|
+
dispatchFetch_(reference, stream, streamDataCallback) {
|
|
2209
2244
|
const requestType = shaka.net.NetworkingEngine.RequestType.SEGMENT;
|
|
2210
|
-
const type = isInit ?
|
|
2211
|
-
shaka.net.NetworkingEngine.AdvancedRequestType.INIT_SEGMENT :
|
|
2212
|
-
shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_SEGMENT;
|
|
2213
2245
|
const segment = reference instanceof shaka.media.SegmentReference ?
|
|
2214
2246
|
reference : undefined;
|
|
2247
|
+
const type = segment ?
|
|
2248
|
+
shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_SEGMENT :
|
|
2249
|
+
shaka.net.NetworkingEngine.AdvancedRequestType.INIT_SEGMENT;
|
|
2215
2250
|
const request = shaka.util.Networking.createSegmentRequest(
|
|
2216
2251
|
reference.getUris(),
|
|
2217
2252
|
reference.startByte,
|
package/lib/mss/mss_parser.js
CHANGED
|
@@ -213,6 +213,22 @@ shaka.mss.MssParser = class {
|
|
|
213
213
|
// No-op
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
+
/**
|
|
217
|
+
* @override
|
|
218
|
+
* @exportInterface
|
|
219
|
+
*/
|
|
220
|
+
onInitialVariantChosen(variant) {
|
|
221
|
+
// No-op
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* @override
|
|
226
|
+
* @exportInterface
|
|
227
|
+
*/
|
|
228
|
+
banLocation(uri) {
|
|
229
|
+
// No-op
|
|
230
|
+
}
|
|
231
|
+
|
|
216
232
|
/**
|
|
217
233
|
* Makes a network request for the manifest and parses the resulting data.
|
|
218
234
|
*
|
|
@@ -500,6 +516,7 @@ shaka.mss.MssParser = class {
|
|
|
500
516
|
const stream = {
|
|
501
517
|
id: id,
|
|
502
518
|
originalId: streamIndex.getAttribute('Name') || String(id),
|
|
519
|
+
groupId: null,
|
|
503
520
|
createSegmentIndex: () => Promise.resolve(),
|
|
504
521
|
closeSegmentIndex: () => Promise.resolve(),
|
|
505
522
|
segmentIndex: null,
|
|
@@ -528,6 +545,7 @@ shaka.mss.MssParser = class {
|
|
|
528
545
|
spatialAudio: false,
|
|
529
546
|
closedCaptions: null,
|
|
530
547
|
hdr: undefined,
|
|
548
|
+
videoLayout: undefined,
|
|
531
549
|
tilesLayout: undefined,
|
|
532
550
|
matchedStreams: [],
|
|
533
551
|
mssPrivateData: {
|
|
@@ -537,6 +555,7 @@ shaka.mss.MssParser = class {
|
|
|
537
555
|
},
|
|
538
556
|
accessibilityPurpose: null,
|
|
539
557
|
external: false,
|
|
558
|
+
fastSwitching: false,
|
|
540
559
|
};
|
|
541
560
|
|
|
542
561
|
// This is specifically for text tracks.
|
|
@@ -1076,7 +1095,5 @@ shaka.mss.MssParser.Context;
|
|
|
1076
1095
|
*/
|
|
1077
1096
|
shaka.mss.MssParser.TimeRange;
|
|
1078
1097
|
|
|
1079
|
-
shaka.media.ManifestParser.registerParserByExtension(
|
|
1080
|
-
'ism', () => new shaka.mss.MssParser());
|
|
1081
1098
|
shaka.media.ManifestParser.registerParserByMime(
|
|
1082
1099
|
'application/vnd.ms-sstr+xml', () => new shaka.mss.MssParser());
|