shaka-player 3.1.4 → 3.3.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/ISSUE_TEMPLATE/feature_request.md +1 -1
- package/.github/ISSUE_TEMPLATE/question.md +1 -1
- package/AUTHORS +6 -5
- package/CHANGELOG.md +363 -0
- package/CONTRIBUTORS +4 -2
- package/README.md +4 -4
- package/build/types/core +3 -0
- package/build/types/offline +1 -0
- package/build/types/polyfill +2 -0
- package/build/types/ui +2 -0
- package/demo/common/asset.js +9 -7
- package/demo/common/assets.js +28 -1
- package/demo/common/message_ids.js +15 -2
- package/demo/config.js +35 -2
- package/demo/index.html +1 -1
- package/demo/locales/en.json +14 -1
- package/demo/locales/source.json +56 -4
- package/demo/main.js +2 -1
- package/dist/controls.css +26 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +24 -21
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +24 -21
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +33 -25
- package/dist/locales.js +31 -29
- package/dist/receiver.compiled.debug.js +14 -12
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +14 -12
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +258 -20
- package/dist/shaka-player.compiled.debug.d.ts +258 -20
- package/dist/shaka-player.compiled.debug.externs.js +1005 -695
- package/dist/shaka-player.compiled.debug.js +720 -640
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +1005 -695
- package/dist/shaka-player.compiled.js +850 -817
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +274 -21
- package/dist/shaka-player.ui.debug.d.ts +274 -21
- package/dist/shaka-player.ui.debug.externs.js +766 -429
- package/dist/shaka-player.ui.debug.js +863 -765
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +766 -429
- package/dist/shaka-player.ui.js +1042 -996
- package/dist/shaka-player.ui.map +4 -4
- package/docs/design/bg-fetch-after.gv +29 -0
- package/docs/design/bg-fetch-after.gv.png +0 -0
- package/docs/design/bg-fetch-before.gv +18 -0
- package/docs/design/bg-fetch-before.gv.png +0 -0
- package/docs/design/bg-fetch.md +134 -0
- package/docs/tutorials/blob-url.md +15 -0
- package/docs/tutorials/index.json +1 -0
- package/docs/tutorials/ui-customization.md +66 -0
- package/docs/tutorials/ui.md +5 -5
- package/externs/aria.js +6 -0
- package/externs/ima.js +3 -0
- package/externs/shaka/ads.js +29 -1
- package/externs/shaka/manifest.js +18 -2
- package/externs/shaka/manifest_parser.js +10 -1
- package/externs/shaka/net.js +20 -4
- package/externs/shaka/offline.js +36 -2
- package/externs/shaka/player.js +182 -13
- package/externs/shaka/text.js +24 -10
- package/externs/texttrack.js +3 -0
- package/externs/webcrypto.js +18 -0
- package/lib/abr/ewma.js +14 -0
- package/lib/abr/ewma_bandwidth_estimator.js +16 -2
- package/lib/abr/simple_abr_manager.js +6 -0
- package/lib/ads/ad_manager.js +16 -15
- package/lib/ads/client_side_ad.js +8 -0
- package/lib/ads/client_side_ad_manager.js +14 -6
- package/lib/ads/server_side_ad.js +7 -0
- package/lib/ads/server_side_ad_manager.js +19 -2
- package/lib/cast/cast_proxy.js +8 -0
- package/lib/cast/cast_utils.js +7 -1
- package/lib/cea/cea608_data_channel.js +56 -56
- package/lib/cea/cea608_memory.js +33 -33
- package/lib/cea/cea708_service.js +43 -43
- package/lib/cea/cea708_window.js +38 -38
- package/lib/cea/cea_decoder.js +13 -14
- package/lib/cea/cea_utils.js +23 -23
- package/lib/cea/dtvcc_packet_builder.js +7 -7
- package/lib/cea/i_caption_decoder.js +2 -3
- package/lib/cea/i_cea_parser.js +2 -2
- package/lib/cea/mp4_cea_parser.js +6 -6
- package/lib/dash/dash_parser.js +53 -14
- package/lib/dash/segment_base.js +25 -1
- package/lib/dash/segment_list.js +18 -9
- package/lib/dash/segment_template.js +23 -10
- package/lib/hls/hls_parser.js +210 -30
- package/lib/media/closed_caption_parser.js +1 -2
- package/lib/media/drm_engine.js +162 -192
- package/lib/media/quality_observer.js +291 -0
- package/lib/media/segment_index.js +9 -1
- package/lib/media/segment_reference.js +37 -5
- package/lib/media/streaming_engine.js +48 -10
- package/lib/net/http_fetch_plugin.js +31 -11
- package/lib/net/http_plugin_utils.js +1 -0
- package/lib/net/http_xhr_plugin.js +40 -14
- package/lib/net/networking_engine.js +82 -18
- package/lib/offline/download_info.js +68 -0
- package/lib/offline/download_manager.js +14 -7
- package/lib/offline/indexeddb/base_storage_cell.js +35 -0
- package/lib/offline/indexeddb/storage_mechanism.js +1 -1
- package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v5_storage_cell.js +5 -0
- package/lib/offline/manifest_converter.js +3 -1
- package/lib/offline/storage.js +404 -297
- package/lib/offline/stored_content_utils.js +2 -0
- package/lib/player.js +622 -153
- package/lib/polyfill/aria.js +82 -0
- package/lib/polyfill/random_uuid.js +52 -0
- package/lib/routing/walker.js +2 -3
- package/lib/text/cue.js +12 -0
- package/lib/text/srt_text_parser.js +4 -4
- package/lib/text/text_engine.js +2 -2
- package/lib/text/ttml_text_parser.js +25 -2
- package/lib/text/ui_text_displayer.js +2 -2
- package/lib/text/vtt_text_parser.js +2 -2
- package/lib/text/web_vtt_generator.js +55 -12
- package/lib/util/cmcd_manager.js +826 -0
- package/lib/util/error.js +12 -0
- package/lib/util/language_utils.js +12 -0
- package/lib/util/manifest_parser_utils.js +1 -0
- package/lib/util/mp4_box_parsers.js +20 -20
- package/lib/util/multi_map.js +8 -0
- package/lib/util/mutex.js +52 -0
- package/lib/util/periods.js +98 -64
- package/lib/util/player_configuration.js +31 -1
- package/lib/util/stream_utils.js +140 -85
- package/lib/util/xml_utils.js +31 -12
- package/package.json +1 -1
- package/roadmap.md +24 -22
- package/shaka-player.uncompiled.js +4 -0
- package/test/cast/cast_utils_unit.js +1 -0
- package/test/cea/cea608_memory_unit.js +1 -1
- package/test/cea/cea708_service_unit.js +8 -8
- package/test/cea/cea708_window_unit.js +6 -6
- package/test/cea/cea_decoder_unit.js +1 -1
- package/test/cea/dtvcc_packet_builder_unit.js +2 -2
- package/test/dash/dash_parser_content_protection_unit.js +2 -0
- package/test/dash/dash_parser_live_unit.js +101 -1
- package/test/dash/dash_parser_manifest_unit.js +78 -2
- package/test/dash/dash_parser_segment_base_unit.js +2 -0
- package/test/dash/dash_parser_segment_list_unit.js +2 -1
- package/test/dash/dash_parser_segment_template_unit.js +2 -1
- package/test/hls/hls_live_unit.js +2 -0
- package/test/hls/hls_parser_unit.js +252 -0
- package/test/media/drm_engine_integration.js +86 -12
- package/test/media/drm_engine_unit.js +310 -450
- package/test/media/quality_observer_unit.js +139 -0
- package/test/media/segment_reference_unit.js +16 -1
- package/test/media/streaming_engine_integration.js +2 -1
- package/test/media/streaming_engine_unit.js +2 -0
- package/test/net/http_plugin_unit.js +20 -15
- package/test/offline/manifest_convert_unit.js +2 -0
- package/test/offline/storage_integration.js +117 -23
- package/test/player_integration.js +151 -0
- package/test/player_src_equals_integration.js +52 -0
- package/test/player_unit.js +11 -33
- package/test/test/assets/chapters.srt +11 -0
- package/test/test/assets/chapters.vtt +10 -0
- package/test/test/util/cea_utils.js +12 -12
- package/test/test/util/dash_parser_util.js +4 -0
- package/test/test/util/fake_ad.js +7 -0
- package/test/test/util/fake_ad_manager.js +7 -0
- package/test/test/util/fake_drm_engine.js +9 -2
- package/test/test/util/manifest_generator.js +5 -2
- package/test/test/util/manifest_parser_util.js +3 -1
- package/test/test/util/test_scheme.js +14 -1
- package/test/text/ttml_text_parser_unit.js +47 -0
- package/test/text/web_vtt_generator_unit.js +81 -7
- package/test/ui/ui_unit.js +250 -0
- package/test/util/cmcd_manager_unit.js +277 -0
- package/test/util/stream_utils_unit.js +118 -10
- package/ui/airplay_button.js +2 -1
- package/ui/audio_language_selection.js +9 -5
- package/ui/cast_button.js +5 -6
- package/ui/constants.js +0 -3
- package/ui/context_menu.js +109 -0
- package/ui/controls.js +41 -7
- package/ui/controls.less +1 -0
- package/ui/enums.js +4 -0
- package/ui/externs/ui.js +28 -1
- package/ui/fast_forward_button.js +16 -8
- package/ui/fullscreen_button.js +2 -3
- package/ui/language_utils.js +1 -1
- package/ui/less/buttons.less +0 -4
- package/ui/less/containers.less +74 -0
- package/ui/less/overflow_menu.less +0 -10
- package/ui/less/tooltip.less +97 -0
- package/ui/locales/en.json +1 -0
- package/ui/locales/source.json +4 -0
- package/ui/loop_button.js +6 -3
- package/ui/mute_button.js +3 -4
- package/ui/overflow_menu.js +7 -28
- package/ui/pip_button.js +10 -7
- package/ui/play_button.js +2 -2
- package/ui/playback_rate_selection.js +11 -15
- package/ui/presentation_time.js +1 -3
- package/ui/resolution_selection.js +11 -7
- package/ui/rewind_button.js +17 -9
- package/ui/seek_bar.js +6 -6
- package/ui/settings_menu.js +36 -4
- package/ui/small_play_button.js +1 -0
- package/ui/spacer.js +1 -1
- package/ui/statistics_button.js +253 -0
- package/ui/text_selection.js +19 -15
- package/ui/ui.js +30 -0
- package/ui/ui_utils.js +1 -1
- package/ui/volume_bar.js +2 -4
package/lib/util/error.js
CHANGED
|
@@ -814,6 +814,12 @@ shaka.util.Error.Code = {
|
|
|
814
814
|
*/
|
|
815
815
|
'INIT_DATA_TRANSFORM_ERROR': 6016,
|
|
816
816
|
|
|
817
|
+
/**
|
|
818
|
+
* The server certificate request failed.
|
|
819
|
+
* <br> error.data[0] is a shaka.util.Error from the networking engine.
|
|
820
|
+
*/
|
|
821
|
+
'SERVER_CERTIFICATE_REQUEST_FAILED': 6017,
|
|
822
|
+
|
|
817
823
|
|
|
818
824
|
/**
|
|
819
825
|
* The call to Player.load() was interrupted by a call to Player.unload()
|
|
@@ -980,6 +986,12 @@ shaka.util.Error.Code = {
|
|
|
980
986
|
*/
|
|
981
987
|
'DOWNLOAD_SIZE_CALLBACK_ERROR': 9015,
|
|
982
988
|
|
|
989
|
+
/**
|
|
990
|
+
* The storage cell does not allow new operations that significantly change
|
|
991
|
+
* existing data.
|
|
992
|
+
*/
|
|
993
|
+
'MODIFY_OPERATION_NOT_SUPPORTED': 9016,
|
|
994
|
+
|
|
983
995
|
/**
|
|
984
996
|
* CS IMA SDK, required for ad insertion, has not been included on the page.
|
|
985
997
|
*/
|
|
@@ -13,6 +13,7 @@ goog.require('shaka.util.ManifestParserUtils');
|
|
|
13
13
|
/**
|
|
14
14
|
* @summary A set of language utility functions.
|
|
15
15
|
* @final
|
|
16
|
+
* @export
|
|
16
17
|
*/
|
|
17
18
|
shaka.util.LanguageUtils = class {
|
|
18
19
|
/**
|
|
@@ -32,6 +33,7 @@ shaka.util.LanguageUtils = class {
|
|
|
32
33
|
* @param {string} locale1
|
|
33
34
|
* @param {string} locale2
|
|
34
35
|
* @return {boolean}
|
|
36
|
+
* @export
|
|
35
37
|
*/
|
|
36
38
|
static areLocaleCompatible(locale1, locale2) {
|
|
37
39
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
@@ -62,6 +64,7 @@ shaka.util.LanguageUtils = class {
|
|
|
62
64
|
* @param {string} locale1
|
|
63
65
|
* @param {string} locale2
|
|
64
66
|
* @return {boolean}
|
|
67
|
+
* @export
|
|
65
68
|
*/
|
|
66
69
|
static areLanguageCompatible(locale1, locale2) {
|
|
67
70
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
@@ -102,6 +105,7 @@ shaka.util.LanguageUtils = class {
|
|
|
102
105
|
* @param {string} possibleParent
|
|
103
106
|
* @param {string} possibleChild
|
|
104
107
|
* @return {boolean}
|
|
108
|
+
* @export
|
|
105
109
|
*/
|
|
106
110
|
static isParentOf(possibleParent, possibleChild) {
|
|
107
111
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
@@ -146,6 +150,7 @@ shaka.util.LanguageUtils = class {
|
|
|
146
150
|
* @param {string} localeA
|
|
147
151
|
* @param {string} localeB
|
|
148
152
|
* @return {boolean}
|
|
153
|
+
* @export
|
|
149
154
|
*/
|
|
150
155
|
static isSiblingOf(localeA, localeB) {
|
|
151
156
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
@@ -181,6 +186,7 @@ shaka.util.LanguageUtils = class {
|
|
|
181
186
|
*
|
|
182
187
|
* @param {string} locale
|
|
183
188
|
* @return {string}
|
|
189
|
+
* @export
|
|
184
190
|
*/
|
|
185
191
|
static normalize(locale) {
|
|
186
192
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
@@ -217,6 +223,7 @@ shaka.util.LanguageUtils = class {
|
|
|
217
223
|
* @param {string} a
|
|
218
224
|
* @param {string} b
|
|
219
225
|
* @return {boolean}
|
|
226
|
+
* @export
|
|
220
227
|
*/
|
|
221
228
|
static areSiblings(a, b) {
|
|
222
229
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
@@ -235,6 +242,7 @@ shaka.util.LanguageUtils = class {
|
|
|
235
242
|
* @param {string} target
|
|
236
243
|
* @param {string} candidate
|
|
237
244
|
* @return {number}
|
|
245
|
+
* @export
|
|
238
246
|
*/
|
|
239
247
|
static relatedness(target, candidate) {
|
|
240
248
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
@@ -271,6 +279,7 @@ shaka.util.LanguageUtils = class {
|
|
|
271
279
|
*
|
|
272
280
|
* @param {string} lang
|
|
273
281
|
* @return {string}
|
|
282
|
+
* @export
|
|
274
283
|
*/
|
|
275
284
|
static getBase(lang) {
|
|
276
285
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
@@ -300,6 +309,7 @@ shaka.util.LanguageUtils = class {
|
|
|
300
309
|
*
|
|
301
310
|
* @param {shaka.extern.Stream} stream
|
|
302
311
|
* @return {string}
|
|
312
|
+
* @export
|
|
303
313
|
*/
|
|
304
314
|
static getLocaleForText(stream) {
|
|
305
315
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
@@ -322,6 +332,7 @@ shaka.util.LanguageUtils = class {
|
|
|
322
332
|
*
|
|
323
333
|
* @param {shaka.extern.Variant} variant
|
|
324
334
|
* @return {string}
|
|
335
|
+
* @export
|
|
325
336
|
*/
|
|
326
337
|
static getLocaleForVariant(variant) {
|
|
327
338
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
@@ -356,6 +367,7 @@ shaka.util.LanguageUtils = class {
|
|
|
356
367
|
* @param {string} target
|
|
357
368
|
* @param {!Iterable.<string>} searchSpace
|
|
358
369
|
* @return {?string}
|
|
370
|
+
* @export
|
|
359
371
|
*/
|
|
360
372
|
static findClosestLocale(target, searchSpace) {
|
|
361
373
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
@@ -14,7 +14,7 @@ shaka.util.Mp4BoxParsers = class {
|
|
|
14
14
|
/**
|
|
15
15
|
* Parses a TFHD Box.
|
|
16
16
|
* @param {!shaka.util.DataViewReader} reader
|
|
17
|
-
* @param {
|
|
17
|
+
* @param {number} flags
|
|
18
18
|
* @return {!shaka.util.ParsedTFHDBox}
|
|
19
19
|
*/
|
|
20
20
|
static parseTFHD(reader, flags) {
|
|
@@ -53,7 +53,7 @@ shaka.util.Mp4BoxParsers = class {
|
|
|
53
53
|
/**
|
|
54
54
|
* Parses a TFDT Box.
|
|
55
55
|
* @param {!shaka.util.DataViewReader} reader
|
|
56
|
-
* @param {
|
|
56
|
+
* @param {number} version
|
|
57
57
|
* @return {!shaka.util.ParsedTFDTBox}
|
|
58
58
|
*/
|
|
59
59
|
static parseTFDT(reader, version) {
|
|
@@ -68,7 +68,7 @@ shaka.util.Mp4BoxParsers = class {
|
|
|
68
68
|
/**
|
|
69
69
|
* Parses a MDHD Box.
|
|
70
70
|
* @param {!shaka.util.DataViewReader} reader
|
|
71
|
-
* @param {
|
|
71
|
+
* @param {number} version
|
|
72
72
|
* @return {!shaka.util.ParsedMDHDBox}
|
|
73
73
|
*/
|
|
74
74
|
static parseMDHD(reader, version) {
|
|
@@ -107,8 +107,8 @@ shaka.util.Mp4BoxParsers = class {
|
|
|
107
107
|
/**
|
|
108
108
|
* Parses a TRUN Box.
|
|
109
109
|
* @param {!shaka.util.DataViewReader} reader
|
|
110
|
-
* @param {
|
|
111
|
-
* @param {
|
|
110
|
+
* @param {number} version
|
|
111
|
+
* @param {number} flags
|
|
112
112
|
* @return {!shaka.util.ParsedTRUNBox}
|
|
113
113
|
*/
|
|
114
114
|
static parseTRUN(reader, version, flags) {
|
|
@@ -168,7 +168,7 @@ shaka.util.Mp4BoxParsers = class {
|
|
|
168
168
|
/**
|
|
169
169
|
* Parses a TKHD Box.
|
|
170
170
|
* @param {!shaka.util.DataViewReader} reader
|
|
171
|
-
* @param {
|
|
171
|
+
* @param {number} version
|
|
172
172
|
* @return {!shaka.util.ParsedTKHDBox}
|
|
173
173
|
*/
|
|
174
174
|
static parseTKHD(reader, version) {
|
|
@@ -192,12 +192,12 @@ shaka.util.Mp4BoxParsers = class {
|
|
|
192
192
|
|
|
193
193
|
/**
|
|
194
194
|
* @typedef {{
|
|
195
|
-
* trackId:
|
|
195
|
+
* trackId: number,
|
|
196
196
|
* defaultSampleDuration: ?number,
|
|
197
197
|
* defaultSampleSize: ?number
|
|
198
198
|
* }}
|
|
199
199
|
*
|
|
200
|
-
* @property {
|
|
200
|
+
* @property {number} trackId
|
|
201
201
|
* As per the spec: an integer that uniquely identifies this
|
|
202
202
|
* track over the entire life‐time of this presentation
|
|
203
203
|
* @property {?number} defaultSampleDuration
|
|
@@ -213,10 +213,10 @@ shaka.util.ParsedTFHDBox;
|
|
|
213
213
|
|
|
214
214
|
/**
|
|
215
215
|
* @typedef {{
|
|
216
|
-
* baseMediaDecodeTime:
|
|
216
|
+
* baseMediaDecodeTime: number
|
|
217
217
|
* }}
|
|
218
218
|
*
|
|
219
|
-
* @property {
|
|
219
|
+
* @property {number} baseMediaDecodeTime
|
|
220
220
|
* As per the spec: the absolute decode time, measured on the media
|
|
221
221
|
* timeline, of the first sample in decode order in the track fragment
|
|
222
222
|
*
|
|
@@ -226,10 +226,10 @@ shaka.util.ParsedTFDTBox;
|
|
|
226
226
|
|
|
227
227
|
/**
|
|
228
228
|
* @typedef {{
|
|
229
|
-
* timescale:
|
|
229
|
+
* timescale: number
|
|
230
230
|
* }}
|
|
231
231
|
*
|
|
232
|
-
* @property {
|
|
232
|
+
* @property {number} timescale
|
|
233
233
|
* As per the spec: an integer that specifies the time‐scale for this media;
|
|
234
234
|
* this is the number of time units that pass in one second
|
|
235
235
|
*
|
|
@@ -239,13 +239,13 @@ shaka.util.ParsedMDHDBox;
|
|
|
239
239
|
|
|
240
240
|
/**
|
|
241
241
|
* @typedef {{
|
|
242
|
-
* defaultSampleDuration:
|
|
243
|
-
* defaultSampleSize:
|
|
242
|
+
* defaultSampleDuration: number,
|
|
243
|
+
* defaultSampleSize: number
|
|
244
244
|
* }}
|
|
245
245
|
*
|
|
246
|
-
* @property {
|
|
246
|
+
* @property {number} defaultSampleDuration
|
|
247
247
|
* The default sample duration to be used in track fragments
|
|
248
|
-
* @property {
|
|
248
|
+
* @property {number} defaultSampleSize
|
|
249
249
|
* The default sample size to be used in track fragments
|
|
250
250
|
*
|
|
251
251
|
* @exportDoc
|
|
@@ -254,11 +254,11 @@ shaka.util.ParsedTREXBox;
|
|
|
254
254
|
|
|
255
255
|
/**
|
|
256
256
|
* @typedef {{
|
|
257
|
-
* sampleCount:
|
|
257
|
+
* sampleCount: number,
|
|
258
258
|
* sampleData: !Array.<shaka.util.ParsedTRUNSample>
|
|
259
259
|
* }}
|
|
260
260
|
*
|
|
261
|
-
* @property {
|
|
261
|
+
* @property {number} sampleCount
|
|
262
262
|
* As per the spec: the number of samples being added in this run;
|
|
263
263
|
* @property {!Array.<shaka.util.ParsedTRUNSample>} sampleData
|
|
264
264
|
* An array of size <sampleCount> containing data for each sample
|
|
@@ -290,10 +290,10 @@ shaka.util.ParsedTRUNSample;
|
|
|
290
290
|
|
|
291
291
|
/**
|
|
292
292
|
* @typedef {{
|
|
293
|
-
* trackId:
|
|
293
|
+
* trackId: number
|
|
294
294
|
* }}
|
|
295
295
|
*
|
|
296
|
-
* @property {
|
|
296
|
+
* @property {number} trackId
|
|
297
297
|
* Unique ID indicative of this track
|
|
298
298
|
*
|
|
299
299
|
* @exportDoc
|
package/lib/util/multi_map.js
CHANGED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
goog.provide('shaka.util.Mutex');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @summary A simple mutex.
|
|
12
|
+
*/
|
|
13
|
+
shaka.util.Mutex = class {
|
|
14
|
+
/** Creates the mutex. */
|
|
15
|
+
constructor() {
|
|
16
|
+
/** @private {!Array.<function()>} */
|
|
17
|
+
this.waiting_ = [];
|
|
18
|
+
|
|
19
|
+
/** @private {number} */
|
|
20
|
+
this.nextMutexId_ = 0;
|
|
21
|
+
|
|
22
|
+
/** @private {number} */
|
|
23
|
+
this.acquiredMutexId_ = 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** @return {!Promise.<number>} mutexId */
|
|
27
|
+
async acquire() {
|
|
28
|
+
const mutexId = ++this.nextMutexId_;
|
|
29
|
+
if (!this.acquiredMutexId_) {
|
|
30
|
+
this.acquiredMutexId_ = mutexId;
|
|
31
|
+
} else {
|
|
32
|
+
await (new Promise((resolve, reject) => {
|
|
33
|
+
this.waiting_.push(() => {
|
|
34
|
+
this.acquiredMutexId_ = mutexId;
|
|
35
|
+
resolve();
|
|
36
|
+
});
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
return mutexId;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** @param {number} mutexId */
|
|
43
|
+
release(mutexId) {
|
|
44
|
+
if (mutexId == this.acquiredMutexId_) {
|
|
45
|
+
this.acquiredMutexId_ = 0;
|
|
46
|
+
if (this.waiting_.length > 0) {
|
|
47
|
+
const callback = this.waiting_.shift();
|
|
48
|
+
callback();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
package/lib/util/periods.js
CHANGED
|
@@ -547,8 +547,7 @@ shaka.util.PeriodCombiner = class {
|
|
|
547
547
|
for (const stream of unusedStreams) {
|
|
548
548
|
// Create a new output stream which includes this input stream.
|
|
549
549
|
const outputStream =
|
|
550
|
-
|
|
551
|
-
await shaka.util.PeriodCombiner.createNewOutputStream_(
|
|
550
|
+
shaka.util.PeriodCombiner.createNewOutputStream_(
|
|
552
551
|
stream, streamsPerPeriod, clone, concat,
|
|
553
552
|
unusedStreamsPerPeriod);
|
|
554
553
|
if (outputStream) {
|
|
@@ -619,52 +618,69 @@ shaka.util.PeriodCombiner = class {
|
|
|
619
618
|
static async extendExistingOutputStream_(
|
|
620
619
|
outputStream, streamsPerPeriod, firstNewPeriodIndex, concat,
|
|
621
620
|
unusedStreamsPerPeriod) {
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
if (!matches) {
|
|
626
|
-
// We were unable to extend this output stream.
|
|
627
|
-
shaka.log.error('No matches extending output stream!',
|
|
628
|
-
outputStream, streamsPerPeriod);
|
|
629
|
-
return false;
|
|
630
|
-
}
|
|
621
|
+
shaka.util.PeriodCombiner.findMatchesInAllPeriods_(streamsPerPeriod,
|
|
622
|
+
outputStream);
|
|
631
623
|
|
|
632
624
|
// This only exists where T == Stream, and this should only ever be called
|
|
633
625
|
// on Stream types. StreamDB should not have pre-existing output streams.
|
|
634
626
|
goog.asserts.assert(outputStream.createSegmentIndex,
|
|
635
627
|
'outputStream should be a Stream type!');
|
|
636
628
|
|
|
629
|
+
if (!outputStream.matchedStreams) {
|
|
630
|
+
// We were unable to extend this output stream.
|
|
631
|
+
shaka.log.error('No matches extending output stream!',
|
|
632
|
+
outputStream, streamsPerPeriod);
|
|
633
|
+
return false;
|
|
634
|
+
}
|
|
637
635
|
// We need to create all the per-period segment indexes and append them to
|
|
638
636
|
// the output's MetaSegmentIndex.
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
goog.asserts.assert(matches, 'Matches should be non-null');
|
|
637
|
+
if (outputStream.segmentIndex) {
|
|
638
|
+
await shaka.util.PeriodCombiner.extendOutputSegmentIndex_(outputStream,
|
|
639
|
+
firstNewPeriodIndex);
|
|
640
|
+
}
|
|
644
641
|
|
|
645
|
-
shaka.util.PeriodCombiner.extendOutputStream_(
|
|
646
|
-
|
|
647
|
-
unusedStreamsPerPeriod);
|
|
642
|
+
shaka.util.PeriodCombiner.extendOutputStream_(outputStream,
|
|
643
|
+
firstNewPeriodIndex, concat, unusedStreamsPerPeriod);
|
|
648
644
|
return true;
|
|
649
645
|
}
|
|
650
646
|
|
|
651
647
|
/**
|
|
652
|
-
* Creates
|
|
653
|
-
* segment index
|
|
648
|
+
* Creates the segment indexes for an array of input streams, and append them
|
|
649
|
+
* to the output stream's segment index.
|
|
654
650
|
*
|
|
655
|
-
* @param {
|
|
656
|
-
* @
|
|
651
|
+
* @param {shaka.extern.Stream} outputStream
|
|
652
|
+
* @param {number} firstNewPeriodIndex An index into streamsPerPeriod which
|
|
653
|
+
* represents the first new period that hasn't been processed yet.
|
|
657
654
|
* @private
|
|
658
655
|
*/
|
|
659
|
-
static
|
|
656
|
+
static async extendOutputSegmentIndex_(outputStream, firstNewPeriodIndex) {
|
|
660
657
|
const operations = [];
|
|
658
|
+
const streams = outputStream.matchedStreams;
|
|
659
|
+
goog.asserts.assert(streams, 'matched streams should be valid');
|
|
660
|
+
|
|
661
661
|
for (const stream of streams) {
|
|
662
662
|
operations.push(stream.createSegmentIndex());
|
|
663
663
|
if (stream.trickModeVideo && !stream.trickModeVideo.segmentIndex) {
|
|
664
664
|
operations.push(stream.trickModeVideo.createSegmentIndex());
|
|
665
665
|
}
|
|
666
666
|
}
|
|
667
|
-
|
|
667
|
+
await Promise.all(operations);
|
|
668
|
+
|
|
669
|
+
// Concatenate the new matches onto the stream, starting at the first new
|
|
670
|
+
// period.
|
|
671
|
+
const Iterables = shaka.util.Iterables;
|
|
672
|
+
// Satisfy the compiler about the type.
|
|
673
|
+
// Also checks if the segmentIndex is still valid after the async
|
|
674
|
+
// operations, to make sure we stop if the active stream has changed.
|
|
675
|
+
if (outputStream.segmentIndex instanceof shaka.media.MetaSegmentIndex) {
|
|
676
|
+
for (const {i, item: match} of Iterables.enumerate(streams)) {
|
|
677
|
+
if (match.segmentIndex && i >= firstNewPeriodIndex) {
|
|
678
|
+
goog.asserts.assert(match.segmentIndex,
|
|
679
|
+
'stream should have a segmentIndex.');
|
|
680
|
+
outputStream.segmentIndex.appendSegmentIndex(match.segmentIndex);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
}
|
|
668
684
|
}
|
|
669
685
|
|
|
670
686
|
/**
|
|
@@ -682,7 +698,7 @@ shaka.util.PeriodCombiner = class {
|
|
|
682
698
|
* @param {!Array.<!Set.<T>>} unusedStreamsPerPeriod An array of sets of
|
|
683
699
|
* unused streams from each period.
|
|
684
700
|
*
|
|
685
|
-
* @return {
|
|
701
|
+
* @return {?T} A newly-created output Stream, or null if matches
|
|
686
702
|
* could not be found.`
|
|
687
703
|
*
|
|
688
704
|
* @template T
|
|
@@ -690,35 +706,36 @@ shaka.util.PeriodCombiner = class {
|
|
|
690
706
|
*
|
|
691
707
|
* @private
|
|
692
708
|
*/
|
|
693
|
-
static
|
|
709
|
+
static createNewOutputStream_(
|
|
694
710
|
stream, streamsPerPeriod, clone, concat, unusedStreamsPerPeriod) {
|
|
695
711
|
// Start by cloning the stream without segments, key IDs, etc.
|
|
696
712
|
const outputStream = clone(stream);
|
|
697
713
|
|
|
698
714
|
// Find best-matching streams in all periods.
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
if (!matches) {
|
|
703
|
-
// This is not a stream we can build output from, but it may become part
|
|
704
|
-
// of another output based on another period's stream.
|
|
705
|
-
return null;
|
|
706
|
-
}
|
|
715
|
+
shaka.util.PeriodCombiner.findMatchesInAllPeriods_(streamsPerPeriod,
|
|
716
|
+
outputStream);
|
|
707
717
|
|
|
708
718
|
// This only exists where T == Stream.
|
|
709
719
|
if (outputStream.createSegmentIndex) {
|
|
720
|
+
// Override the createSegmentIndex function of the outputStream.
|
|
721
|
+
outputStream.createSegmentIndex = async () => {
|
|
722
|
+
if (!outputStream.segmentIndex) {
|
|
723
|
+
outputStream.segmentIndex = new shaka.media.MetaSegmentIndex();
|
|
724
|
+
await shaka.util.PeriodCombiner.extendOutputSegmentIndex_(
|
|
725
|
+
outputStream, /* firstNewPeriodIndex= */ 0);
|
|
726
|
+
}
|
|
727
|
+
};
|
|
710
728
|
// For T == Stream, we need to create all the per-period segment indexes
|
|
711
729
|
// in advance. concat() will add them to the output's MetaSegmentIndex.
|
|
712
|
-
await shaka.util.PeriodCombiner.createSegmentIndexes_(matches);
|
|
713
730
|
}
|
|
714
731
|
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
unusedStreamsPerPeriod);
|
|
732
|
+
if (!outputStream.matchedStreams) {
|
|
733
|
+
// This is not a stream we can build output from, but it may become part
|
|
734
|
+
// of another output based on another period's stream.
|
|
735
|
+
return null;
|
|
736
|
+
}
|
|
737
|
+
shaka.util.PeriodCombiner.extendOutputStream_(outputStream,
|
|
738
|
+
/* firstNewPeriodIndex= */ 0, concat, unusedStreamsPerPeriod);
|
|
722
739
|
|
|
723
740
|
return outputStream;
|
|
724
741
|
}
|
|
@@ -726,7 +743,6 @@ shaka.util.PeriodCombiner = class {
|
|
|
726
743
|
/**
|
|
727
744
|
* @param {T} outputStream An existing output stream which needs to be
|
|
728
745
|
* extended into new periods.
|
|
729
|
-
* @param {!Array.<T>} matches A list of matching Streams from each period.
|
|
730
746
|
* @param {number} firstNewPeriodIndex An index into streamsPerPeriod which
|
|
731
747
|
* represents the first new period that hasn't been processed yet.
|
|
732
748
|
* @param {function(T, T)} concat Concatenate the second stream onto the end
|
|
@@ -740,10 +756,15 @@ shaka.util.PeriodCombiner = class {
|
|
|
740
756
|
* @private
|
|
741
757
|
*/
|
|
742
758
|
static extendOutputStream_(
|
|
743
|
-
outputStream,
|
|
744
|
-
unusedStreamsPerPeriod) {
|
|
759
|
+
outputStream, firstNewPeriodIndex, concat, unusedStreamsPerPeriod) {
|
|
745
760
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
746
761
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
762
|
+
const matches = outputStream.matchedStreams;
|
|
763
|
+
|
|
764
|
+
// Assure the compiler that matches didn't become null during the async
|
|
765
|
+
// operation before.
|
|
766
|
+
goog.asserts.assert(outputStream.matchedStreams,
|
|
767
|
+
'matchedStreams should be non-null');
|
|
747
768
|
|
|
748
769
|
// Concatenate the new matches onto the stream, starting at the first new
|
|
749
770
|
// period.
|
|
@@ -787,7 +808,23 @@ shaka.util.PeriodCombiner = class {
|
|
|
787
808
|
// streams that match this output.
|
|
788
809
|
clone.originalId = null;
|
|
789
810
|
clone.createSegmentIndex = () => Promise.resolve();
|
|
790
|
-
clone.
|
|
811
|
+
clone.closeSegmentIndex = () => {
|
|
812
|
+
if (clone.segmentIndex) {
|
|
813
|
+
clone.segmentIndex.release();
|
|
814
|
+
clone.segmentIndex = null;
|
|
815
|
+
}
|
|
816
|
+
// Close the segment index of the matched streams.
|
|
817
|
+
if (clone.matchedStreams) {
|
|
818
|
+
for (const match of clone.matchedStreams) {
|
|
819
|
+
if (match.segmentIndex) {
|
|
820
|
+
match.segmentIndex.release();
|
|
821
|
+
match.segmentIndex = null;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
|
|
827
|
+
clone.segmentIndex = null;
|
|
791
828
|
clone.emsgSchemeIdUris = [];
|
|
792
829
|
clone.keyIds = new Set();
|
|
793
830
|
clone.closedCaptions = null;
|
|
@@ -873,26 +910,24 @@ shaka.util.PeriodCombiner = class {
|
|
|
873
910
|
}
|
|
874
911
|
}
|
|
875
912
|
|
|
876
|
-
// Satisfy the compiler about the type.
|
|
877
|
-
goog.asserts.assert(
|
|
878
|
-
output.segmentIndex instanceof shaka.media.MetaSegmentIndex,
|
|
879
|
-
'Output streams should have a MetaSegmentIndex!');
|
|
880
|
-
// Satisfy the compiler that the input index has been created.
|
|
881
|
-
goog.asserts.assert(
|
|
882
|
-
input.segmentIndex,
|
|
883
|
-
'Input segment index should have been created by now!');
|
|
884
|
-
|
|
885
|
-
output.segmentIndex.appendSegmentIndex(input.segmentIndex);
|
|
886
|
-
|
|
887
913
|
// Combine trick-play video streams, if present.
|
|
888
914
|
if (input.trickModeVideo) {
|
|
889
915
|
if (!output.trickModeVideo) {
|
|
890
916
|
// Create a fresh output stream for trick-mode playback.
|
|
891
917
|
output.trickModeVideo = shaka.util.PeriodCombiner.cloneStream_(
|
|
892
918
|
input.trickModeVideo);
|
|
893
|
-
//
|
|
894
|
-
//
|
|
895
|
-
|
|
919
|
+
// TODO: fix the createSegmentIndex function for trickModeVideo.
|
|
920
|
+
// The trick-mode tracks in multi-period content should have trick-mode
|
|
921
|
+
// segment indexes whenever available, rather than only regular-mode
|
|
922
|
+
// segment indexes.
|
|
923
|
+
output.trickModeVideo.createSegmentIndex = () => {
|
|
924
|
+
// Satisfy the compiler about the type.
|
|
925
|
+
goog.asserts.assert(
|
|
926
|
+
output.segmentIndex instanceof shaka.media.MetaSegmentIndex,
|
|
927
|
+
'The stream should have a MetaSegmentIndex.');
|
|
928
|
+
output.trickModeVideo.segmentIndex = output.segmentIndex.clone();
|
|
929
|
+
return Promise.resolve();
|
|
930
|
+
};
|
|
896
931
|
}
|
|
897
932
|
|
|
898
933
|
// Concatenate the trick mode input onto the trick mode output.
|
|
@@ -943,7 +978,6 @@ shaka.util.PeriodCombiner = class {
|
|
|
943
978
|
*
|
|
944
979
|
* @param {!Array.<!Array.<T>>} streamsPerPeriod
|
|
945
980
|
* @param {T} outputStream
|
|
946
|
-
* @return {Array.<T>}
|
|
947
981
|
*
|
|
948
982
|
* @template T
|
|
949
983
|
* Accepts either a StreamDB or Stream type.
|
|
@@ -956,11 +990,11 @@ shaka.util.PeriodCombiner = class {
|
|
|
956
990
|
const match = shaka.util.PeriodCombiner.findBestMatchInPeriod_(
|
|
957
991
|
streams, outputStream);
|
|
958
992
|
if (!match) {
|
|
959
|
-
return
|
|
993
|
+
return;
|
|
960
994
|
}
|
|
961
995
|
matches.push(match);
|
|
962
996
|
}
|
|
963
|
-
|
|
997
|
+
outputStream.matchedStreams = matches;
|
|
964
998
|
}
|
|
965
999
|
|
|
966
1000
|
/**
|
|
@@ -75,6 +75,7 @@ shaka.util.PlayerConfiguration = class {
|
|
|
75
75
|
initDataTransform: shaka.media.DrmEngine.defaultInitDataTransform,
|
|
76
76
|
logLicenseExchange: false,
|
|
77
77
|
updateExpirationTime: 1,
|
|
78
|
+
preferredKeySystems: [],
|
|
78
79
|
};
|
|
79
80
|
|
|
80
81
|
const manifest = {
|
|
@@ -108,10 +109,19 @@ shaka.util.PlayerConfiguration = class {
|
|
|
108
109
|
'urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb':
|
|
109
110
|
'com.adobe.primetime',
|
|
110
111
|
},
|
|
112
|
+
// Need some operation in the callback or else closure may remove calls
|
|
113
|
+
// to the function as it would be a no-op. The operation can't just be
|
|
114
|
+
// a log message, because those are stripped in the compiled build.
|
|
115
|
+
manifestPreprocessor: (element) => {
|
|
116
|
+
return element;
|
|
117
|
+
},
|
|
111
118
|
},
|
|
112
119
|
hls: {
|
|
113
120
|
ignoreTextStreamFailures: false,
|
|
121
|
+
ignoreImageStreamFailures: false,
|
|
114
122
|
useFullSegmentsForStartTime: false,
|
|
123
|
+
defaultAudioCodec: 'mp4a.40.2',
|
|
124
|
+
defaultVideoCodec: 'avc1.42E01E',
|
|
115
125
|
},
|
|
116
126
|
};
|
|
117
127
|
|
|
@@ -154,6 +164,9 @@ shaka.util.PlayerConfiguration = class {
|
|
|
154
164
|
autoLowLatencyMode: false,
|
|
155
165
|
forceHTTPS: false,
|
|
156
166
|
preferNativeHls: false,
|
|
167
|
+
updateIntervalSeconds: 1,
|
|
168
|
+
dispatchAllEmsgBoxes: false,
|
|
169
|
+
observeQualityChanges: false,
|
|
157
170
|
};
|
|
158
171
|
|
|
159
172
|
// Some browsers will stop earlier than others before a gap (e.g., Edge
|
|
@@ -226,6 +239,19 @@ shaka.util.PlayerConfiguration = class {
|
|
|
226
239
|
minBandwidth: 0,
|
|
227
240
|
maxBandwidth: Infinity,
|
|
228
241
|
},
|
|
242
|
+
advanced: {
|
|
243
|
+
minTotalBytes: 128e3,
|
|
244
|
+
minBytes: 16e3,
|
|
245
|
+
fastHalfLife: 2,
|
|
246
|
+
slowHalfLife: 5,
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const cmcd = {
|
|
251
|
+
enabled: false,
|
|
252
|
+
sessionId: '',
|
|
253
|
+
contentId: '',
|
|
254
|
+
useHeaders: false,
|
|
229
255
|
};
|
|
230
256
|
|
|
231
257
|
/** @type {shaka.extern.PlayerConfiguration} */
|
|
@@ -241,7 +267,10 @@ shaka.util.PlayerConfiguration = class {
|
|
|
241
267
|
preferredVariantRole: '',
|
|
242
268
|
preferredTextRole: '',
|
|
243
269
|
preferredAudioChannelCount: 2,
|
|
270
|
+
preferredVideoCodecs: [],
|
|
271
|
+
preferredAudioCodecs: [],
|
|
244
272
|
preferForcedSubs: false,
|
|
273
|
+
preferredDecodingAttributes: [],
|
|
245
274
|
restrictions: {
|
|
246
275
|
minWidth: 0,
|
|
247
276
|
maxWidth: Infinity,
|
|
@@ -256,8 +285,8 @@ shaka.util.PlayerConfiguration = class {
|
|
|
256
285
|
},
|
|
257
286
|
playRangeStart: 0,
|
|
258
287
|
playRangeEnd: Infinity,
|
|
259
|
-
useMediaCapabilities: false,
|
|
260
288
|
textDisplayFactory: () => null,
|
|
289
|
+
cmcd: cmcd,
|
|
261
290
|
};
|
|
262
291
|
|
|
263
292
|
// Add this callback so that we can reference the preferred audio language
|
|
@@ -293,6 +322,7 @@ shaka.util.PlayerConfiguration = class {
|
|
|
293
322
|
audioRobustness: '',
|
|
294
323
|
sessionType: '',
|
|
295
324
|
serverCertificate: new Uint8Array(0),
|
|
325
|
+
serverCertificateUri: '',
|
|
296
326
|
individualizationServer: '',
|
|
297
327
|
},
|
|
298
328
|
};
|