shaka-player 3.3.4 → 4.0.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/.github/config.yml +1 -0
- package/.github/workflows/build-and-test.yaml +0 -1
- package/.github/workflows/demo-version-index.yaml +8 -0
- package/.github/workflows/release-please.yaml +19 -3
- package/.github/workflows/selenium-lab-tests.yaml +0 -1
- package/.github/workflows/sync-labels.yaml +33 -0
- package/.github/workflows/update-issues.yaml +29 -0
- package/.github/workflows/validate-pr-title.yaml +35 -0
- package/AUTHORS +1 -0
- package/CHANGELOG.md +209 -28
- package/CONTRIBUTORS +1 -0
- package/README.md +10 -7
- package/app-engine/demo-version-index/README.md +3 -3
- package/app-engine/demo-version-index/app.yaml +27 -1
- package/app-engine/demo-version-index/generate.py +164 -0
- package/app-engine/demo-version-index/main.py +4 -155
- package/app-engine/demo-version-index/requirements.txt +0 -1
- package/build/README.md +2 -2
- package/build/compiler.py +1 -1
- package/build/generateTsDefs.py +0 -2
- package/build/misspellings.txt +1 -0
- package/build/shaka-lab.yaml +0 -2
- package/build/test.py +7 -1
- package/build/types/core +0 -1
- package/build/types/polyfill +0 -3
- package/demo/common/asset.js +17 -1
- package/demo/common/assets.js +29 -0
- package/demo/common/message_ids.js +6 -3
- package/demo/config.js +10 -11
- package/demo/custom.js +39 -0
- package/demo/demo_utils.js +0 -1
- package/demo/locales/en.json +6 -3
- package/demo/locales/source.json +22 -10
- package/demo/main.js +9 -6
- package/demo/search.js +2 -1
- package/dist/controls.css +1 -1
- package/dist/demo.compiled.debug.js +71 -64
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +71 -64
- package/dist/demo.compiled.map +3 -3
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +16 -20
- package/dist/locales.js +33 -31
- package/dist/receiver.compiled.debug.js +32 -28
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +32 -28
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +78 -82
- package/dist/shaka-player.compiled.debug.d.ts +78 -82
- package/dist/shaka-player.compiled.debug.externs.js +127 -126
- package/dist/shaka-player.compiled.debug.js +471 -523
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +127 -126
- package/dist/shaka-player.compiled.js +844 -858
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +80 -82
- package/dist/shaka-player.ui.debug.d.ts +80 -82
- package/dist/shaka-player.ui.debug.externs.js +135 -126
- package/dist/shaka-player.ui.debug.js +531 -581
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +135 -126
- package/dist/shaka-player.ui.js +991 -1001
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/config.md +0 -2
- package/docs/tutorials/drm-config.md +5 -0
- package/docs/tutorials/fairplay.md +7 -22
- package/docs/tutorials/faq.md +0 -11
- package/docs/tutorials/index.json +2 -8
- package/docs/tutorials/plugins.md +1 -3
- package/docs/tutorials/upgrade.md +85 -11
- package/externs/polyfill.js +15 -0
- package/externs/shaka/manifest.js +5 -1
- package/externs/shaka/net.js +12 -0
- package/externs/shaka/offline.js +5 -1
- package/externs/shaka/player.js +39 -21
- package/externs/shaka/text.js +12 -12
- package/externs/sourcebuffer.js +15 -0
- package/karma.conf.js +4 -0
- package/lib/ads/client_side_ad.js +13 -2
- package/lib/ads/client_side_ad_manager.js +22 -4
- package/lib/cast/cast_utils.js +0 -1
- package/lib/dash/content_protection.js +85 -5
- package/lib/dash/dash_parser.js +3 -3
- package/lib/hls/hls_parser.js +391 -747
- package/lib/hls/manifest_text_parser.js +2 -3
- package/lib/media/drm_engine.js +102 -37
- package/lib/media/gap_jumping_controller.js +10 -45
- package/lib/media/media_source_engine.js +157 -31
- package/lib/media/playhead.js +2 -5
- package/lib/media/presentation_timeline.js +1 -2
- package/lib/media/segment_index.js +13 -46
- package/lib/media/segment_reference.js +47 -1
- package/lib/media/streaming_engine.js +28 -11
- package/lib/media/time_ranges_utils.js +4 -9
- package/lib/net/networking_engine.js +3 -0
- package/lib/offline/indexeddb/storage_mechanism.js +4 -2
- 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 +1 -0
- package/lib/offline/storage.js +100 -132
- package/lib/player.js +181 -307
- package/lib/polyfill/media_capabilities.js +12 -6
- package/lib/polyfill/mediasource.js +0 -28
- package/lib/polyfill/patchedmediakeys_nop.js +2 -0
- package/lib/polyfill/patchedmediakeys_webkit.js +2 -0
- package/lib/text/cue.js +0 -6
- package/lib/text/lrc_text_parser.js +8 -0
- package/lib/text/mp4_ttml_parser.js +8 -0
- package/lib/text/mp4_vtt_parser.js +8 -0
- package/lib/text/sbv_text_parser.js +8 -0
- package/lib/text/simple_text_displayer.js +1 -7
- package/lib/text/srt_text_parser.js +8 -0
- package/lib/text/ssa_text_parser.js +8 -0
- package/lib/text/text_engine.js +19 -3
- package/lib/text/ttml_text_parser.js +8 -0
- package/lib/text/ui_text_displayer.js +1 -7
- package/lib/text/vtt_text_parser.js +27 -5
- package/lib/text/web_vtt_generator.js +1 -7
- package/lib/util/config_utils.js +25 -0
- package/lib/util/error.js +16 -13
- package/lib/util/fairplay_utils.js +109 -0
- package/lib/util/functional.js +0 -42
- package/lib/util/manifest_parser_utils.js +1 -1
- package/lib/util/mime_utils.js +50 -1
- package/lib/util/periods.js +5 -4
- package/lib/util/platform.js +45 -0
- package/lib/util/player_configuration.js +26 -20
- package/lib/util/pssh.js +23 -4
- package/lib/util/stream_utils.js +96 -24
- package/lib/util/uint8array_utils.js +0 -16
- package/lib/util/xml_utils.js +1 -1
- package/package.json +4 -1
- package/roadmap.md +19 -19
- package/shaka-player.uncompiled.js +0 -3
- package/test/cast/cast_utils_unit.js +1 -0
- package/test/dash/dash_parser_content_protection_unit.js +44 -0
- package/test/dash/dash_parser_manifest_unit.js +0 -24
- package/test/dash/dash_parser_segment_template_unit.js +3 -4
- package/test/demo/demo_unit.js +2 -1
- package/test/hls/hls_live_unit.js +121 -220
- package/test/hls/hls_parser_unit.js +515 -432
- package/test/hls/manifest_text_parser_unit.js +19 -0
- package/test/media/drm_engine_unit.js +86 -120
- package/test/media/media_source_engine_integration.js +26 -3
- package/test/media/media_source_engine_unit.js +7 -6
- package/test/media/playhead_unit.js +27 -191
- package/test/media/segment_index_unit.js +15 -25
- package/test/media/streaming_engine_integration.js +4 -39
- package/test/media/streaming_engine_unit.js +3 -2
- package/test/media/time_ranges_utils_unit.js +0 -5
- package/test/offline/indexeddb_storage_unit.js +1 -1
- package/test/offline/manifest_convert_unit.js +34 -4
- package/test/offline/offline_manifest_parser_unit.js +1 -0
- package/test/offline/storage_compatibility_unit.js +1 -1
- package/test/offline/storage_integration.js +5 -4
- package/test/player_external.js +7 -7
- package/test/player_integration.js +22 -10
- package/test/player_src_equals_integration.js +81 -83
- package/test/player_unit.js +124 -1
- package/test/test/boot.js +9 -0
- package/test/test/externs/filters.js +4 -0
- package/test/test/util/fake_media_source_engine.js +11 -4
- package/test/test/util/manifest_generator.js +3 -1
- package/test/test/util/manifest_parser_util.js +4 -1
- package/test/test/util/offline_utils.js +1 -0
- package/test/test/util/simple_fakes.js +31 -2
- package/test/test/util/streaming_engine_util.js +1 -0
- package/test/test/util/test_scheme.js +24 -1
- package/test/test/util/util.js +4 -4
- package/test/text/cue_integration.js +2 -2
- package/test/text/lrc_text_parser_unit.js +6 -7
- package/test/text/mp4_ttml_parser_unit.js +6 -4
- package/test/text/mp4_vtt_parser_unit.js +6 -5
- package/test/text/sbv_text_parser_unit.js +5 -6
- package/test/text/srt_text_parser_unit.js +5 -6
- package/test/text/ssa_text_parser_unit.js +17 -29
- package/test/text/text_engine_unit.js +45 -5
- package/test/text/ttml_text_parser_unit.js +77 -77
- package/test/text/vtt_text_parser_unit.js +116 -59
- package/test/ui/ui_integration.js +0 -16
- package/test/ui/ui_unit.js +27 -0
- package/test/util/cmcd_manager_unit.js +3 -0
- package/test/util/mime_utils_unit.js +54 -0
- package/test/util/periods_unit.js +79 -0
- package/test/util/stream_utils_unit.js +23 -7
- package/ui/controls.js +65 -40
- package/ui/fullscreen_button.js +26 -6
- package/ui/less/containers.less +3 -3
- package/ui/locales/en.json +1 -0
- package/ui/locales/source.json +5 -0
- package/ui/resolution_selection.js +31 -33
- package/ui/ui.js +0 -17
- package/docs/tutorials/gsoc-ideas-list.md +0 -3
- package/docs/tutorials/upgrade-v2-5.md +0 -441
- package/docs/tutorials/upgrade-v3.md +0 -38
- package/lib/polyfill/mathround.js +0 -49
- package/lib/polyfill/patchedmediakeys_apple.js +0 -744
- package/lib/polyfill/patchedmediakeys_ms.js +0 -698
- package/lib/util/mutex.js +0 -52
- package/test/util/functional_unit.js +0 -82
package/lib/util/mime_utils.js
CHANGED
|
@@ -11,6 +11,7 @@ goog.require('shaka.media.Transmuxer');
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* @summary A set of utility functions for dealing with MIME types.
|
|
14
|
+
* @export
|
|
14
15
|
*/
|
|
15
16
|
shaka.util.MimeUtils = class {
|
|
16
17
|
/**
|
|
@@ -20,6 +21,7 @@ shaka.util.MimeUtils = class {
|
|
|
20
21
|
* @param {string} mimeType
|
|
21
22
|
* @param {string=} codecs
|
|
22
23
|
* @return {string}
|
|
24
|
+
* @export
|
|
23
25
|
*/
|
|
24
26
|
static getFullType(mimeType, codecs) {
|
|
25
27
|
let fullMimeType = mimeType;
|
|
@@ -94,6 +96,53 @@ shaka.util.MimeUtils = class {
|
|
|
94
96
|
return codecs.split(',');
|
|
95
97
|
}
|
|
96
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Get the normalized codec from a codec string,
|
|
101
|
+
* independently of their container.
|
|
102
|
+
*
|
|
103
|
+
* @param {string} codecString
|
|
104
|
+
* @return {string}
|
|
105
|
+
*/
|
|
106
|
+
static getNormalizedCodec(codecString) {
|
|
107
|
+
const parts =
|
|
108
|
+
shaka.util.MimeUtils.getCodecParts_(codecString);
|
|
109
|
+
const base = parts[0];
|
|
110
|
+
const profile = parts[1].toLowerCase();
|
|
111
|
+
switch (true) {
|
|
112
|
+
case base === 'mp4a' && profile === '69':
|
|
113
|
+
case base === 'mp4a' && profile === '6b':
|
|
114
|
+
return 'mp3';
|
|
115
|
+
case base === 'mp4a' && profile === '66':
|
|
116
|
+
case base === 'mp4a' && profile === '67':
|
|
117
|
+
case base === 'mp4a' && profile === '68':
|
|
118
|
+
case base === 'mp4a' && profile === '40.2':
|
|
119
|
+
case base === 'mp4a' && profile === '40.02':
|
|
120
|
+
case base === 'mp4a' && profile === '40.5':
|
|
121
|
+
case base === 'mp4a' && profile === '40.05':
|
|
122
|
+
case base === 'mp4a' && profile === '40.29':
|
|
123
|
+
case base === 'mp4a' && profile === '40.42': // Extended HE-AAC
|
|
124
|
+
return 'aac';
|
|
125
|
+
case base === 'mp4a' && profile === 'a5':
|
|
126
|
+
return 'ac-3'; // Dolby Digital
|
|
127
|
+
case base === 'mp4a' && profile === 'a6':
|
|
128
|
+
return 'ec-3'; // Dolby Digital Plus
|
|
129
|
+
case base === 'mp4a' && profile === 'b2':
|
|
130
|
+
return 'dtsx'; // DTS:X
|
|
131
|
+
case base === 'mp4a' && profile === 'a9':
|
|
132
|
+
return 'dtsc'; // DTS Digital Surround
|
|
133
|
+
case base === 'avc1':
|
|
134
|
+
case base === 'avc3':
|
|
135
|
+
return 'avc'; // H264
|
|
136
|
+
case base === 'hvc1':
|
|
137
|
+
case base === 'hev1':
|
|
138
|
+
return 'hevc'; // H265
|
|
139
|
+
case base === 'dvh1':
|
|
140
|
+
case base === 'dvhe':
|
|
141
|
+
return 'dovi'; // Dolby Vision
|
|
142
|
+
}
|
|
143
|
+
return base;
|
|
144
|
+
}
|
|
145
|
+
|
|
97
146
|
/**
|
|
98
147
|
* Get the base codec from a codec string.
|
|
99
148
|
*
|
|
@@ -150,7 +199,7 @@ shaka.util.MimeUtils = class {
|
|
|
150
199
|
|
|
151
200
|
const base = parts[0];
|
|
152
201
|
|
|
153
|
-
parts.
|
|
202
|
+
parts.shift();
|
|
154
203
|
const profile = parts.join('.');
|
|
155
204
|
|
|
156
205
|
// Make sure that we always return a "base" and "profile".
|
package/lib/util/periods.js
CHANGED
|
@@ -573,8 +573,8 @@ shaka.util.PeriodCombiner = class {
|
|
|
573
573
|
// TODO(#1528): Consider changing this when we support codec switching.
|
|
574
574
|
const hasCodec = outputStreams.some((s) => {
|
|
575
575
|
return s.mimeType == stream.mimeType &&
|
|
576
|
-
shaka.util.MimeUtils.
|
|
577
|
-
shaka.util.MimeUtils.
|
|
576
|
+
shaka.util.MimeUtils.getNormalizedCodec(s.codecs) ==
|
|
577
|
+
shaka.util.MimeUtils.getNormalizedCodec(stream.codecs);
|
|
578
578
|
});
|
|
579
579
|
if (!hasCodec) {
|
|
580
580
|
continue;
|
|
@@ -1050,10 +1050,11 @@ shaka.util.PeriodCombiner = class {
|
|
|
1050
1050
|
* @private
|
|
1051
1051
|
*/
|
|
1052
1052
|
static areAVStreamsCompatible_(outputStream, candidate) {
|
|
1053
|
-
const
|
|
1053
|
+
const getCodec = (codecs) =>
|
|
1054
|
+
shaka.util.MimeUtils.getNormalizedCodec(codecs);
|
|
1054
1055
|
// Check MIME type and codecs, which should always be the same.
|
|
1055
1056
|
if (candidate.mimeType != outputStream.mimeType ||
|
|
1056
|
-
|
|
1057
|
+
getCodec(candidate.codecs) != getCodec(outputStream.codecs)) {
|
|
1057
1058
|
return false;
|
|
1058
1059
|
}
|
|
1059
1060
|
|
package/lib/util/platform.js
CHANGED
|
@@ -142,6 +142,18 @@ shaka.util.Platform = class {
|
|
|
142
142
|
return shaka.util.Platform.userAgentContains_('Web0S');
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Check if the current platform is a WebOS 3.
|
|
147
|
+
*
|
|
148
|
+
* @return {boolean}
|
|
149
|
+
*/
|
|
150
|
+
static isWebOS3() {
|
|
151
|
+
// See: http://webostv.developer.lge.com/discover/specifications/web-engine/
|
|
152
|
+
return shaka.util.Platform.userAgentContains_('Web0S') &&
|
|
153
|
+
shaka.util.Platform.userAgentContains_(
|
|
154
|
+
'Chrome/38.0.2125.122 Safari/537.36');
|
|
155
|
+
}
|
|
156
|
+
|
|
145
157
|
/**
|
|
146
158
|
* Check if the current platform is a Google Chromecast.
|
|
147
159
|
*
|
|
@@ -151,6 +163,16 @@ shaka.util.Platform = class {
|
|
|
151
163
|
return shaka.util.Platform.userAgentContains_('CrKey');
|
|
152
164
|
}
|
|
153
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Check if the current platform is a Android-based Cast devices.
|
|
168
|
+
*
|
|
169
|
+
* @return {boolean}
|
|
170
|
+
*/
|
|
171
|
+
static isAndroidCastDevice() {
|
|
172
|
+
return shaka.util.Platform.isChromecast() &&
|
|
173
|
+
shaka.util.Platform.userAgentContains_('Android');
|
|
174
|
+
}
|
|
175
|
+
|
|
154
176
|
/**
|
|
155
177
|
* Check if the current platform is Google Chrome.
|
|
156
178
|
*
|
|
@@ -228,6 +250,16 @@ shaka.util.Platform = class {
|
|
|
228
250
|
return null;
|
|
229
251
|
}
|
|
230
252
|
|
|
253
|
+
/**
|
|
254
|
+
* Check if the current platform is Apple Safari
|
|
255
|
+
* or Safari-based iOS browsers.
|
|
256
|
+
*
|
|
257
|
+
* @return {boolean}
|
|
258
|
+
*/
|
|
259
|
+
static isSafari() {
|
|
260
|
+
return !!shaka.util.Platform.safariVersion();
|
|
261
|
+
}
|
|
262
|
+
|
|
231
263
|
/**
|
|
232
264
|
* Guesses if the platform is a mobile one (iOS or Android).
|
|
233
265
|
*
|
|
@@ -318,6 +350,19 @@ shaka.util.Platform = class {
|
|
|
318
350
|
const Platform = shaka.util.Platform;
|
|
319
351
|
return Platform.isTizen() || Platform.isXboxOne();
|
|
320
352
|
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Returns true if MediaKeys is polyfilled
|
|
356
|
+
*
|
|
357
|
+
* @return {boolean}
|
|
358
|
+
*/
|
|
359
|
+
static isMediaKeysPolyfilled() {
|
|
360
|
+
if (window.shakaMediaKeysPolyfill) {
|
|
361
|
+
return true;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return false;
|
|
365
|
+
}
|
|
321
366
|
};
|
|
322
367
|
|
|
323
368
|
/** @private {shaka.util.Timer} */
|
|
@@ -9,7 +9,6 @@ goog.provide('shaka.util.PlayerConfiguration');
|
|
|
9
9
|
goog.require('goog.asserts');
|
|
10
10
|
goog.require('shaka.abr.SimpleAbrManager');
|
|
11
11
|
goog.require('shaka.log');
|
|
12
|
-
goog.require('shaka.media.DrmEngine');
|
|
13
12
|
goog.require('shaka.net.NetworkingEngine');
|
|
14
13
|
goog.require('shaka.util.ConfigUtils');
|
|
15
14
|
goog.require('shaka.util.LanguageUtils');
|
|
@@ -17,20 +16,15 @@ goog.require('shaka.util.ManifestParserUtils');
|
|
|
17
16
|
goog.require('shaka.util.Platform');
|
|
18
17
|
|
|
19
18
|
|
|
20
|
-
// TODO(vaage): Many times in our configs, we need to create an empty
|
|
21
|
-
// implementation of a method, but to avoid closure from removing unused
|
|
22
|
-
// parameters (and breaking our merge config code) we need to use each
|
|
23
|
-
// parameter. Is there a better solution to this problem than what we are
|
|
24
|
-
// doing now?
|
|
25
|
-
//
|
|
26
|
-
// NOTE: Chrome App Content Security Policy prohibits usage of new Function()
|
|
27
|
-
|
|
28
19
|
/**
|
|
29
20
|
* @final
|
|
30
21
|
* @export
|
|
31
22
|
*/
|
|
32
23
|
shaka.util.PlayerConfiguration = class {
|
|
33
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* @return {shaka.extern.PlayerConfiguration}
|
|
26
|
+
* @export
|
|
27
|
+
*/
|
|
34
28
|
static createDefault() {
|
|
35
29
|
// This is a relatively safe default in the absence of clues from the
|
|
36
30
|
// browser. For slower connections, the default estimate may be too high.
|
|
@@ -72,7 +66,11 @@ shaka.util.PlayerConfiguration = class {
|
|
|
72
66
|
clearKeys: {}, // key is arbitrary key system ID, value must be string
|
|
73
67
|
advanced: {}, // key is arbitrary key system ID, value is a record type
|
|
74
68
|
delayLicenseRequestUntilPlayed: false,
|
|
75
|
-
initDataTransform:
|
|
69
|
+
initDataTransform: (initData, initDataType, drmInfo) => {
|
|
70
|
+
return shaka.util.ConfigUtils.referenceParametersAndReturn(
|
|
71
|
+
[initData, initDataType, drmInfo],
|
|
72
|
+
initData);
|
|
73
|
+
},
|
|
76
74
|
logLicenseExchange: false,
|
|
77
75
|
updateExpirationTime: 1,
|
|
78
76
|
preferredKeySystems: [],
|
|
@@ -86,6 +84,7 @@ shaka.util.PlayerConfiguration = class {
|
|
|
86
84
|
disableText: false,
|
|
87
85
|
disableThumbnails: false,
|
|
88
86
|
defaultPresentationDelay: 0,
|
|
87
|
+
segmentRelativeVttTiming: false,
|
|
89
88
|
dash: {
|
|
90
89
|
clockSyncUri: '',
|
|
91
90
|
ignoreDrmInfo: false,
|
|
@@ -100,6 +99,8 @@ shaka.util.PlayerConfiguration = class {
|
|
|
100
99
|
keySystemsByURI: {
|
|
101
100
|
'urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b':
|
|
102
101
|
'org.w3.clearkey',
|
|
102
|
+
'urn:uuid:e2719d58-a985-b3c9-781a-b030af78d30e':
|
|
103
|
+
'org.w3.clearkey',
|
|
103
104
|
'urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed':
|
|
104
105
|
'com.widevine.alpha',
|
|
105
106
|
'urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95':
|
|
@@ -109,19 +110,20 @@ shaka.util.PlayerConfiguration = class {
|
|
|
109
110
|
'urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb':
|
|
110
111
|
'com.adobe.primetime',
|
|
111
112
|
},
|
|
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
113
|
manifestPreprocessor: (element) => {
|
|
116
|
-
return
|
|
114
|
+
return shaka.util.ConfigUtils.referenceParametersAndReturn(
|
|
115
|
+
[element],
|
|
116
|
+
element);
|
|
117
117
|
},
|
|
118
118
|
},
|
|
119
119
|
hls: {
|
|
120
120
|
ignoreTextStreamFailures: false,
|
|
121
121
|
ignoreImageStreamFailures: false,
|
|
122
|
-
useFullSegmentsForStartTime: false,
|
|
123
122
|
defaultAudioCodec: 'mp4a.40.2',
|
|
124
123
|
defaultVideoCodec: 'avc1.42E01E',
|
|
124
|
+
ignoreManifestProgramDateTime: false,
|
|
125
|
+
mediaPlaylistFullMimeType:
|
|
126
|
+
'video/mp2t; codecs="avc1.42E01E, mp4a.40.2"',
|
|
125
127
|
},
|
|
126
128
|
};
|
|
127
129
|
|
|
@@ -132,7 +134,9 @@ shaka.util.PlayerConfiguration = class {
|
|
|
132
134
|
// log message, because those are stripped in the compiled build.
|
|
133
135
|
failureCallback: (error) => {
|
|
134
136
|
shaka.log.error('Unhandled streaming error', error);
|
|
135
|
-
return
|
|
137
|
+
return shaka.util.ConfigUtils.referenceParametersAndReturn(
|
|
138
|
+
[error],
|
|
139
|
+
undefined);
|
|
136
140
|
},
|
|
137
141
|
// When low latency streaming is enabled, rebufferingGoal will default to
|
|
138
142
|
// 0.01 if not specified.
|
|
@@ -143,8 +147,6 @@ shaka.util.PlayerConfiguration = class {
|
|
|
143
147
|
alwaysStreamText: false,
|
|
144
148
|
startAtSegmentBoundary: false,
|
|
145
149
|
gapDetectionThreshold: 0.1,
|
|
146
|
-
smallGapLimit: 0.5,
|
|
147
|
-
jumpLargeGaps: false,
|
|
148
150
|
durationBackoff: 1,
|
|
149
151
|
forceTransmuxTS: false,
|
|
150
152
|
// Offset by 5 seconds since Chromecast takes a few seconds to start
|
|
@@ -210,7 +212,9 @@ shaka.util.PlayerConfiguration = class {
|
|
|
210
212
|
// to the function as it would be a no-op. The operation can't just be a
|
|
211
213
|
// log message, because those are stripped in the compiled build.
|
|
212
214
|
progressCallback: (content, progress) => {
|
|
213
|
-
return
|
|
215
|
+
return shaka.util.ConfigUtils.referenceParametersAndReturn(
|
|
216
|
+
[content, progress],
|
|
217
|
+
undefined);
|
|
214
218
|
},
|
|
215
219
|
|
|
216
220
|
// By default we use persistent licenses as forces errors to surface if
|
|
@@ -218,6 +222,8 @@ shaka.util.PlayerConfiguration = class {
|
|
|
218
222
|
// unexpected behaviours when someone tries to plays downloaded content
|
|
219
223
|
// without a persistent license.
|
|
220
224
|
usePersistentLicense: true,
|
|
225
|
+
|
|
226
|
+
numberOfParallelDownloads: 5,
|
|
221
227
|
};
|
|
222
228
|
|
|
223
229
|
const abr = {
|
package/lib/util/pssh.js
CHANGED
|
@@ -90,16 +90,21 @@ shaka.util.Pssh = class {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
/**
|
|
93
|
-
* Creates a pssh blob from the given system ID and
|
|
93
|
+
* Creates a pssh blob from the given system ID, data, keyIds and version.
|
|
94
94
|
*
|
|
95
95
|
* @param {!Uint8Array} data
|
|
96
96
|
* @param {!Uint8Array} systemId
|
|
97
|
+
* @param {!Set.<string>} keyIds
|
|
98
|
+
* @param {number} version
|
|
97
99
|
* @return {!Uint8Array}
|
|
98
100
|
*/
|
|
99
|
-
static createPssh(data, systemId) {
|
|
101
|
+
static createPssh(data, systemId, keyIds, version) {
|
|
100
102
|
goog.asserts.assert(systemId.byteLength == 16, 'Invalid system ID length');
|
|
101
103
|
const dataLength = data.length;
|
|
102
|
-
|
|
104
|
+
let psshSize = 0x4 + 0x4 + 0x4 + systemId.length + 0x4 + dataLength;
|
|
105
|
+
if (version > 0) {
|
|
106
|
+
psshSize += 0x4 + (16 * keyIds.size);
|
|
107
|
+
}
|
|
103
108
|
|
|
104
109
|
/** @type {!Uint8Array} */
|
|
105
110
|
const psshBox = new Uint8Array(psshSize);
|
|
@@ -111,10 +116,24 @@ shaka.util.Pssh = class {
|
|
|
111
116
|
byteCursor += 0x4;
|
|
112
117
|
psshData.setUint32(byteCursor, 0x70737368); // 'pssh'
|
|
113
118
|
byteCursor += 0x4;
|
|
114
|
-
psshData.setUint32(byteCursor, 0)
|
|
119
|
+
(version < 1) ? psshData.setUint32(byteCursor, 0) :
|
|
120
|
+
psshData.setUint32(byteCursor, 0x01000000); // version + flags
|
|
115
121
|
byteCursor += 0x4;
|
|
116
122
|
psshBox.set(systemId, byteCursor);
|
|
117
123
|
byteCursor += systemId.length;
|
|
124
|
+
|
|
125
|
+
// if version > 0, add KID count and kid values.
|
|
126
|
+
if (version > 0) {
|
|
127
|
+
psshData.setUint32(byteCursor, keyIds.size); // KID_count
|
|
128
|
+
byteCursor += 0x4;
|
|
129
|
+
const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;
|
|
130
|
+
for (const keyId of keyIds) {
|
|
131
|
+
const KID = Uint8ArrayUtils.fromHex(keyId);
|
|
132
|
+
psshBox.set(KID, byteCursor);
|
|
133
|
+
byteCursor += KID.length;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
118
137
|
psshData.setUint32(byteCursor, dataLength);
|
|
119
138
|
byteCursor += 0x4;
|
|
120
139
|
psshBox.set(data, byteCursor);
|
package/lib/util/stream_utils.js
CHANGED
|
@@ -283,12 +283,14 @@ shaka.util.StreamUtils = class {
|
|
|
283
283
|
// both be considered the same codec: avc1.42c01e, avc1.4d401f
|
|
284
284
|
let baseVideoCodec = '';
|
|
285
285
|
if (variant.video) {
|
|
286
|
-
baseVideoCodec =
|
|
286
|
+
baseVideoCodec =
|
|
287
|
+
shaka.util.MimeUtils.getNormalizedCodec(variant.video.codecs);
|
|
287
288
|
}
|
|
288
289
|
|
|
289
290
|
let baseAudioCodec = '';
|
|
290
291
|
if (variant.audio) {
|
|
291
|
-
baseAudioCodec =
|
|
292
|
+
baseAudioCodec =
|
|
293
|
+
shaka.util.MimeUtils.getNormalizedCodec(variant.audio.codecs);
|
|
292
294
|
}
|
|
293
295
|
|
|
294
296
|
return baseVideoCodec + '-' + baseAudioCodec;
|
|
@@ -406,7 +408,7 @@ shaka.util.StreamUtils = class {
|
|
|
406
408
|
shaka.util.StreamUtils.filterManifestByCurrentVariant(
|
|
407
409
|
currentVariant, manifest);
|
|
408
410
|
shaka.util.StreamUtils.filterTextStreams_(manifest);
|
|
409
|
-
shaka.util.StreamUtils.filterImageStreams_(manifest);
|
|
411
|
+
await shaka.util.StreamUtils.filterImageStreams_(manifest);
|
|
410
412
|
}
|
|
411
413
|
|
|
412
414
|
|
|
@@ -813,37 +815,57 @@ shaka.util.StreamUtils = class {
|
|
|
813
815
|
* @param {shaka.extern.Manifest} manifest
|
|
814
816
|
* @private
|
|
815
817
|
*/
|
|
816
|
-
static filterImageStreams_(manifest) {
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
Platform.isTizen() ||
|
|
830
|
-
Platform.isChromecast();
|
|
831
|
-
if (webpSupport) {
|
|
832
|
-
validMimeTypes.push('image/webp');
|
|
818
|
+
static async filterImageStreams_(manifest) {
|
|
819
|
+
const imageStreams = [];
|
|
820
|
+
for (const stream of manifest.imageStreams) {
|
|
821
|
+
const mimeType = stream.mimeType;
|
|
822
|
+
if (!shaka.util.StreamUtils.supportedImageMimeTypes_.has(mimeType)) {
|
|
823
|
+
const minImage = shaka.util.StreamUtils.minImage_.get(mimeType);
|
|
824
|
+
if (minImage) {
|
|
825
|
+
// eslint-disable-next-line no-await-in-loop
|
|
826
|
+
const res = await shaka.util.StreamUtils.isImageSupported_(minImage);
|
|
827
|
+
shaka.util.StreamUtils.supportedImageMimeTypes_.set(mimeType, res);
|
|
828
|
+
} else {
|
|
829
|
+
shaka.util.StreamUtils.supportedImageMimeTypes_.set(mimeType, false);
|
|
830
|
+
}
|
|
833
831
|
}
|
|
834
|
-
|
|
835
|
-
const keep =
|
|
832
|
+
|
|
833
|
+
const keep =
|
|
834
|
+
shaka.util.StreamUtils.supportedImageMimeTypes_.get(mimeType);
|
|
836
835
|
|
|
837
836
|
if (!keep) {
|
|
838
837
|
shaka.log.debug('Dropping image stream. Is not supported by the ' +
|
|
839
838
|
'platform.', stream);
|
|
839
|
+
} else {
|
|
840
|
+
imageStreams.push(stream);
|
|
840
841
|
}
|
|
842
|
+
}
|
|
843
|
+
manifest.imageStreams = imageStreams;
|
|
844
|
+
}
|
|
841
845
|
|
|
842
|
-
|
|
846
|
+
/**
|
|
847
|
+
* @param {string} minImage
|
|
848
|
+
* @return {!Promise.<boolean>}
|
|
849
|
+
* @private
|
|
850
|
+
*/
|
|
851
|
+
static isImageSupported_(minImage) {
|
|
852
|
+
return new Promise((resolve) => {
|
|
853
|
+
const imageElement = /** @type {HTMLImageElement} */(new Image());
|
|
854
|
+
imageElement.src = minImage;
|
|
855
|
+
if ('decode' in imageElement) {
|
|
856
|
+
imageElement.decode().then(() => {
|
|
857
|
+
resolve(true);
|
|
858
|
+
}).catch(() => {
|
|
859
|
+
resolve(false);
|
|
860
|
+
});
|
|
861
|
+
} else {
|
|
862
|
+
imageElement.onload = imageElement.onerror = () => {
|
|
863
|
+
resolve(imageElement.height === 2);
|
|
864
|
+
};
|
|
865
|
+
}
|
|
843
866
|
});
|
|
844
867
|
}
|
|
845
868
|
|
|
846
|
-
|
|
847
869
|
/**
|
|
848
870
|
* @param {shaka.extern.Stream} s0
|
|
849
871
|
* @param {shaka.extern.Stream} s1
|
|
@@ -878,6 +900,11 @@ shaka.util.StreamUtils = class {
|
|
|
878
900
|
/** @type {?shaka.extern.Stream} */
|
|
879
901
|
const video = variant.video;
|
|
880
902
|
|
|
903
|
+
/** @type {?string} */
|
|
904
|
+
const audioMimeType = audio ? audio.mimeType : null;
|
|
905
|
+
/** @type {?string} */
|
|
906
|
+
const videoMimeType = video ? video.mimeType : null;
|
|
907
|
+
|
|
881
908
|
/** @type {?string} */
|
|
882
909
|
const audioCodec = audio ? audio.codecs : null;
|
|
883
910
|
/** @type {?string} */
|
|
@@ -942,6 +969,8 @@ shaka.util.StreamUtils = class {
|
|
|
942
969
|
pixelAspectRatio: null,
|
|
943
970
|
hdr: null,
|
|
944
971
|
mimeType: mimeType,
|
|
972
|
+
audioMimeType: audioMimeType,
|
|
973
|
+
videoMimeType: videoMimeType,
|
|
945
974
|
codecs: codecs.join(', '),
|
|
946
975
|
audioCodec: audioCodec,
|
|
947
976
|
videoCodec: videoCodec,
|
|
@@ -1009,6 +1038,8 @@ shaka.util.StreamUtils = class {
|
|
|
1009
1038
|
pixelAspectRatio: null,
|
|
1010
1039
|
hdr: null,
|
|
1011
1040
|
mimeType: stream.mimeType,
|
|
1041
|
+
audioMimeType: null,
|
|
1042
|
+
videoMimeType: null,
|
|
1012
1043
|
codecs: stream.codecs || null,
|
|
1013
1044
|
audioCodec: null,
|
|
1014
1045
|
videoCodec: null,
|
|
@@ -1081,6 +1112,8 @@ shaka.util.StreamUtils = class {
|
|
|
1081
1112
|
pixelAspectRatio: null,
|
|
1082
1113
|
hdr: null,
|
|
1083
1114
|
mimeType: stream.mimeType,
|
|
1115
|
+
audioMimeType: null,
|
|
1116
|
+
videoMimeType: null,
|
|
1084
1117
|
codecs: null,
|
|
1085
1118
|
audioCodec: null,
|
|
1086
1119
|
videoCodec: null,
|
|
@@ -1199,6 +1232,8 @@ shaka.util.StreamUtils = class {
|
|
|
1199
1232
|
pixelAspectRatio: null,
|
|
1200
1233
|
hdr: null,
|
|
1201
1234
|
mimeType: null,
|
|
1235
|
+
audioMimeType: null,
|
|
1236
|
+
videoMimeType: null,
|
|
1202
1237
|
codecs: null,
|
|
1203
1238
|
audioCodec: null,
|
|
1204
1239
|
videoCodec: null,
|
|
@@ -1503,3 +1538,40 @@ shaka.util.StreamUtils.DecodingAttributes = {
|
|
|
1503
1538
|
POWER: 'powerEfficient',
|
|
1504
1539
|
BANDWIDTH: 'bandwidth',
|
|
1505
1540
|
};
|
|
1541
|
+
|
|
1542
|
+
/**
|
|
1543
|
+
* @private {!Map.<string, boolean>}
|
|
1544
|
+
*/
|
|
1545
|
+
shaka.util.StreamUtils.supportedImageMimeTypes_ = new Map()
|
|
1546
|
+
.set('image/svg+xml', true)
|
|
1547
|
+
.set('image/png', true)
|
|
1548
|
+
.set('image/jpeg', true)
|
|
1549
|
+
.set('image/jpg', true);
|
|
1550
|
+
|
|
1551
|
+
/**
|
|
1552
|
+
* @const {string}
|
|
1553
|
+
* @private
|
|
1554
|
+
*/
|
|
1555
|
+
shaka.util.StreamUtils.minWebPImage_ = 'data:image/webp;base64,UklGRjoAAABXRU' +
|
|
1556
|
+
'JQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwY' +
|
|
1557
|
+
'AAA';
|
|
1558
|
+
|
|
1559
|
+
/**
|
|
1560
|
+
* @const {string}
|
|
1561
|
+
* @private
|
|
1562
|
+
*/
|
|
1563
|
+
shaka.util.StreamUtils.minAvifImage_ = 'data:image/avif;base64,AAAAIGZ0eXBhdm' +
|
|
1564
|
+
'lmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljd' +
|
|
1565
|
+
'AAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEA' +
|
|
1566
|
+
'AAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAA' +
|
|
1567
|
+
'AamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAA' +
|
|
1568
|
+
'xhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAA' +
|
|
1569
|
+
'CVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=';
|
|
1570
|
+
|
|
1571
|
+
/**
|
|
1572
|
+
* @const {!Map.<string, string>}
|
|
1573
|
+
* @private
|
|
1574
|
+
*/
|
|
1575
|
+
shaka.util.StreamUtils.minImage_ = new Map()
|
|
1576
|
+
.set('image/webp', shaka.util.StreamUtils.minWebPImage_)
|
|
1577
|
+
.set('image/avif', shaka.util.StreamUtils.minAvifImage_);
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
goog.provide('shaka.util.Uint8ArrayUtils');
|
|
8
8
|
|
|
9
|
-
goog.require('shaka.Deprecate');
|
|
10
9
|
goog.require('shaka.util.BufferUtils');
|
|
11
10
|
goog.require('shaka.util.StringUtils');
|
|
12
11
|
|
|
@@ -17,21 +16,6 @@ goog.require('shaka.util.StringUtils');
|
|
|
17
16
|
* @export
|
|
18
17
|
*/
|
|
19
18
|
shaka.util.Uint8ArrayUtils = class {
|
|
20
|
-
/**
|
|
21
|
-
* Compare two Uint8Arrays for equality.
|
|
22
|
-
* @param {Uint8Array} arr1
|
|
23
|
-
* @param {Uint8Array} arr2
|
|
24
|
-
* @return {boolean}
|
|
25
|
-
* @deprecated
|
|
26
|
-
* @export
|
|
27
|
-
*/
|
|
28
|
-
static equal(arr1, arr2) {
|
|
29
|
-
shaka.Deprecate.deprecateFeature(4,
|
|
30
|
-
'shaka.util.Uint8ArrayUtils.equal',
|
|
31
|
-
'Please use shaka.util.BufferUtils.equal instead.');
|
|
32
|
-
return shaka.util.BufferUtils.equal(arr1, arr2);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
19
|
/**
|
|
36
20
|
* Convert a buffer to a base64 string. The output will be standard
|
|
37
21
|
* alphabet as opposed to base64url safe alphabet.
|
package/lib/util/xml_utils.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shaka-player",
|
|
3
3
|
"description": "DASH/EME video player library",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.1",
|
|
5
5
|
"homepage": "https://github.com/shaka-project/shaka-player",
|
|
6
6
|
"author": "Google",
|
|
7
7
|
"maintainers": [
|
|
@@ -97,5 +97,8 @@
|
|
|
97
97
|
},
|
|
98
98
|
"dependencies": {
|
|
99
99
|
"eme-encryption-scheme-polyfill": "^2.0.3"
|
|
100
|
+
},
|
|
101
|
+
"engines": {
|
|
102
|
+
"node": ">=14"
|
|
100
103
|
}
|
|
101
104
|
}
|
package/roadmap.md
CHANGED
|
@@ -9,41 +9,41 @@ The goals of future milestones are fluid until we begin that development cycle,
|
|
|
9
9
|
so the exact milestone for future features is not pre-determined.
|
|
10
10
|
|
|
11
11
|
Priority features up next:
|
|
12
|
-
- Support containerless formats
|
|
13
|
-
https://github.com/shaka-project/shaka-player/issues/2337
|
|
14
12
|
- Preload API
|
|
15
13
|
https://github.com/shaka-project/shaka-player/issues/880
|
|
16
|
-
- Codec-switching and order preference
|
|
17
|
-
https://github.com/shaka-project/shaka-player/issues/1528
|
|
18
|
-
https://github.com/shaka-project/shaka-player/issues/2179
|
|
19
14
|
|
|
20
15
|
Candidate features for future release cycles:
|
|
21
|
-
- HLS interstitial support
|
|
22
|
-
https://github.com/shaka-project/shaka-player/issues/3364
|
|
23
|
-
- Support ID3 tags in mp4
|
|
24
|
-
https://github.com/shaka-project/shaka-player/issues/3351
|
|
25
|
-
- MSE support for FairPlay
|
|
26
|
-
https://github.com/shaka-project/shaka-player/issues/3346
|
|
27
|
-
- Smaller, more modular binary
|
|
28
16
|
- Official TypeScript defs, generated from source
|
|
29
17
|
https://github.com/shaka-project/shaka-player/issues/1030
|
|
30
|
-
-
|
|
31
|
-
https://github.com/shaka-project/shaka-player/issues/
|
|
32
|
-
- Integration with Google Video ML/Cloud AI
|
|
33
|
-
|
|
34
|
-
v3.3 - 2021 Q3 or Q4
|
|
18
|
+
- Codec-switching
|
|
19
|
+
https://github.com/shaka-project/shaka-player/issues/1528
|
|
35
20
|
- Background fetch for offline storage
|
|
36
21
|
https://github.com/shaka-project/shaka-player/issues/879
|
|
37
|
-
-
|
|
38
|
-
https://github.com/shaka-project/shaka-player/issues/
|
|
22
|
+
- Support ID3 tags in mp4
|
|
23
|
+
https://github.com/shaka-project/shaka-player/issues/3351
|
|
24
|
+
- Smaller, more modular binary
|
|
25
|
+
|
|
26
|
+
v3.4 - 2022 Q1 or Q2
|
|
27
|
+
- MSE support for FairPlay
|
|
28
|
+
https://github.com/shaka-project/shaka-player/issues/3346
|
|
29
|
+
- Support containerless formats
|
|
30
|
+
https://github.com/shaka-project/shaka-player/issues/2337
|
|
39
31
|
|
|
40
32
|
=====
|
|
41
33
|
|
|
34
|
+
v3.3 - 2022 Q1
|
|
35
|
+
- Common Media Client Data (CMCD) logging support
|
|
36
|
+
https://github.com/shaka-project/shaka-player/issues/3619
|
|
37
|
+
- Non-linear IMA CS ads
|
|
38
|
+
https://github.com/shaka-project/shaka-player/pull/3639
|
|
39
|
+
|
|
42
40
|
v3.2 - 2021 Q3
|
|
43
41
|
- MediaCapabilities to make performance-based decisions
|
|
44
42
|
https://github.com/shaka-project/shaka-player/issues/1391
|
|
45
43
|
- Configurable key-system priority
|
|
46
44
|
https://github.com/shaka-project/shaka-player/issues/3002
|
|
45
|
+
- Codec order preferences
|
|
46
|
+
https://github.com/shaka-project/shaka-player/issues/2179
|
|
47
47
|
|
|
48
48
|
v3.1 - 2021 Q2
|
|
49
49
|
- Low-latency live (LL-HLS, LL-DASH)
|