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
|
@@ -46,18 +46,21 @@ goog.require('shaka.util.Timer');
|
|
|
46
46
|
*/
|
|
47
47
|
shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
|
|
48
48
|
/**
|
|
49
|
-
* @param {function(number, number)=} onProgressUpdated Called when
|
|
50
|
-
* event is triggered. Passed the duration, in milliseconds,
|
|
51
|
-
* request took,
|
|
49
|
+
* @param {function(number, number, boolean)=} onProgressUpdated Called when
|
|
50
|
+
* a progress event is triggered. Passed the duration, in milliseconds,
|
|
51
|
+
* that the request took, the number of bytes transferred, and the boolean
|
|
52
|
+
* of whether the switching is allowed.
|
|
52
53
|
* @param {shaka.net.NetworkingEngine.OnHeadersReceived=} onHeadersReceived
|
|
53
54
|
* Called when the headers are received for a download.
|
|
54
55
|
* @param {shaka.net.NetworkingEngine.OnDownloadFailed=} onDownloadFailed
|
|
55
56
|
* Called when a download fails, for any reason.
|
|
56
57
|
* @param {shaka.net.NetworkingEngine.OnRequest=} onRequest
|
|
57
58
|
* Called when a request is made
|
|
59
|
+
* @param {shaka.net.NetworkingEngine.OnRetry=} onRetry
|
|
60
|
+
* Called when a request retry is made
|
|
58
61
|
*/
|
|
59
62
|
constructor(onProgressUpdated, onHeadersReceived, onDownloadFailed,
|
|
60
|
-
onRequest) {
|
|
63
|
+
onRequest, onRetry) {
|
|
61
64
|
super();
|
|
62
65
|
|
|
63
66
|
/** @private {boolean} */
|
|
@@ -72,7 +75,7 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
|
|
|
72
75
|
/** @private {!Set.<shaka.extern.ResponseFilter>} */
|
|
73
76
|
this.responseFilters_ = new Set();
|
|
74
77
|
|
|
75
|
-
/** @private {?function(number, number)} */
|
|
78
|
+
/** @private {?function(number, number, boolean)} */
|
|
76
79
|
this.onProgressUpdated_ = onProgressUpdated || null;
|
|
77
80
|
|
|
78
81
|
/** @private {?shaka.net.NetworkingEngine.OnHeadersReceived} */
|
|
@@ -84,6 +87,9 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
|
|
|
84
87
|
/** @private {?shaka.net.NetworkingEngine.OnRequest} */
|
|
85
88
|
this.onRequest_ = onRequest || null;
|
|
86
89
|
|
|
90
|
+
/** @private {?shaka.net.NetworkingEngine.OnRetry} */
|
|
91
|
+
this.onRetry_ = onRetry || null;
|
|
92
|
+
|
|
87
93
|
/** @private {boolean} */
|
|
88
94
|
this.forceHTTPS_ = false;
|
|
89
95
|
}
|
|
@@ -295,7 +301,8 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
|
|
|
295
301
|
// Apply the registered filters to the request.
|
|
296
302
|
const requestFilterOperation = this.filterRequest_(type, request, context);
|
|
297
303
|
const requestOperation = requestFilterOperation.chain(
|
|
298
|
-
() => this.makeRequestWithRetry_(type, request,
|
|
304
|
+
() => this.makeRequestWithRetry_(type, request, context,
|
|
305
|
+
numBytesRemainingObj));
|
|
299
306
|
const responseFilterOperation = requestOperation.chain(
|
|
300
307
|
(responseAndGotProgress) =>
|
|
301
308
|
this.filterResponse_(type, responseAndGotProgress, context));
|
|
@@ -322,7 +329,9 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
|
|
|
322
329
|
!response.fromCache &&
|
|
323
330
|
request.method != 'HEAD' &&
|
|
324
331
|
type == shaka.net.NetworkingEngine.RequestType.SEGMENT) {
|
|
325
|
-
this.
|
|
332
|
+
const allowSwitch = this.allowSwitch_(context);
|
|
333
|
+
this.onProgressUpdated_(
|
|
334
|
+
response.timeMs, response.data.byteLength, allowSwitch);
|
|
326
335
|
}
|
|
327
336
|
return response;
|
|
328
337
|
}, (e) => {
|
|
@@ -399,18 +408,19 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
|
|
|
399
408
|
/**
|
|
400
409
|
* @param {shaka.net.NetworkingEngine.RequestType} type
|
|
401
410
|
* @param {shaka.extern.Request} request
|
|
411
|
+
* @param {(shaka.extern.RequestContext|undefined)} context
|
|
402
412
|
* @param {shaka.net.NetworkingEngine.NumBytesRemainingClass}
|
|
403
413
|
* numBytesRemainingObj
|
|
404
414
|
* @return {!shaka.extern.IAbortableOperation.<
|
|
405
415
|
* shaka.net.NetworkingEngine.ResponseAndGotProgress>}
|
|
406
416
|
* @private
|
|
407
417
|
*/
|
|
408
|
-
makeRequestWithRetry_(type, request, numBytesRemainingObj) {
|
|
418
|
+
makeRequestWithRetry_(type, request, context, numBytesRemainingObj) {
|
|
409
419
|
const backoff = new shaka.net.Backoff(
|
|
410
420
|
request.retryParameters, /* autoReset= */ false);
|
|
411
421
|
const index = 0;
|
|
412
422
|
return this.send_(
|
|
413
|
-
type, request, backoff, index, /* lastError= */ null,
|
|
423
|
+
type, request, context, backoff, index, /* lastError= */ null,
|
|
414
424
|
numBytesRemainingObj);
|
|
415
425
|
}
|
|
416
426
|
|
|
@@ -419,6 +429,7 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
|
|
|
419
429
|
*
|
|
420
430
|
* @param {shaka.net.NetworkingEngine.RequestType} type
|
|
421
431
|
* @param {shaka.extern.Request} request
|
|
432
|
+
* @param {(shaka.extern.RequestContext|undefined)} context
|
|
422
433
|
* @param {!shaka.net.Backoff} backoff
|
|
423
434
|
* @param {number} index
|
|
424
435
|
* @param {?shaka.util.Error} lastError
|
|
@@ -428,11 +439,18 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
|
|
|
428
439
|
* shaka.net.NetworkingEngine.ResponseAndGotProgress>}
|
|
429
440
|
* @private
|
|
430
441
|
*/
|
|
431
|
-
send_(type, request, backoff, index, lastError,
|
|
442
|
+
send_(type, request, context, backoff, index, lastError,
|
|
443
|
+
numBytesRemainingObj) {
|
|
432
444
|
if (this.forceHTTPS_) {
|
|
433
445
|
request.uris[index] = request.uris[index].replace('http://', 'https://');
|
|
434
446
|
}
|
|
435
447
|
|
|
448
|
+
if (index > 0 && this.onRetry_) {
|
|
449
|
+
const newUri = request.uris[index];
|
|
450
|
+
const oldUri = request.uris[index - 1];
|
|
451
|
+
this.onRetry_(type, context, newUri, oldUri);
|
|
452
|
+
}
|
|
453
|
+
|
|
436
454
|
const uri = new goog.Uri(request.uris[index]);
|
|
437
455
|
let scheme = uri.getScheme();
|
|
438
456
|
// Whether it got a progress event.
|
|
@@ -501,7 +519,8 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
|
|
|
501
519
|
stallTimer.tickAfter(stallTimeoutMs / 1000);
|
|
502
520
|
}
|
|
503
521
|
if (this.onProgressUpdated_ && type == segment) {
|
|
504
|
-
this.
|
|
522
|
+
const allowSwitch = this.allowSwitch_(context);
|
|
523
|
+
this.onProgressUpdated_(time, bytes, allowSwitch);
|
|
505
524
|
gotProgress = true;
|
|
506
525
|
numBytesRemainingObj.setBytes(numBytesRemaining);
|
|
507
526
|
}
|
|
@@ -610,7 +629,8 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
|
|
|
610
629
|
// Move to the next URI.
|
|
611
630
|
index = (index + 1) % request.uris.length;
|
|
612
631
|
return this.send_(
|
|
613
|
-
type, request, backoff, index, error,
|
|
632
|
+
type, request, context, backoff, index, error,
|
|
633
|
+
numBytesRemainingObj);
|
|
614
634
|
}
|
|
615
635
|
}
|
|
616
636
|
|
|
@@ -670,6 +690,24 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
|
|
|
670
690
|
});
|
|
671
691
|
}
|
|
672
692
|
|
|
693
|
+
/**
|
|
694
|
+
* @param {(shaka.extern.RequestContext|undefined)} context
|
|
695
|
+
* @return {boolean}
|
|
696
|
+
* @private
|
|
697
|
+
*/
|
|
698
|
+
allowSwitch_(context) {
|
|
699
|
+
if (context) {
|
|
700
|
+
const segment = context.segment;
|
|
701
|
+
const stream = context.stream;
|
|
702
|
+
if (segment && stream && stream.fastSwitching) {
|
|
703
|
+
if (segment.isPartial() && !segment.isLastPartial()) {
|
|
704
|
+
return false;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
return true;
|
|
709
|
+
}
|
|
710
|
+
|
|
673
711
|
/**
|
|
674
712
|
* This is here only for testability. We can't mock location in our tests on
|
|
675
713
|
* all browsers, so instead we mock this.
|
|
@@ -769,6 +807,8 @@ shaka.net.NetworkingEngine.RequestType = {
|
|
|
769
807
|
'TIMING': 4,
|
|
770
808
|
'SERVER_CERTIFICATE': 5,
|
|
771
809
|
'KEY': 6,
|
|
810
|
+
'ADS': 7,
|
|
811
|
+
'CONTENT_STEERING': 8,
|
|
772
812
|
};
|
|
773
813
|
|
|
774
814
|
/**
|
|
@@ -886,3 +926,18 @@ shaka.net.NetworkingEngine.OnDownloadFailed;
|
|
|
886
926
|
* @export
|
|
887
927
|
*/
|
|
888
928
|
shaka.net.NetworkingEngine.OnRequest;
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
/**
|
|
932
|
+
* @typedef {function(
|
|
933
|
+
* !shaka.net.NetworkingEngine.RequestType,
|
|
934
|
+
* (shaka.extern.RequestContext|undefined),
|
|
935
|
+
* string,
|
|
936
|
+
* string)}
|
|
937
|
+
*
|
|
938
|
+
* @description
|
|
939
|
+
* A callback function called on every request retry. The first string is the
|
|
940
|
+
* new URI and the second string is the old URI.
|
|
941
|
+
* @export
|
|
942
|
+
*/
|
|
943
|
+
shaka.net.NetworkingEngine.OnRetry;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
goog.provide('shaka.net.NetworkingUtils');
|
|
8
|
+
|
|
9
|
+
goog.require('goog.Uri');
|
|
10
|
+
goog.require('shaka.net.NetworkingEngine');
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @summary Networking utility functions.
|
|
15
|
+
*/
|
|
16
|
+
shaka.net.NetworkingUtils = class {
|
|
17
|
+
/**
|
|
18
|
+
* @param {string} uri
|
|
19
|
+
* @param {!shaka.net.NetworkingEngine} netEngine
|
|
20
|
+
* @param {shaka.extern.RetryParameters} retryParams
|
|
21
|
+
* @return {!Promise.<string>}
|
|
22
|
+
*/
|
|
23
|
+
static async getMimeType(uri, netEngine, retryParams) {
|
|
24
|
+
const extension = shaka.net.NetworkingUtils.getExtension_(uri);
|
|
25
|
+
let mimeType =
|
|
26
|
+
shaka.net.NetworkingUtils.EXTENSIONS_TO_MIME_TYPES_[extension];
|
|
27
|
+
if (mimeType) {
|
|
28
|
+
return mimeType;
|
|
29
|
+
}
|
|
30
|
+
const type = shaka.net.NetworkingEngine.RequestType.MANIFEST;
|
|
31
|
+
|
|
32
|
+
const request = shaka.net.NetworkingEngine.makeRequest([uri], retryParams);
|
|
33
|
+
request.method = 'HEAD';
|
|
34
|
+
|
|
35
|
+
const response = await netEngine.request(type, request).promise;
|
|
36
|
+
|
|
37
|
+
// https://bit.ly/2K9s9kf says this header should always be available,
|
|
38
|
+
// but just to be safe:
|
|
39
|
+
mimeType = response.headers['content-type'];
|
|
40
|
+
return mimeType ? mimeType.toLowerCase().split(';').shift() : '';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @param {string} uri
|
|
46
|
+
* @return {string}
|
|
47
|
+
* @private
|
|
48
|
+
*/
|
|
49
|
+
static getExtension_(uri) {
|
|
50
|
+
const uriObj = new goog.Uri(uri);
|
|
51
|
+
const uriPieces = uriObj.getPath().split('/');
|
|
52
|
+
const uriFilename = uriPieces.pop();
|
|
53
|
+
const filenamePieces = uriFilename.split('.');
|
|
54
|
+
|
|
55
|
+
// Only one piece means there is no extension.
|
|
56
|
+
if (filenamePieces.length == 1) {
|
|
57
|
+
return '';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return filenamePieces.pop().toLowerCase();
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @const {!Object.<string, string>}
|
|
66
|
+
* @private
|
|
67
|
+
*/
|
|
68
|
+
shaka.net.NetworkingUtils.EXTENSIONS_TO_MIME_TYPES_ = {
|
|
69
|
+
'mp4': 'video/mp4',
|
|
70
|
+
'm4v': 'video/mp4',
|
|
71
|
+
'm4a': 'audio/mp4',
|
|
72
|
+
'webm': 'video/webm',
|
|
73
|
+
'weba': 'audio/webm',
|
|
74
|
+
'mkv': 'video/webm', // Chromium browsers supports it.
|
|
75
|
+
'ts': 'video/mp2t',
|
|
76
|
+
'ogv': 'video/ogg',
|
|
77
|
+
'ogg': 'audio/ogg',
|
|
78
|
+
'mpg': 'video/mpeg',
|
|
79
|
+
'mpeg': 'video/mpeg',
|
|
80
|
+
'm3u8': 'application/x-mpegurl',
|
|
81
|
+
'mpd': 'application/dash+xml',
|
|
82
|
+
'ism': 'application/vnd.ms-sstr+xml',
|
|
83
|
+
'mp3': 'audio/mpeg',
|
|
84
|
+
'aac': 'audio/aac',
|
|
85
|
+
'flac': 'audio/flac',
|
|
86
|
+
'wav': 'audio/wav',
|
|
87
|
+
'sbv': 'text/x-subviewer',
|
|
88
|
+
'srt': 'text/srt',
|
|
89
|
+
'vtt': 'text/vtt',
|
|
90
|
+
'webvtt': 'text/vtt',
|
|
91
|
+
'ttml': 'application/ttml+xml',
|
|
92
|
+
'lrc': 'application/x-subtitle-lrc',
|
|
93
|
+
'ssa': 'text/x-ssa',
|
|
94
|
+
'ass': 'text/x-ssa',
|
|
95
|
+
};
|
|
@@ -150,6 +150,7 @@ shaka.offline.indexeddb.V1StorageCell = class
|
|
|
150
150
|
return {
|
|
151
151
|
id: old.id,
|
|
152
152
|
originalId: null,
|
|
153
|
+
groupId: null,
|
|
153
154
|
primary: old.primary,
|
|
154
155
|
type: old.contentType,
|
|
155
156
|
mimeType: old.mimeType,
|
|
@@ -157,6 +158,7 @@ shaka.offline.indexeddb.V1StorageCell = class
|
|
|
157
158
|
frameRate: old.frameRate,
|
|
158
159
|
pixelAspectRatio: undefined,
|
|
159
160
|
hdr: undefined,
|
|
161
|
+
videoLayout: undefined,
|
|
160
162
|
kind: old.kind,
|
|
161
163
|
language: old.language,
|
|
162
164
|
originalLanguage: old.language || null,
|
|
@@ -178,6 +180,7 @@ shaka.offline.indexeddb.V1StorageCell = class
|
|
|
178
180
|
closedCaptions: null,
|
|
179
181
|
tilesLayout: undefined,
|
|
180
182
|
external: false,
|
|
183
|
+
fastSwitching: false,
|
|
181
184
|
};
|
|
182
185
|
}
|
|
183
186
|
|
|
@@ -99,6 +99,7 @@ shaka.offline.indexeddb.V2StorageCell = class
|
|
|
99
99
|
return {
|
|
100
100
|
id: old.id,
|
|
101
101
|
originalId: old.originalId,
|
|
102
|
+
groupId: null,
|
|
102
103
|
primary: old.primary,
|
|
103
104
|
type: old.contentType,
|
|
104
105
|
mimeType: old.mimeType,
|
|
@@ -106,6 +107,7 @@ shaka.offline.indexeddb.V2StorageCell = class
|
|
|
106
107
|
frameRate: old.frameRate,
|
|
107
108
|
pixelAspectRatio: old.pixelAspectRatio,
|
|
108
109
|
hdr: undefined,
|
|
110
|
+
videoLayout: undefined,
|
|
109
111
|
kind: old.kind,
|
|
110
112
|
language: old.language,
|
|
111
113
|
originalLanguage: old.language || null,
|
|
@@ -127,6 +129,7 @@ shaka.offline.indexeddb.V2StorageCell = class
|
|
|
127
129
|
closedCaptions: null,
|
|
128
130
|
tilesLayout: undefined,
|
|
129
131
|
external: false,
|
|
132
|
+
fastSwitching: false,
|
|
130
133
|
};
|
|
131
134
|
}
|
|
132
135
|
|
|
@@ -180,6 +180,7 @@ shaka.offline.ManifestConverter = class {
|
|
|
180
180
|
const stream = {
|
|
181
181
|
id: streamDB.id,
|
|
182
182
|
originalId: streamDB.originalId,
|
|
183
|
+
groupId: streamDB.groupId,
|
|
183
184
|
createSegmentIndex: () => Promise.resolve(),
|
|
184
185
|
segmentIndex,
|
|
185
186
|
mimeType: streamDB.mimeType,
|
|
@@ -189,6 +190,7 @@ shaka.offline.ManifestConverter = class {
|
|
|
189
190
|
frameRate: streamDB.frameRate,
|
|
190
191
|
pixelAspectRatio: streamDB.pixelAspectRatio,
|
|
191
192
|
hdr: streamDB.hdr,
|
|
193
|
+
videoLayout: streamDB.videoLayout,
|
|
192
194
|
kind: streamDB.kind,
|
|
193
195
|
encrypted: streamDB.encrypted,
|
|
194
196
|
drmInfos: [],
|
|
@@ -209,6 +211,7 @@ shaka.offline.ManifestConverter = class {
|
|
|
209
211
|
tilesLayout: streamDB.tilesLayout,
|
|
210
212
|
accessibilityPurpose: null,
|
|
211
213
|
external: streamDB.external,
|
|
214
|
+
fastSwitching: streamDB.fastSwitching,
|
|
212
215
|
};
|
|
213
216
|
|
|
214
217
|
return stream;
|
|
@@ -112,6 +112,16 @@ shaka.offline.OfflineManifestParser = class {
|
|
|
112
112
|
await muxer.destroy();
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
+
|
|
116
|
+
/** @override */
|
|
117
|
+
onInitialVariantChosen(variant) {
|
|
118
|
+
// No-op
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** @override */
|
|
122
|
+
banLocation(uri) {
|
|
123
|
+
// No-op
|
|
124
|
+
}
|
|
115
125
|
};
|
|
116
126
|
|
|
117
127
|
|
package/lib/offline/storage.js
CHANGED
|
@@ -12,6 +12,7 @@ goog.require('shaka.log');
|
|
|
12
12
|
goog.require('shaka.media.DrmEngine');
|
|
13
13
|
goog.require('shaka.media.ManifestParser');
|
|
14
14
|
goog.require('shaka.net.NetworkingEngine');
|
|
15
|
+
goog.require('shaka.net.NetworkingUtils');
|
|
15
16
|
goog.require('shaka.offline.DownloadInfo');
|
|
16
17
|
goog.require('shaka.offline.DownloadManager');
|
|
17
18
|
goog.require('shaka.offline.OfflineUri');
|
|
@@ -271,10 +272,13 @@ shaka.offline.Storage = class {
|
|
|
271
272
|
goog.asserts.assert(
|
|
272
273
|
this.networkingEngine_, 'Should not call |store| after |destroy|');
|
|
273
274
|
|
|
274
|
-
|
|
275
|
+
if (!mimeType) {
|
|
276
|
+
mimeType = await shaka.net.NetworkingUtils.getMimeType(
|
|
277
|
+
uri, this.networkingEngine_, config.manifest.retryParameters);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const factory = shaka.media.ManifestParser.getFactory(
|
|
275
281
|
uri,
|
|
276
|
-
this.networkingEngine_,
|
|
277
|
-
config.manifest.retryParameters,
|
|
278
282
|
mimeType || null);
|
|
279
283
|
|
|
280
284
|
return factory();
|
|
@@ -656,20 +660,19 @@ shaka.offline.Storage = class {
|
|
|
656
660
|
// Filter the manifest based on what we know MediaCapabilities will be able
|
|
657
661
|
// to play later (no point storing something we can't play).
|
|
658
662
|
await shaka.util.StreamUtils.filterManifestByMediaCapabilities(
|
|
659
|
-
manifest, config.offline.usePersistentLicense);
|
|
663
|
+
drmEngine, manifest, config.offline.usePersistentLicense);
|
|
660
664
|
|
|
661
665
|
// Gather all tracks.
|
|
662
666
|
const allTracks = [];
|
|
663
667
|
|
|
664
668
|
// Choose the codec that has the lowest average bandwidth.
|
|
665
|
-
const preferredAudioChannelCount = config.preferredAudioChannelCount;
|
|
666
669
|
const preferredDecodingAttributes = config.preferredDecodingAttributes;
|
|
667
670
|
const preferredVideoCodecs = config.preferredVideoCodecs;
|
|
668
671
|
const preferredAudioCodecs = config.preferredAudioCodecs;
|
|
669
672
|
|
|
670
673
|
shaka.util.StreamUtils.chooseCodecsAndFilterManifest(
|
|
671
674
|
manifest, preferredVideoCodecs, preferredAudioCodecs,
|
|
672
|
-
|
|
675
|
+
preferredDecodingAttributes);
|
|
673
676
|
|
|
674
677
|
for (const variant of manifest.variants) {
|
|
675
678
|
goog.asserts.assert(
|
|
@@ -1168,6 +1171,8 @@ shaka.offline.Storage = class {
|
|
|
1168
1171
|
enableLowLatencyMode: () => {},
|
|
1169
1172
|
updateDuration: () => {},
|
|
1170
1173
|
newDrmInfo: (stream) => {},
|
|
1174
|
+
onManifestUpdated: () => {},
|
|
1175
|
+
getBandwidthEstimate: () => config.abr.defaultBandwidthEstimate,
|
|
1171
1176
|
};
|
|
1172
1177
|
|
|
1173
1178
|
parser.configure(config.manifest);
|
|
@@ -1228,7 +1233,6 @@ shaka.offline.Storage = class {
|
|
|
1228
1233
|
drmEngine.configure(config.drm);
|
|
1229
1234
|
await drmEngine.initForStorage(
|
|
1230
1235
|
manifest.variants, config.offline.usePersistentLicense);
|
|
1231
|
-
await drmEngine.setServerCertificate();
|
|
1232
1236
|
await drmEngine.createOrLoad();
|
|
1233
1237
|
|
|
1234
1238
|
return drmEngine;
|
|
@@ -1299,6 +1303,7 @@ shaka.offline.Storage = class {
|
|
|
1299
1303
|
const streamDb = {
|
|
1300
1304
|
id: stream.id,
|
|
1301
1305
|
originalId: stream.originalId,
|
|
1306
|
+
groupId: stream.groupId,
|
|
1302
1307
|
primary: stream.primary,
|
|
1303
1308
|
type: stream.type,
|
|
1304
1309
|
mimeType: stream.mimeType,
|
|
@@ -1306,6 +1311,7 @@ shaka.offline.Storage = class {
|
|
|
1306
1311
|
frameRate: stream.frameRate,
|
|
1307
1312
|
pixelAspectRatio: stream.pixelAspectRatio,
|
|
1308
1313
|
hdr: stream.hdr,
|
|
1314
|
+
videoLayout: stream.videoLayout,
|
|
1309
1315
|
kind: stream.kind,
|
|
1310
1316
|
language: stream.language,
|
|
1311
1317
|
originalLanguage: stream.originalLanguage,
|
|
@@ -1324,6 +1330,7 @@ shaka.offline.Storage = class {
|
|
|
1324
1330
|
closedCaptions: stream.closedCaptions,
|
|
1325
1331
|
tilesLayout: stream.tilesLayout,
|
|
1326
1332
|
external: stream.external,
|
|
1333
|
+
fastSwitching: stream.fastSwitching,
|
|
1327
1334
|
};
|
|
1328
1335
|
|
|
1329
1336
|
const startTime =
|