shaka-player 4.3.11 → 4.4.1
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/AUTHORS +9 -0
- package/CHANGELOG.md +303 -202
- package/CONTRIBUTORS +8 -0
- package/LICENSE +32 -0
- package/README.md +63 -10
- package/demo/autoTemplate.txt +40 -5
- package/demo/close_button.js +11 -0
- package/demo/common/asset.js +13 -1
- package/demo/common/assets.js +53 -3
- package/demo/common/message_ids.js +25 -1
- package/demo/config.js +69 -10
- package/demo/customWarning.txt +2 -2
- package/demo/index.html +3 -1
- package/demo/locales/en.json +26 -2
- package/demo/locales/source.json +105 -9
- package/demo/main.js +52 -9
- package/demo/search.js +3 -1
- package/demo/service_worker.js +3 -0
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +124 -112
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +124 -112
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +46 -28
- package/dist/locales.js +33 -33
- package/dist/receiver.compiled.debug.js +52 -46
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +52 -46
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +676 -391
- package/dist/shaka-player.compiled.debug.d.ts +676 -391
- package/dist/shaka-player.compiled.debug.externs.js +1188 -616
- package/dist/shaka-player.compiled.debug.js +1043 -699
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +1188 -616
- package/dist/shaka-player.compiled.js +1091 -929
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +677 -392
- package/dist/shaka-player.ui.debug.d.ts +677 -392
- package/dist/shaka-player.ui.debug.externs.js +1023 -451
- package/dist/shaka-player.ui.debug.js +1098 -737
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +1023 -451
- package/dist/shaka-player.ui.js +1246 -1071
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/ad_monetization.md +15 -1
- package/docs/tutorials/application-level-redirects.md +1 -1
- package/docs/tutorials/config.md +9 -5
- package/docs/tutorials/drm-config.md +61 -0
- package/docs/tutorials/fairplay.md +19 -4
- package/docs/tutorials/license-server-auth.md +4 -4
- package/docs/tutorials/license-wrapping.md +2 -2
- package/docs/tutorials/ui-customization.md +7 -3
- package/docs/tutorials/ui.md +7 -7
- package/docs/tutorials/upgrade.md +3 -0
- package/externs/ima.js +123 -2
- package/externs/isoboxer.js +217 -0
- package/externs/mediakeys.js +18 -0
- package/externs/mux.js +1 -105
- package/externs/pictureinpicture.js +48 -0
- package/externs/shaka/ads.js +61 -1
- package/externs/shaka/cea.js +110 -0
- package/externs/shaka/codecs.js +32 -0
- package/externs/shaka/manifest.js +101 -1
- package/externs/shaka/manifest_parser.js +0 -10
- package/externs/shaka/net.js +36 -7
- package/externs/shaka/offline.js +8 -1
- package/externs/shaka/player.js +220 -21
- package/externs/shaka/text.js +1 -382
- package/externs/shaka/transmuxer.js +60 -0
- package/karma.conf.js +13 -0
- package/lib/abr/simple_abr_manager.js +6 -3
- package/lib/ads/ad_manager.js +60 -2
- package/lib/ads/client_side_ad.js +86 -0
- package/lib/ads/client_side_ad_manager.js +79 -3
- package/lib/ads/server_side_ad.js +86 -0
- package/lib/ads/server_side_ad_manager.js +13 -0
- package/lib/cast/cast_utils.js +1 -0
- package/lib/cea/cea608_data_channel.js +24 -14
- package/lib/cea/cea608_memory.js +5 -2
- package/lib/cea/cea708_service.js +8 -9
- package/lib/cea/cea708_window.js +1 -2
- package/lib/cea/cea_decoder.js +23 -6
- package/lib/cea/cea_utils.js +25 -2
- package/lib/cea/dummy_caption_decoder.js +21 -0
- package/lib/cea/dummy_cea_parser.js +1 -3
- package/lib/cea/mp4_cea_parser.js +15 -10
- package/lib/cea/ts_cea_parser.js +69 -0
- package/lib/dash/content_protection.js +32 -2
- package/lib/dash/dash_parser.js +93 -31
- package/lib/dash/mpd_utils.js +6 -25
- package/lib/dash/segment_base.js +12 -14
- package/lib/dash/segment_list.js +10 -6
- package/lib/dash/segment_template.js +349 -32
- package/lib/dependencies/all.js +8 -0
- package/lib/hls/hls_classes.js +33 -8
- package/lib/hls/hls_parser.js +805 -191
- package/lib/hls/manifest_text_parser.js +4 -14
- package/lib/media/adaptation_set_criteria.js +43 -3
- package/lib/media/closed_caption_parser.js +74 -12
- package/lib/media/drm_engine.js +189 -49
- package/lib/media/gap_jumping_controller.js +1 -1
- package/lib/media/manifest_parser.js +34 -0
- package/lib/media/media_source_capabilities.js +10 -0
- package/lib/media/media_source_engine.js +495 -231
- package/lib/media/playhead.js +1 -1
- package/lib/media/presentation_timeline.js +62 -0
- package/lib/media/segment_index.js +50 -14
- package/lib/media/segment_prefetch.js +277 -0
- package/lib/media/segment_reference.js +70 -4
- package/lib/media/streaming_engine.js +258 -81
- package/lib/media/video_wrapper.js +15 -7
- package/lib/mss/content_protection.js +353 -0
- package/lib/mss/mss_parser.js +1082 -0
- package/lib/net/networking_engine.js +60 -10
- package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
- package/lib/offline/manifest_converter.js +6 -0
- package/lib/offline/storage.js +2 -4
- package/lib/player.js +309 -105
- package/lib/polyfill/media_capabilities.js +43 -3
- package/lib/polyfill/patchedmediakeys_apple.js +5 -0
- package/lib/polyfill/patchedmediakeys_nop.js +5 -0
- package/lib/polyfill/patchedmediakeys_webkit.js +5 -0
- package/lib/text/cue.js +208 -130
- package/lib/text/lrc_text_parser.js +2 -2
- package/lib/text/mp4_vtt_parser.js +2 -2
- package/lib/text/sbv_text_parser.js +1 -1
- package/lib/text/simple_text_displayer.js +1 -1
- package/lib/text/srt_text_parser.js +9 -1
- package/lib/text/ssa_text_parser.js +2 -2
- package/lib/text/text_engine.js +3 -21
- package/lib/text/text_utils.js +71 -20
- package/lib/text/ui_text_displayer.js +14 -14
- package/lib/text/vtt_text_parser.js +22 -14
- package/lib/transmuxer/aac_transmuxer.js +224 -0
- package/lib/transmuxer/ac3.js +142 -0
- package/lib/transmuxer/ac3_transmuxer.js +213 -0
- package/lib/transmuxer/adts.js +232 -0
- package/lib/transmuxer/ec3.js +103 -0
- package/lib/transmuxer/ec3_transmuxer.js +213 -0
- package/lib/transmuxer/h264.js +324 -0
- package/lib/transmuxer/mp3_transmuxer.js +205 -0
- package/lib/transmuxer/mpeg_audio.js +196 -0
- package/lib/transmuxer/mpeg_ts_transmuxer.js +182 -0
- package/lib/transmuxer/mss_transmuxer.js +389 -0
- package/lib/{media/transmuxer.js → transmuxer/muxjs_transmuxer.js} +34 -80
- package/lib/transmuxer/transmuxer_engine.js +161 -0
- package/lib/transmuxer/ts_transmuxer.js +721 -0
- package/lib/util/cmcd_manager.js +131 -71
- package/lib/util/error.js +62 -26
- package/lib/util/exp_golomb.js +220 -0
- package/lib/util/fairplay_utils.js +64 -13
- package/lib/util/id3_utils.js +56 -3
- package/lib/util/language_utils.js +11 -8
- package/lib/util/manifest_parser_utils.js +3 -0
- package/lib/util/mime_utils.js +44 -7
- package/lib/util/mp4_box_parsers.js +233 -5
- package/lib/util/mp4_generator.js +1388 -0
- package/lib/util/periods.js +40 -34
- package/lib/util/platform.js +17 -3
- package/lib/util/player_configuration.js +38 -1
- package/lib/util/stream_utils.js +138 -27
- package/lib/util/text_parser.js +1 -1
- package/lib/util/ts_parser.js +460 -74
- package/lib/util/xml_utils.js +16 -3
- package/maintained-branches.md +2 -2
- package/package.json +3 -1
- package/roadmap.md +21 -6
- package/shaka-player.uncompiled.js +18 -0
- package/test/abr/simple_abr_manager_unit.js +32 -4
- package/test/ads/ad_manager_unit.js +18 -2
- package/test/cast/cast_utils_unit.js +7 -2
- package/test/cea/cea608_memory_unit.js +24 -0
- package/test/cea/cea_decoder_unit.js +33 -0
- package/test/dash/dash_parser_content_protection_unit.js +93 -3
- package/test/dash/dash_parser_live_unit.js +56 -13
- package/test/dash/dash_parser_manifest_unit.js +70 -2
- package/test/dash/dash_parser_segment_base_unit.js +14 -9
- package/test/dash/dash_parser_segment_template_unit.js +286 -6
- package/test/demo/demo_unit.js +5 -1
- package/test/hls/hls_live_unit.js +188 -28
- package/test/hls/hls_parser_unit.js +250 -109
- package/test/hls/manifest_text_parser_unit.js +18 -13
- package/test/media/adaptation_set_criteria_unit.js +46 -14
- package/test/media/adaptation_set_unit.js +2 -0
- package/test/media/drm_engine_integration.js +11 -8
- package/test/media/drm_engine_unit.js +220 -7
- package/test/media/media_source_engine_integration.js +124 -40
- package/test/media/media_source_engine_unit.js +133 -153
- package/test/media/playhead_unit.js +3 -0
- package/test/media/presentation_timeline_unit.js +51 -0
- package/test/media/segment_index_unit.js +52 -0
- package/test/media/segment_prefetch_unit.js +243 -0
- package/test/media/streaming_engine_integration.js +9 -3
- package/test/media/streaming_engine_unit.js +440 -59
- package/test/mss/mss_parser_content_protection_unit.js +49 -0
- package/test/mss/mss_parser_unit.js +472 -0
- package/test/mss/mss_player_integration.js +123 -0
- package/test/offline/manifest_convert_unit.js +9 -0
- package/test/offline/storage_integration.js +6 -1
- package/test/player_unit.js +386 -133
- package/test/polyfill/media_capabilities_unit.js +18 -0
- package/test/test/assets/hls-raw-aac/fileSequence0.aac +0 -0
- package/test/test/assets/hls-raw-aac/fileSequence1.aac +0 -0
- package/test/test/assets/hls-raw-aac/fileSequence2.aac +0 -0
- package/test/test/assets/hls-raw-aac/fileSequence3.aac +0 -0
- package/test/test/assets/hls-raw-aac/manifest.m3u8 +4 -0
- package/test/test/assets/hls-raw-aac/stream.m4a.m3u8 +14 -0
- package/test/test/assets/hls-raw-ac3/fileSequence0.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence1.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence2.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence3.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence4.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence5.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence6.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/fileSequence7.ac3 +0 -0
- package/test/test/assets/hls-raw-ac3/prog_index.m3u8 +31 -0
- package/test/test/assets/hls-raw-ec3/fileSequence0.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence1.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence2.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence3.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence4.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence5.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence6.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/fileSequence7.ec3 +0 -0
- package/test/test/assets/hls-raw-ec3/prog_index.m3u8 +31 -0
- package/test/test/assets/hls-raw-mp3/chunklist_w905519204.m3u8 +13 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_0.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_1.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_2.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/media_w905519204_3.mp3 +0 -0
- package/test/test/assets/hls-raw-mp3/playlist.m3u8 +4 -0
- package/test/test/assets/hls-ts-aac/playlist.m3u8 +23 -0
- package/test/test/assets/hls-ts-aac/segment_0.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_1.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_2.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_3.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_4.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_5.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_6.ts +0 -0
- package/test/test/assets/hls-ts-aac/segment_7.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0000.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0001.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0002.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0003.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0004.ts +0 -0
- package/test/test/assets/hls-ts-ac3/ChID_voices_6ch_640kbps_dd_sub_0005.ts +0 -0
- package/test/test/assets/hls-ts-ac3/prog_index.m3u8 +19 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0000.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0001.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0002.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0003.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0004.ts +0 -0
- package/test/test/assets/hls-ts-ec3/ChID_voices_6ch_256kbps_ddp_sub_0005.ts +0 -0
- package/test/test/assets/hls-ts-ec3/prog_index.m3u8 +19 -0
- package/test/test/assets/hls-ts-h264/fileSequence0.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence1.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence2.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence3.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence4.ts +0 -0
- package/test/test/assets/hls-ts-h264/fileSequence5.ts +0 -0
- package/test/test/assets/hls-ts-h264/prog_index.m3u8 +25 -0
- package/test/test/assets/hls-ts-mp3/manifest.m3u8 +13 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_0.ts +0 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_1.ts +0 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_2.ts +0 -0
- package/test/test/assets/hls-ts-mp3/media_w239891843_3.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/chunk.m3u8 +17 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_0_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_1_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_2_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_3_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_4_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/n_5_0_0.ts +0 -0
- package/test/test/assets/hls-ts-muxed-aac-h264/playlist.m3u8 +4 -0
- package/test/test/boot.js +7 -2
- package/test/test/util/fake_ad.js +99 -0
- package/test/test/util/fake_ad_manager.js +7 -1
- package/test/test/util/fake_networking_engine.js +41 -14
- package/test/test/util/fake_segment_prefetch.js +81 -0
- package/test/test/util/manifest_generator.js +19 -5
- package/test/test/util/mss_parser_util.js +115 -0
- package/test/test/util/offline_utils.js +1 -0
- package/test/test/util/simple_fakes.js +12 -3
- package/test/test/util/streaming_engine_util.js +14 -4
- package/test/test/util/ttml_utils.js +2 -2
- package/test/text/cue_integration.js +1 -1
- package/test/text/srt_text_parser_unit.js +78 -0
- package/test/text/text_engine_unit.js +17 -8
- package/test/text/ui_text_displayer_unit.js +4 -4
- package/test/text/vtt_text_parser_unit.js +59 -40
- package/test/text/web_vtt_generator_unit.js +9 -3
- package/test/{media/transmuxer_integration.js → transmuxer/muxjs_transmuxer_integration.js} +30 -33
- package/test/transmuxer/transmuxer_engine_integration.js +60 -0
- package/test/transmuxer/transmuxer_integration.js +296 -0
- package/test/util/cmcd_manager_unit.js +162 -13
- package/test/util/language_utils_unit.js +9 -2
- package/test/util/mp4_box_parsers_unit.js +39 -4
- package/test/util/periods_unit.js +34 -26
- package/test/util/stream_utils_unit.js +60 -107
- package/ui/controls.js +19 -1
- package/ui/controls.less +1 -0
- package/ui/externs/ui.js +11 -1
- package/ui/language_utils.js +15 -0
- package/ui/less/thumbnails.less +26 -0
- package/ui/locales/oc.json +42 -0
- package/ui/pip_button.js +83 -2
- package/ui/range_element.js +15 -0
- package/ui/resolution_selection.js +9 -2
- package/ui/seek_bar.js +223 -0
- package/ui/ui.js +5 -0
- package/lib/cea/i_caption_decoder.js +0 -51
- package/lib/cea/i_cea_parser.js +0 -68
|
@@ -158,15 +158,7 @@ shaka.hls.ManifestTextParser = class {
|
|
|
158
158
|
partialSegmentTags.push(tag);
|
|
159
159
|
} else if (tag.name == 'EXT-X-PRELOAD-HINT') {
|
|
160
160
|
if (tag.getAttributeValue('TYPE') == 'PART') {
|
|
161
|
-
|
|
162
|
-
// ignored.
|
|
163
|
-
if (tag.getAttributeValue('BYTERANGE-START') != null) {
|
|
164
|
-
if (tag.getAttributeValue('BYTERANGE-LENGTH') != null) {
|
|
165
|
-
partialSegmentTags.push(tag);
|
|
166
|
-
}
|
|
167
|
-
} else {
|
|
168
|
-
partialSegmentTags.push(tag);
|
|
169
|
-
}
|
|
161
|
+
partialSegmentTags.push(tag);
|
|
170
162
|
} else if (tag.getAttributeValue('TYPE') == 'MAP') {
|
|
171
163
|
// Rename the Preload Hint tag to be a Map tag.
|
|
172
164
|
tag.setName('EXT-X-MAP');
|
|
@@ -180,15 +172,13 @@ shaka.hls.ManifestTextParser = class {
|
|
|
180
172
|
// Skip comments.
|
|
181
173
|
} else {
|
|
182
174
|
const verbatimSegmentUri = line.trim();
|
|
183
|
-
const absoluteSegmentUri = shaka.hls.Utils.constructAbsoluteUri(
|
|
184
|
-
absoluteMediaPlaylistUri, verbatimSegmentUri);
|
|
185
175
|
// Attach the last parsed EXT-X-MAP tag to the segment.
|
|
186
176
|
if (currentMapTag) {
|
|
187
177
|
segmentTags.push(currentMapTag);
|
|
188
178
|
}
|
|
189
179
|
// The URI appears after all of the tags describing the segment.
|
|
190
|
-
const segment = new shaka.hls.Segment(
|
|
191
|
-
partialSegmentTags);
|
|
180
|
+
const segment = new shaka.hls.Segment(absoluteMediaPlaylistUri,
|
|
181
|
+
verbatimSegmentUri, segmentTags, partialSegmentTags);
|
|
192
182
|
segments.push(segment);
|
|
193
183
|
segmentTags = [];
|
|
194
184
|
partialSegmentTags = [];
|
|
@@ -203,7 +193,7 @@ shaka.hls.ManifestTextParser = class {
|
|
|
203
193
|
if (currentMapTag) {
|
|
204
194
|
segmentTags.push(currentMapTag);
|
|
205
195
|
}
|
|
206
|
-
const segment = new shaka.hls.Segment('', segmentTags,
|
|
196
|
+
const segment = new shaka.hls.Segment('', '', segmentTags,
|
|
207
197
|
partialSegmentTags);
|
|
208
198
|
segments.push(segment);
|
|
209
199
|
}
|
|
@@ -49,13 +49,14 @@ shaka.media.ExampleBasedCriteria = class {
|
|
|
49
49
|
// role and label for this.
|
|
50
50
|
const role = '';
|
|
51
51
|
const label = '';
|
|
52
|
+
const hdrLevel = '';
|
|
52
53
|
const channelCount = example.audio && example.audio.channelsCount ?
|
|
53
54
|
example.audio.channelsCount :
|
|
54
55
|
0;
|
|
55
56
|
|
|
56
57
|
/** @private {!shaka.media.AdaptationSetCriteria} */
|
|
57
58
|
this.fallback_ = new shaka.media.PreferenceBasedCriteria(
|
|
58
|
-
example.language, role, channelCount, label);
|
|
59
|
+
example.language, role, channelCount, hdrLevel, label);
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
/** @override */
|
|
@@ -87,9 +88,10 @@ shaka.media.PreferenceBasedCriteria = class {
|
|
|
87
88
|
* @param {string} language
|
|
88
89
|
* @param {string} role
|
|
89
90
|
* @param {number} channelCount
|
|
91
|
+
* @param {string} hdrLevel
|
|
90
92
|
* @param {string=} label
|
|
91
93
|
*/
|
|
92
|
-
constructor(language, role, channelCount, label = '') {
|
|
94
|
+
constructor(language, role, channelCount, hdrLevel, label = '') {
|
|
93
95
|
/** @private {string} */
|
|
94
96
|
this.language_ = language;
|
|
95
97
|
/** @private {string} */
|
|
@@ -97,6 +99,8 @@ shaka.media.PreferenceBasedCriteria = class {
|
|
|
97
99
|
/** @private {number} */
|
|
98
100
|
this.channelCount_ = channelCount;
|
|
99
101
|
/** @private {string} */
|
|
102
|
+
this.hdrLevel_ = hdrLevel;
|
|
103
|
+
/** @private {string} */
|
|
100
104
|
this.label_ = label;
|
|
101
105
|
}
|
|
102
106
|
|
|
@@ -127,6 +131,17 @@ shaka.media.PreferenceBasedCriteria = class {
|
|
|
127
131
|
shaka.log.warning('No exact match for variant role could be found.');
|
|
128
132
|
}
|
|
129
133
|
|
|
134
|
+
if (this.hdrLevel_) {
|
|
135
|
+
const byHdrLevel = Class.filterVariantsByHDRLevel_(
|
|
136
|
+
current, this.hdrLevel_);
|
|
137
|
+
if (byHdrLevel.length) {
|
|
138
|
+
current = byHdrLevel;
|
|
139
|
+
} else {
|
|
140
|
+
shaka.log.warning(
|
|
141
|
+
'No exact match for the hdr level could be found.');
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
130
145
|
if (this.channelCount_) {
|
|
131
146
|
const byChannel = StreamUtils.filterVariantsByAudioChannelCount(
|
|
132
147
|
current, this.channelCount_);
|
|
@@ -218,7 +233,7 @@ shaka.media.PreferenceBasedCriteria = class {
|
|
|
218
233
|
*/
|
|
219
234
|
static filterVariantsByLabel_(variants, preferredLabel) {
|
|
220
235
|
return variants.filter((variant) => {
|
|
221
|
-
if (!variant.audio) {
|
|
236
|
+
if (!variant.audio || !variant.audio.label) {
|
|
222
237
|
return false;
|
|
223
238
|
}
|
|
224
239
|
|
|
@@ -227,4 +242,29 @@ shaka.media.PreferenceBasedCriteria = class {
|
|
|
227
242
|
return label1 == label2;
|
|
228
243
|
});
|
|
229
244
|
}
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Filters variants according to the given hdr level config.
|
|
249
|
+
*
|
|
250
|
+
* @param {!Array.<shaka.extern.Variant>} variants
|
|
251
|
+
* @param {string} hdrLevel
|
|
252
|
+
* @private
|
|
253
|
+
*/
|
|
254
|
+
static filterVariantsByHDRLevel_(variants, hdrLevel) {
|
|
255
|
+
if (hdrLevel == 'AUTO') {
|
|
256
|
+
// Auto detect the ideal HDR level.
|
|
257
|
+
if (window.matchMedia('(color-gamut: p3)').matches) {
|
|
258
|
+
hdrLevel = 'PQ';
|
|
259
|
+
} else {
|
|
260
|
+
hdrLevel = 'SDR';
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return variants.filter((variant) => {
|
|
264
|
+
if (variant.video && variant.video.hdr && variant.video.hdr != hdrLevel) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
return true;
|
|
268
|
+
});
|
|
269
|
+
}
|
|
230
270
|
};
|
|
@@ -7,12 +7,9 @@
|
|
|
7
7
|
goog.provide('shaka.media.ClosedCaptionParser');
|
|
8
8
|
goog.provide('shaka.media.IClosedCaptionParser');
|
|
9
9
|
|
|
10
|
-
goog.require('shaka.cea.
|
|
10
|
+
goog.require('shaka.cea.DummyCaptionDecoder');
|
|
11
11
|
goog.require('shaka.cea.DummyCeaParser');
|
|
12
|
-
goog.require('shaka.cea.Mp4CeaParser');
|
|
13
12
|
goog.require('shaka.util.BufferUtils');
|
|
14
|
-
goog.requireType('shaka.cea.ICaptionDecoder');
|
|
15
|
-
goog.requireType('shaka.cea.ICeaParser');
|
|
16
13
|
|
|
17
14
|
|
|
18
15
|
/**
|
|
@@ -21,6 +18,7 @@ goog.requireType('shaka.cea.ICeaParser');
|
|
|
21
18
|
* TODO: Remove this interface and move method definitions
|
|
22
19
|
* directly to ClosedCaptonParser.
|
|
23
20
|
* @interface
|
|
21
|
+
* @export
|
|
24
22
|
*/
|
|
25
23
|
shaka.media.IClosedCaptionParser = class {
|
|
26
24
|
/**
|
|
@@ -35,7 +33,7 @@ shaka.media.IClosedCaptionParser = class {
|
|
|
35
33
|
* captions.
|
|
36
34
|
*
|
|
37
35
|
* @param {BufferSource} mediaFragment
|
|
38
|
-
* @return {!Array<!shaka.
|
|
36
|
+
* @return {!Array<!shaka.extern.ICaptionDecoder.ClosedCaption>}
|
|
39
37
|
* An array of parsed closed captions.
|
|
40
38
|
*/
|
|
41
39
|
parseFrom(mediaFragment) {}
|
|
@@ -52,23 +50,32 @@ shaka.media.IClosedCaptionParser = class {
|
|
|
52
50
|
*
|
|
53
51
|
* @implements {shaka.media.IClosedCaptionParser}
|
|
54
52
|
* @final
|
|
53
|
+
* @export
|
|
55
54
|
*/
|
|
56
55
|
shaka.media.ClosedCaptionParser = class {
|
|
57
|
-
/**
|
|
56
|
+
/**
|
|
57
|
+
* @param {string} mimeType
|
|
58
|
+
*/
|
|
58
59
|
constructor(mimeType) {
|
|
59
|
-
/** @private {!shaka.
|
|
60
|
+
/** @private {!shaka.extern.ICeaParser} */
|
|
60
61
|
this.ceaParser_ = new shaka.cea.DummyCeaParser();
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
const parserFactory =
|
|
64
|
+
shaka.media.ClosedCaptionParser.findParser(mimeType.toLowerCase());
|
|
65
|
+
if (parserFactory) {
|
|
66
|
+
this.ceaParser_ = parserFactory();
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
/**
|
|
68
70
|
* Decoder for decoding CEA-X08 data from closed caption packets.
|
|
69
|
-
* @private {!shaka.
|
|
71
|
+
* @private {!shaka.extern.ICaptionDecoder}
|
|
70
72
|
*/
|
|
71
|
-
this.ceaDecoder_ = new shaka.cea.
|
|
73
|
+
this.ceaDecoder_ = new shaka.cea.DummyCaptionDecoder();
|
|
74
|
+
|
|
75
|
+
const decoderFactory = shaka.media.ClosedCaptionParser.findDecoder();
|
|
76
|
+
if (decoderFactory) {
|
|
77
|
+
this.ceaDecoder_ = decoderFactory();
|
|
78
|
+
}
|
|
72
79
|
}
|
|
73
80
|
|
|
74
81
|
/**
|
|
@@ -104,4 +111,59 @@ shaka.media.ClosedCaptionParser = class {
|
|
|
104
111
|
reset() {
|
|
105
112
|
this.ceaDecoder_.clear();
|
|
106
113
|
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @param {string} mimeType
|
|
117
|
+
* @param {!shaka.extern.CeaParserPlugin} plugin
|
|
118
|
+
* @export
|
|
119
|
+
*/
|
|
120
|
+
static registerParser(mimeType, plugin) {
|
|
121
|
+
shaka.media.ClosedCaptionParser.parserMap_[mimeType] = plugin;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @param {string} mimeType
|
|
126
|
+
* @export
|
|
127
|
+
*/
|
|
128
|
+
static unregisterParser(mimeType) {
|
|
129
|
+
delete shaka.media.ClosedCaptionParser.parserMap_[mimeType];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @param {string} mimeType
|
|
134
|
+
* @return {?shaka.extern.CeaParserPlugin}
|
|
135
|
+
* @export
|
|
136
|
+
*/
|
|
137
|
+
static findParser(mimeType) {
|
|
138
|
+
return shaka.media.ClosedCaptionParser.parserMap_[mimeType];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @param {!shaka.extern.CaptionDecoderPlugin} plugin
|
|
143
|
+
* @export
|
|
144
|
+
*/
|
|
145
|
+
static registerDecoder(plugin) {
|
|
146
|
+
shaka.media.ClosedCaptionParser.decoderFactory_ = plugin;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @export
|
|
151
|
+
*/
|
|
152
|
+
static unregisterDecoder() {
|
|
153
|
+
shaka.media.ClosedCaptionParser.decoderFactory_ = null;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @return {?shaka.extern.CaptionDecoderPlugin}
|
|
158
|
+
* @export
|
|
159
|
+
*/
|
|
160
|
+
static findDecoder() {
|
|
161
|
+
return shaka.media.ClosedCaptionParser.decoderFactory_;
|
|
162
|
+
}
|
|
107
163
|
};
|
|
164
|
+
|
|
165
|
+
/** @private {!Object<string, shaka.extern.CeaParserPlugin>} */
|
|
166
|
+
shaka.media.ClosedCaptionParser.parserMap_ = {};
|
|
167
|
+
|
|
168
|
+
/** @private {?shaka.extern.CaptionDecoderPlugin} */
|
|
169
|
+
shaka.media.ClosedCaptionParser.decoderFactory_ = null;
|
package/lib/media/drm_engine.js
CHANGED
|
@@ -8,8 +8,8 @@ goog.provide('shaka.media.DrmEngine');
|
|
|
8
8
|
|
|
9
9
|
goog.require('goog.asserts');
|
|
10
10
|
goog.require('shaka.log');
|
|
11
|
-
goog.require('shaka.media.Transmuxer');
|
|
12
11
|
goog.require('shaka.net.NetworkingEngine');
|
|
12
|
+
goog.require('shaka.transmuxer.TransmuxerEngine');
|
|
13
13
|
goog.require('shaka.util.BufferUtils');
|
|
14
14
|
goog.require('shaka.util.Destroyer');
|
|
15
15
|
goog.require('shaka.util.Error');
|
|
@@ -71,8 +71,11 @@ shaka.media.DrmEngine = class {
|
|
|
71
71
|
*/
|
|
72
72
|
this.activeSessions_ = new Map();
|
|
73
73
|
|
|
74
|
-
/**
|
|
75
|
-
|
|
74
|
+
/**
|
|
75
|
+
* @private {!Map<string,
|
|
76
|
+
* {initData: ?Uint8Array, initDataType: ?string}>}
|
|
77
|
+
*/
|
|
78
|
+
this.storedPersistentSessions_ = new Map();
|
|
76
79
|
|
|
77
80
|
/** @private {!shaka.util.PublicPromise} */
|
|
78
81
|
this.allSessionsLoaded_ = new shaka.util.PublicPromise();
|
|
@@ -82,7 +85,10 @@ shaka.media.DrmEngine = class {
|
|
|
82
85
|
|
|
83
86
|
/** @private {function(!shaka.util.Error)} */
|
|
84
87
|
this.onError_ = (err) => {
|
|
85
|
-
|
|
88
|
+
if (err.severity == shaka.util.Error.Severity.CRITICAL) {
|
|
89
|
+
this.allSessionsLoaded_.reject(err);
|
|
90
|
+
}
|
|
91
|
+
|
|
86
92
|
playerInterface.onError(err);
|
|
87
93
|
};
|
|
88
94
|
|
|
@@ -187,7 +193,7 @@ shaka.media.DrmEngine = class {
|
|
|
187
193
|
this.currentDrmInfo_ = null;
|
|
188
194
|
this.supportedTypes_.clear();
|
|
189
195
|
this.mediaKeys_ = null;
|
|
190
|
-
this.
|
|
196
|
+
this.storedPersistentSessions_ = new Map();
|
|
191
197
|
this.config_ = null;
|
|
192
198
|
this.onError_ = () => {};
|
|
193
199
|
this.playerInterface_ = null;
|
|
@@ -231,7 +237,7 @@ shaka.media.DrmEngine = class {
|
|
|
231
237
|
// 2. We are about to remove the offline sessions for this manifest - in
|
|
232
238
|
// that case, we don't need to know about them right now either as
|
|
233
239
|
// we will be told which ones to remove later.
|
|
234
|
-
this.
|
|
240
|
+
this.storedPersistentSessions_ = new Map();
|
|
235
241
|
|
|
236
242
|
// What we really need to know is whether or not they are expecting to use
|
|
237
243
|
// persistent licenses.
|
|
@@ -249,8 +255,20 @@ shaka.media.DrmEngine = class {
|
|
|
249
255
|
* @return {!Promise}
|
|
250
256
|
*/
|
|
251
257
|
initForPlayback(variants, offlineSessionIds) {
|
|
252
|
-
this.
|
|
253
|
-
|
|
258
|
+
this.storedPersistentSessions_ = new Map();
|
|
259
|
+
|
|
260
|
+
for (const sessionId of offlineSessionIds) {
|
|
261
|
+
this.storedPersistentSessions_.set(
|
|
262
|
+
sessionId, {initData: null, initDataType: null});
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
for (const metadata of this.config_.persistentSessionsMetadata) {
|
|
266
|
+
this.storedPersistentSessions_.set(
|
|
267
|
+
metadata.sessionId,
|
|
268
|
+
{initData: metadata.initData, initDataType: metadata.initDataType});
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
this.usePersistentLicenses_ = this.storedPersistentSessions_.size > 0;
|
|
254
272
|
|
|
255
273
|
return this.init_(variants);
|
|
256
274
|
}
|
|
@@ -304,7 +322,7 @@ shaka.media.DrmEngine = class {
|
|
|
304
322
|
/**
|
|
305
323
|
* Negotiate for a key system and set up MediaKeys.
|
|
306
324
|
* This will assume that both |usePersistentLicences_| and
|
|
307
|
-
* |
|
|
325
|
+
* |storedPersistentSessions_| have been properly set.
|
|
308
326
|
*
|
|
309
327
|
* @param {!Array.<shaka.extern.Variant>} variants
|
|
310
328
|
* The variants that we expect to operate with during the drm engine's
|
|
@@ -378,7 +396,8 @@ shaka.media.DrmEngine = class {
|
|
|
378
396
|
// We should get the decodingInfo results for the variants after we filling
|
|
379
397
|
// in the drm infos, and before queryMediaKeys_().
|
|
380
398
|
await shaka.util.StreamUtils.getDecodingInfosForVariants(variants,
|
|
381
|
-
this.usePersistentLicenses_, this.srcEquals_
|
|
399
|
+
this.usePersistentLicenses_, this.srcEquals_,
|
|
400
|
+
this.config_.preferredKeySystems);
|
|
382
401
|
|
|
383
402
|
const hasDrmInfo = hadDrmInfo || Object.keys(this.config_.servers).length;
|
|
384
403
|
// An unencrypted content is initialized.
|
|
@@ -502,18 +521,21 @@ shaka.media.DrmEngine = class {
|
|
|
502
521
|
*/
|
|
503
522
|
if (this.manifestInitData_ ||
|
|
504
523
|
this.currentDrmInfo_.keySystem !== 'com.apple.fps' ||
|
|
505
|
-
this.
|
|
524
|
+
this.storedPersistentSessions_.size) {
|
|
506
525
|
await this.attachMediaKeys_();
|
|
507
526
|
}
|
|
508
527
|
|
|
509
|
-
this.createOrLoad()
|
|
528
|
+
this.createOrLoad().catch(() => {
|
|
529
|
+
// Silence errors
|
|
530
|
+
// createOrLoad will run async, errors are triggered through onError_
|
|
531
|
+
});
|
|
510
532
|
|
|
511
533
|
// Explicit init data for any one stream or an offline session is
|
|
512
534
|
// sufficient to suppress 'encrypted' events for all streams.
|
|
513
535
|
// Also suppress 'encrypted' events when parsing in-band ppsh
|
|
514
536
|
// from media segments because that serves the same purpose as the
|
|
515
537
|
// 'encrypted' events.
|
|
516
|
-
if (!this.manifestInitData_ && !this.
|
|
538
|
+
if (!this.manifestInitData_ && !this.storedPersistentSessions_.size &&
|
|
517
539
|
!this.config_.parseInbandPsshEnabled) {
|
|
518
540
|
this.eventManager_.listen(
|
|
519
541
|
this.video_, 'encrypted', (e) => this.onEncryptedEvent_(e));
|
|
@@ -601,7 +623,8 @@ shaka.media.DrmEngine = class {
|
|
|
601
623
|
goog.asserts.assert(this.mediaKeys_,
|
|
602
624
|
'Must call init() before removeSession');
|
|
603
625
|
|
|
604
|
-
const session = await this.loadOfflineSession_(
|
|
626
|
+
const session = await this.loadOfflineSession_(
|
|
627
|
+
sessionId, {initData: null, initDataType: null});
|
|
605
628
|
|
|
606
629
|
// This will be null on error, such as session not found.
|
|
607
630
|
if (!session) {
|
|
@@ -634,8 +657,30 @@ shaka.media.DrmEngine = class {
|
|
|
634
657
|
*
|
|
635
658
|
* @return {!Promise}
|
|
636
659
|
*/
|
|
637
|
-
createOrLoad() {
|
|
638
|
-
|
|
660
|
+
async createOrLoad() {
|
|
661
|
+
if (this.storedPersistentSessions_.size) {
|
|
662
|
+
this.storedPersistentSessions_.forEach((metadata, sessionId) => {
|
|
663
|
+
this.loadOfflineSession_(sessionId, metadata);
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
await this.allSessionsLoaded_;
|
|
667
|
+
|
|
668
|
+
const keyIds = (this.currentDrmInfo_ && this.currentDrmInfo_.keyIds) ||
|
|
669
|
+
new Set([]);
|
|
670
|
+
|
|
671
|
+
// All the needed keys are already loaded, we don't need another license
|
|
672
|
+
// Therefore we prevent starting a new session
|
|
673
|
+
if (keyIds.size > 0 && this.areAllKeysUsable_()) {
|
|
674
|
+
return this.allSessionsLoaded_;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
// Reset the promise for the next sessions to come if key needs aren't
|
|
678
|
+
// satisfied with persistent sessions
|
|
679
|
+
this.allSessionsLoaded_ = new shaka.util.PublicPromise();
|
|
680
|
+
this.allSessionsLoaded_.catch(() => {});
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
// Create sessions.
|
|
639
684
|
const initDatas =
|
|
640
685
|
(this.currentDrmInfo_ ? this.currentDrmInfo_.initData : []) || [];
|
|
641
686
|
for (const initDataOverride of initDatas) {
|
|
@@ -643,14 +688,9 @@ shaka.media.DrmEngine = class {
|
|
|
643
688
|
initDataOverride.initDataType, initDataOverride.initData);
|
|
644
689
|
}
|
|
645
690
|
|
|
646
|
-
// Load each session.
|
|
647
|
-
for (const sessionId of this.offlineSessionIds_) {
|
|
648
|
-
this.loadOfflineSession_(sessionId);
|
|
649
|
-
}
|
|
650
|
-
|
|
651
691
|
// If we have no sessions, we need to resolve the promise right now or else
|
|
652
692
|
// it will never get resolved.
|
|
653
|
-
if (!initDatas.length
|
|
693
|
+
if (!initDatas.length) {
|
|
654
694
|
this.allSessionsLoaded_.resolve();
|
|
655
695
|
}
|
|
656
696
|
|
|
@@ -778,6 +818,28 @@ shaka.media.DrmEngine = class {
|
|
|
778
818
|
return Array.from(ids);
|
|
779
819
|
}
|
|
780
820
|
|
|
821
|
+
/**
|
|
822
|
+
* Returns the active sessions metadata
|
|
823
|
+
*
|
|
824
|
+
* @return {!Array.<shaka.extern.DrmSessionMetadata>}
|
|
825
|
+
*/
|
|
826
|
+
getActiveSessionsMetadata() {
|
|
827
|
+
const sessions = this.activeSessions_.keys();
|
|
828
|
+
|
|
829
|
+
const metadata = shaka.util.Iterables.map(sessions, (session) => {
|
|
830
|
+
const metadata = this.activeSessions_.get(session);
|
|
831
|
+
|
|
832
|
+
return {
|
|
833
|
+
sessionId: session.sessionId,
|
|
834
|
+
sessionType: metadata.type,
|
|
835
|
+
initData: metadata.initData,
|
|
836
|
+
initDataType: metadata.initDataType,
|
|
837
|
+
};
|
|
838
|
+
});
|
|
839
|
+
|
|
840
|
+
return Array.from(metadata);
|
|
841
|
+
}
|
|
842
|
+
|
|
781
843
|
/**
|
|
782
844
|
* Returns the next expiration time, or Infinity.
|
|
783
845
|
* @return {number}
|
|
@@ -853,10 +915,11 @@ shaka.media.DrmEngine = class {
|
|
|
853
915
|
static computeMimeType_(stream, codecOverride) {
|
|
854
916
|
const realMimeType = shaka.util.MimeUtils.getFullType(stream.mimeType,
|
|
855
917
|
codecOverride || stream.codecs);
|
|
856
|
-
|
|
918
|
+
const TransmuxerEngine = shaka.transmuxer.TransmuxerEngine;
|
|
919
|
+
if (TransmuxerEngine.isSupported(realMimeType, stream.type)) {
|
|
857
920
|
// This will be handled by the Transmuxer, so use the MIME type that the
|
|
858
921
|
// Transmuxer will produce.
|
|
859
|
-
return
|
|
922
|
+
return TransmuxerEngine.convertCodecs(stream.type, realMimeType);
|
|
860
923
|
}
|
|
861
924
|
return realMimeType;
|
|
862
925
|
}
|
|
@@ -934,6 +997,30 @@ shaka.media.DrmEngine = class {
|
|
|
934
997
|
this.currentDrmInfo_.keySystem);
|
|
935
998
|
|
|
936
999
|
this.mediaKeys_ = mediaKeys;
|
|
1000
|
+
if (this.config_.minHdcpVersion != '' &&
|
|
1001
|
+
'getStatusForPolicy' in this.mediaKeys_) {
|
|
1002
|
+
try {
|
|
1003
|
+
const status = await this.mediaKeys_.getStatusForPolicy({
|
|
1004
|
+
minHdcpVersion: this.config_.minHdcpVersion,
|
|
1005
|
+
});
|
|
1006
|
+
if (status != 'usable') {
|
|
1007
|
+
throw new shaka.util.Error(
|
|
1008
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
1009
|
+
shaka.util.Error.Category.DRM,
|
|
1010
|
+
shaka.util.Error.Code.MIN_HDCP_VERSION_NOT_MATCH);
|
|
1011
|
+
}
|
|
1012
|
+
this.destroyer_.ensureNotDestroyed();
|
|
1013
|
+
} catch (e) {
|
|
1014
|
+
if (e instanceof shaka.util.Error) {
|
|
1015
|
+
throw e;
|
|
1016
|
+
}
|
|
1017
|
+
throw new shaka.util.Error(
|
|
1018
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
1019
|
+
shaka.util.Error.Category.DRM,
|
|
1020
|
+
shaka.util.Error.Code.ERROR_CHECKING_HDCP_VERSION,
|
|
1021
|
+
e.message);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
937
1024
|
this.initialized_ = true;
|
|
938
1025
|
|
|
939
1026
|
await this.setServerCertificate();
|
|
@@ -1171,12 +1258,41 @@ shaka.media.DrmEngine = class {
|
|
|
1171
1258
|
};
|
|
1172
1259
|
}
|
|
1173
1260
|
|
|
1261
|
+
/**
|
|
1262
|
+
* Resolves the allSessionsLoaded_ promise when all the sessions are loaded
|
|
1263
|
+
*
|
|
1264
|
+
* @private
|
|
1265
|
+
*/
|
|
1266
|
+
checkSessionsLoaded_() {
|
|
1267
|
+
if (this.areAllSessionsLoaded_()) {
|
|
1268
|
+
this.allSessionsLoaded_.resolve();
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
/**
|
|
1273
|
+
* In case there are no key statuses, consider this session loaded
|
|
1274
|
+
* after a reasonable timeout. It should definitely not take 5
|
|
1275
|
+
* seconds to process a license.
|
|
1276
|
+
* @param {!shaka.media.DrmEngine.SessionMetaData} metadata
|
|
1277
|
+
* @private
|
|
1278
|
+
*/
|
|
1279
|
+
setLoadSessionTimeoutTimer_(metadata) {
|
|
1280
|
+
const timer = new shaka.util.Timer(() => {
|
|
1281
|
+
metadata.loaded = true;
|
|
1282
|
+
this.checkSessionsLoaded_();
|
|
1283
|
+
});
|
|
1284
|
+
|
|
1285
|
+
timer.tickAfter(
|
|
1286
|
+
/* seconds= */ shaka.media.DrmEngine.SESSION_LOAD_TIMEOUT_);
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1174
1289
|
/**
|
|
1175
1290
|
* @param {string} sessionId
|
|
1291
|
+
* @param {{initData: ?Uint8Array, initDataType: ?string}} sessionMetadata
|
|
1176
1292
|
* @return {!Promise.<MediaKeySession>}
|
|
1177
1293
|
* @private
|
|
1178
1294
|
*/
|
|
1179
|
-
async loadOfflineSession_(sessionId) {
|
|
1295
|
+
async loadOfflineSession_(sessionId, sessionMetadata) {
|
|
1180
1296
|
let session;
|
|
1181
1297
|
|
|
1182
1298
|
const sessionType = 'persistent-license';
|
|
@@ -1201,8 +1317,8 @@ shaka.media.DrmEngine = class {
|
|
|
1201
1317
|
(event) => this.onKeyStatusesChange_(event));
|
|
1202
1318
|
|
|
1203
1319
|
const metadata = {
|
|
1204
|
-
initData:
|
|
1205
|
-
initDataType:
|
|
1320
|
+
initData: sessionMetadata.initData,
|
|
1321
|
+
initDataType: sessionMetadata.initDataType,
|
|
1206
1322
|
loaded: false,
|
|
1207
1323
|
oldExpiration: Infinity,
|
|
1208
1324
|
updatePromise: null,
|
|
@@ -1218,32 +1334,42 @@ shaka.media.DrmEngine = class {
|
|
|
1218
1334
|
if (!present) {
|
|
1219
1335
|
this.activeSessions_.delete(session);
|
|
1220
1336
|
|
|
1337
|
+
const severity = this.config_.persistentSessionOnlinePlayback ?
|
|
1338
|
+
shaka.util.Error.Severity.RECOVERABLE :
|
|
1339
|
+
shaka.util.Error.Severity.CRITICAL;
|
|
1340
|
+
|
|
1221
1341
|
this.onError_(new shaka.util.Error(
|
|
1222
|
-
|
|
1342
|
+
severity,
|
|
1223
1343
|
shaka.util.Error.Category.DRM,
|
|
1224
1344
|
shaka.util.Error.Code.OFFLINE_SESSION_REMOVED));
|
|
1225
|
-
return Promise.resolve();
|
|
1226
|
-
}
|
|
1227
1345
|
|
|
1228
|
-
|
|
1229
|
-
// is fixed.
|
|
1230
|
-
metadata.loaded = true;
|
|
1231
|
-
if (this.areAllSessionsLoaded_()) {
|
|
1232
|
-
this.allSessionsLoaded_.resolve();
|
|
1346
|
+
metadata.loaded = true;
|
|
1233
1347
|
}
|
|
1234
1348
|
|
|
1349
|
+
this.setLoadSessionTimeoutTimer_(metadata);
|
|
1350
|
+
this.checkSessionsLoaded_();
|
|
1351
|
+
|
|
1235
1352
|
return session;
|
|
1236
1353
|
} catch (error) {
|
|
1237
1354
|
this.destroyer_.ensureNotDestroyed(error);
|
|
1238
1355
|
|
|
1239
1356
|
this.activeSessions_.delete(session);
|
|
1240
1357
|
|
|
1358
|
+
const severity = this.config_.persistentSessionOnlinePlayback ?
|
|
1359
|
+
shaka.util.Error.Severity.RECOVERABLE :
|
|
1360
|
+
shaka.util.Error.Severity.CRITICAL;
|
|
1361
|
+
|
|
1241
1362
|
this.onError_(new shaka.util.Error(
|
|
1242
|
-
|
|
1363
|
+
severity,
|
|
1243
1364
|
shaka.util.Error.Category.DRM,
|
|
1244
1365
|
shaka.util.Error.Code.FAILED_TO_CREATE_SESSION,
|
|
1245
1366
|
error.message));
|
|
1367
|
+
|
|
1368
|
+
metadata.loaded = true;
|
|
1369
|
+
|
|
1370
|
+
this.checkSessionsLoaded_();
|
|
1246
1371
|
}
|
|
1372
|
+
|
|
1247
1373
|
return Promise.resolve();
|
|
1248
1374
|
}
|
|
1249
1375
|
|
|
@@ -1469,18 +1595,8 @@ shaka.media.DrmEngine = class {
|
|
|
1469
1595
|
if (metadata.updatePromise) {
|
|
1470
1596
|
metadata.updatePromise.resolve();
|
|
1471
1597
|
}
|
|
1472
|
-
// In case there are no key statuses, consider this session loaded
|
|
1473
|
-
// after a reasonable timeout. It should definitely not take 5
|
|
1474
|
-
// seconds to process a license.
|
|
1475
|
-
const timer = new shaka.util.Timer(() => {
|
|
1476
|
-
metadata.loaded = true;
|
|
1477
|
-
if (this.areAllSessionsLoaded_()) {
|
|
1478
|
-
this.allSessionsLoaded_.resolve();
|
|
1479
|
-
}
|
|
1480
|
-
});
|
|
1481
1598
|
|
|
1482
|
-
|
|
1483
|
-
/* seconds= */ shaka.media.DrmEngine.SESSION_LOAD_TIMEOUT_);
|
|
1599
|
+
this.setLoadSessionTimeoutTimer_(metadata);
|
|
1484
1600
|
}
|
|
1485
1601
|
}
|
|
1486
1602
|
|
|
@@ -1828,8 +1944,9 @@ shaka.media.DrmEngine = class {
|
|
|
1828
1944
|
* the playback session ends
|
|
1829
1945
|
*/
|
|
1830
1946
|
if (!this.initializedForStorage_ &&
|
|
1831
|
-
!this.
|
|
1832
|
-
metadata.type === 'persistent-license'
|
|
1947
|
+
!this.storedPersistentSessions_.has(session.sessionId) &&
|
|
1948
|
+
metadata.type === 'persistent-license' &&
|
|
1949
|
+
!this.config_.persistentSessionOnlinePlayback) {
|
|
1833
1950
|
shaka.log.v1('Removing session', session.sessionId);
|
|
1834
1951
|
|
|
1835
1952
|
await session.remove();
|
|
@@ -1895,6 +2012,10 @@ shaka.media.DrmEngine = class {
|
|
|
1895
2012
|
return true;
|
|
1896
2013
|
}
|
|
1897
2014
|
|
|
2015
|
+
if (drms1 === drms2) {
|
|
2016
|
+
return true;
|
|
2017
|
+
}
|
|
2018
|
+
|
|
1898
2019
|
return shaka.media.DrmEngine.getCommonDrmInfos(
|
|
1899
2020
|
drms1, drms2).length > 0;
|
|
1900
2021
|
}
|
|
@@ -2003,6 +2124,25 @@ shaka.media.DrmEngine = class {
|
|
|
2003
2124
|
return shaka.util.Iterables.every(metadatas, (data) => data.loaded);
|
|
2004
2125
|
}
|
|
2005
2126
|
|
|
2127
|
+
/**
|
|
2128
|
+
* @return {boolean}
|
|
2129
|
+
* @private
|
|
2130
|
+
*/
|
|
2131
|
+
areAllKeysUsable_() {
|
|
2132
|
+
const keyIds = (this.currentDrmInfo_ && this.currentDrmInfo_.keyIds) ||
|
|
2133
|
+
new Set([]);
|
|
2134
|
+
|
|
2135
|
+
for (const keyId of keyIds) {
|
|
2136
|
+
const status = this.keyStatusByKeyId_.get(keyId);
|
|
2137
|
+
|
|
2138
|
+
if (status !== 'usable') {
|
|
2139
|
+
return false;
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
|
|
2143
|
+
return true;
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2006
2146
|
/**
|
|
2007
2147
|
* Replace the drm info used in each variant in |variants| to reflect each
|
|
2008
2148
|
* key service in |keySystems|.
|