shaka-player 4.10.0 → 4.10.2
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/dist/deps.js +9 -9
- package/dist/locales.js +36 -36
- package/dist/shaka-player.compiled.d.ts +2 -2
- package/dist/shaka-player.compiled.debug.d.ts +2 -2
- package/dist/shaka-player.compiled.debug.externs.js +1 -1
- package/dist/shaka-player.compiled.debug.js +140 -139
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +1 -1
- package/dist/shaka-player.compiled.js +1169 -1163
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +2 -2
- package/dist/shaka-player.ui.debug.d.ts +2 -2
- package/dist/shaka-player.ui.debug.externs.js +1 -1
- package/dist/shaka-player.ui.debug.js +167 -165
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +1 -1
- package/dist/shaka-player.ui.js +1396 -1391
- package/dist/shaka-player.ui.map +4 -4
- package/externs/shaka/player.js +7 -1
- package/lib/abr/simple_abr_manager.js +11 -8
- package/lib/hls/hls_parser.js +7 -6
- package/lib/media/drm_engine.js +9 -197
- package/lib/media/presentation_timeline.js +13 -5
- package/lib/player.js +20 -12
- package/lib/polyfill/media_capabilities.js +4 -4
- package/lib/polyfill/patchedmediakeys_apple.js +3 -3
- package/lib/polyfill/patchedmediakeys_webkit.js +3 -3
- package/lib/text/simple_text_displayer.js +3 -0
- package/lib/text/ssa_text_parser.js +22 -7
- package/lib/text/text_utils.js +17 -1
- package/lib/text/ttml_text_parser.js +5 -3
- package/lib/text/ui_text_displayer.js +6 -1
- package/lib/util/config_utils.js +5 -0
- package/lib/util/drm_utils.js +191 -0
- package/lib/util/periods.js +4 -4
- package/lib/util/player_configuration.js +1 -0
- package/lib/util/ts_parser.js +4 -4
- package/package.json +1 -1
- package/ui/locales/fr.json +1 -1
- package/ui/statistics_button.js +10 -3
|
@@ -630,7 +630,9 @@ shaka.text.TtmlTextParser = class {
|
|
|
630
630
|
cue.fontFamily = 'serif';
|
|
631
631
|
break;
|
|
632
632
|
default:
|
|
633
|
-
cue.fontFamily = fontFamily
|
|
633
|
+
cue.fontFamily = fontFamily.split(',').filter((font) => {
|
|
634
|
+
return font != 'default';
|
|
635
|
+
}).join(',');
|
|
634
636
|
break;
|
|
635
637
|
}
|
|
636
638
|
}
|
|
@@ -1300,9 +1302,9 @@ shaka.text.TtmlTextParser.percentValues_ =
|
|
|
1300
1302
|
/**
|
|
1301
1303
|
* @const
|
|
1302
1304
|
* @private {!RegExp}
|
|
1303
|
-
* @example 0.6% 90%
|
|
1305
|
+
* @example 0.6% 90% 300% 1000%
|
|
1304
1306
|
*/
|
|
1305
|
-
shaka.text.TtmlTextParser.percentValue_ = /^(\d{1,
|
|
1307
|
+
shaka.text.TtmlTextParser.percentValue_ = /^(\d{1,4}(?:\.\d+)?|100)%$/;
|
|
1306
1308
|
|
|
1307
1309
|
/**
|
|
1308
1310
|
* @const
|
|
@@ -11,6 +11,7 @@ goog.require('goog.asserts');
|
|
|
11
11
|
goog.require('shaka.Deprecate');
|
|
12
12
|
goog.require('shaka.text.Cue');
|
|
13
13
|
goog.require('shaka.text.CueRegion');
|
|
14
|
+
goog.require('shaka.text.Utils');
|
|
14
15
|
goog.require('shaka.util.Dom');
|
|
15
16
|
goog.require('shaka.util.EventManager');
|
|
16
17
|
goog.require('shaka.util.Timer');
|
|
@@ -156,7 +157,7 @@ shaka.text.UITextDisplayer = class {
|
|
|
156
157
|
// list growing during the comparisons for duplicate cues.
|
|
157
158
|
// See: https://github.com/shaka-project/shaka-player/issues/3018
|
|
158
159
|
const cuesList = [...this.cues_];
|
|
159
|
-
for (const cue of cues) {
|
|
160
|
+
for (const cue of shaka.text.Utils.removeDuplicates(cues)) {
|
|
160
161
|
// When a VTT cue spans a segment boundary, the cue will be duplicated
|
|
161
162
|
// into two segments.
|
|
162
163
|
// To avoid displaying duplicate cues, if the current cue list already
|
|
@@ -654,6 +655,10 @@ shaka.text.UITextDisplayer = class {
|
|
|
654
655
|
style.backgroundSize = 'contain';
|
|
655
656
|
style.backgroundPosition = 'center';
|
|
656
657
|
|
|
658
|
+
if (cue.backgroundColor) {
|
|
659
|
+
style.backgroundColor = cue.backgroundColor;
|
|
660
|
+
}
|
|
661
|
+
|
|
657
662
|
// Quoting https://www.w3.org/TR/ttml-imsc1.2/:
|
|
658
663
|
// "The width and height (in pixels) of the image resource referenced by
|
|
659
664
|
// smpte:backgroundImage SHALL be equal to the width and height expressed
|
package/lib/util/config_utils.js
CHANGED
|
@@ -196,6 +196,8 @@ shaka.util.ConfigUtils = class {
|
|
|
196
196
|
}
|
|
197
197
|
} else if (isArrayEmpty(value) && isArrayEmpty(base[key])) {
|
|
198
198
|
// Do nothing if both are empty arrays
|
|
199
|
+
} else if (Number.isNaN(value) && Number.isNaN(base[key])) {
|
|
200
|
+
// Do nothing if both are NaN
|
|
199
201
|
} else if (value !== base[key]) {
|
|
200
202
|
acc[key] = value;
|
|
201
203
|
}
|
|
@@ -215,6 +217,9 @@ shaka.util.ConfigUtils = class {
|
|
|
215
217
|
delete obj[key];
|
|
216
218
|
} else if (isObject(obj[key])) {
|
|
217
219
|
removeEmpty(obj[key]);
|
|
220
|
+
if (Object.keys(obj[key]).length === 0) {
|
|
221
|
+
delete obj[key];
|
|
222
|
+
}
|
|
218
223
|
}
|
|
219
224
|
}
|
|
220
225
|
};
|
package/lib/util/drm_utils.js
CHANGED
|
@@ -6,8 +6,113 @@
|
|
|
6
6
|
|
|
7
7
|
goog.provide('shaka.util.DrmUtils');
|
|
8
8
|
|
|
9
|
+
goog.require('shaka.util.BufferUtils');
|
|
10
|
+
goog.require('shaka.util.Lazy');
|
|
11
|
+
|
|
9
12
|
|
|
10
13
|
shaka.util.DrmUtils = class {
|
|
14
|
+
/**
|
|
15
|
+
* Returns true if the browser has recent EME APIs.
|
|
16
|
+
*
|
|
17
|
+
* @return {boolean}
|
|
18
|
+
*/
|
|
19
|
+
static isBrowserSupported() {
|
|
20
|
+
const basic =
|
|
21
|
+
!!window.MediaKeys &&
|
|
22
|
+
!!window.navigator &&
|
|
23
|
+
!!window.navigator.requestMediaKeySystemAccess &&
|
|
24
|
+
!!window.MediaKeySystemAccess &&
|
|
25
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
26
|
+
!!window.MediaKeySystemAccess.prototype.getConfiguration;
|
|
27
|
+
|
|
28
|
+
return basic;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Checks if two DrmInfos can be decrypted using the same key system.
|
|
33
|
+
* Clear content is considered compatible with every key system.
|
|
34
|
+
*
|
|
35
|
+
* @param {!Array<!shaka.extern.DrmInfo>} drms1
|
|
36
|
+
* @param {!Array<!shaka.extern.DrmInfo>} drms2
|
|
37
|
+
* @return {boolean}
|
|
38
|
+
*/
|
|
39
|
+
static areDrmCompatible(drms1, drms2) {
|
|
40
|
+
if (!drms1.length || !drms2.length) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (drms1 === drms2) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return shaka.util.DrmUtils.getCommonDrmInfos(
|
|
49
|
+
drms1, drms2).length > 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Returns an array of drm infos that are present in both input arrays.
|
|
54
|
+
* If one of the arrays is empty, returns the other one since clear
|
|
55
|
+
* content is considered compatible with every drm info.
|
|
56
|
+
*
|
|
57
|
+
* @param {!Array<!shaka.extern.DrmInfo>} drms1
|
|
58
|
+
* @param {!Array<!shaka.extern.DrmInfo>} drms2
|
|
59
|
+
* @return {!Array<!shaka.extern.DrmInfo>}
|
|
60
|
+
*/
|
|
61
|
+
static getCommonDrmInfos(drms1, drms2) {
|
|
62
|
+
if (!drms1.length) {
|
|
63
|
+
return drms2;
|
|
64
|
+
}
|
|
65
|
+
if (!drms2.length) {
|
|
66
|
+
return drms1;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const commonDrms = [];
|
|
70
|
+
|
|
71
|
+
for (const drm1 of drms1) {
|
|
72
|
+
for (const drm2 of drms2) {
|
|
73
|
+
if (drm1.keySystem == drm2.keySystem) {
|
|
74
|
+
const initDataMap = new Map();
|
|
75
|
+
const bothInitDatas = (drm1.initData || [])
|
|
76
|
+
.concat(drm2.initData || []);
|
|
77
|
+
for (const d of bothInitDatas) {
|
|
78
|
+
initDataMap.set(d.keyId, d);
|
|
79
|
+
}
|
|
80
|
+
const initData = Array.from(initDataMap.values());
|
|
81
|
+
|
|
82
|
+
const keyIds = drm1.keyIds && drm2.keyIds ?
|
|
83
|
+
new Set([...drm1.keyIds, ...drm2.keyIds]) :
|
|
84
|
+
drm1.keyIds || drm2.keyIds;
|
|
85
|
+
const mergedDrm = {
|
|
86
|
+
keySystem: drm1.keySystem,
|
|
87
|
+
licenseServerUri: drm1.licenseServerUri || drm2.licenseServerUri,
|
|
88
|
+
distinctiveIdentifierRequired: drm1.distinctiveIdentifierRequired ||
|
|
89
|
+
drm2.distinctiveIdentifierRequired,
|
|
90
|
+
persistentStateRequired: drm1.persistentStateRequired ||
|
|
91
|
+
drm2.persistentStateRequired,
|
|
92
|
+
videoRobustness: drm1.videoRobustness || drm2.videoRobustness,
|
|
93
|
+
audioRobustness: drm1.audioRobustness || drm2.audioRobustness,
|
|
94
|
+
serverCertificate: drm1.serverCertificate || drm2.serverCertificate,
|
|
95
|
+
serverCertificateUri: drm1.serverCertificateUri ||
|
|
96
|
+
drm2.serverCertificateUri,
|
|
97
|
+
initData,
|
|
98
|
+
keyIds,
|
|
99
|
+
};
|
|
100
|
+
commonDrms.push(mergedDrm);
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return commonDrms;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @param {?shaka.extern.DrmInfo} drmInfo
|
|
111
|
+
* @return {string} */
|
|
112
|
+
static keySystem(drmInfo) {
|
|
113
|
+
return drmInfo ? drmInfo.keySystem : '';
|
|
114
|
+
}
|
|
115
|
+
|
|
11
116
|
/**
|
|
12
117
|
* @param {?string} keySystem
|
|
13
118
|
* @return {boolean}
|
|
@@ -31,4 +136,90 @@ shaka.util.DrmUtils = class {
|
|
|
31
136
|
|
|
32
137
|
return false;
|
|
33
138
|
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* A method for generating a key for the MediaKeySystemAccessRequests cache.
|
|
142
|
+
*
|
|
143
|
+
* @param {string} videoCodec
|
|
144
|
+
* @param {string} audioCodec
|
|
145
|
+
* @param {string} keySystem
|
|
146
|
+
* @return {string}
|
|
147
|
+
* @private
|
|
148
|
+
*/
|
|
149
|
+
static generateKeySystemCacheKey_(videoCodec, audioCodec, keySystem) {
|
|
150
|
+
return `${videoCodec}#${audioCodec}#${keySystem}`;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Check does MediaKeySystemAccess cache contains something for following
|
|
155
|
+
* attributes.
|
|
156
|
+
*
|
|
157
|
+
* @param {string} videoCodec
|
|
158
|
+
* @param {string} audioCodec
|
|
159
|
+
* @param {string} keySystem
|
|
160
|
+
* @return {boolean}
|
|
161
|
+
*/
|
|
162
|
+
static hasMediaKeySystemAccess(videoCodec, audioCodec, keySystem) {
|
|
163
|
+
const DrmUtils = shaka.util.DrmUtils;
|
|
164
|
+
const key = DrmUtils.generateKeySystemCacheKey_(
|
|
165
|
+
videoCodec, audioCodec, keySystem);
|
|
166
|
+
return DrmUtils.memoizedMediaKeySystemAccessRequests_.has(key);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Get MediaKeySystemAccess object for following attributes.
|
|
171
|
+
*
|
|
172
|
+
* @param {string} videoCodec
|
|
173
|
+
* @param {string} audioCodec
|
|
174
|
+
* @param {string} keySystem
|
|
175
|
+
* @return {?MediaKeySystemAccess}
|
|
176
|
+
*/
|
|
177
|
+
static getMediaKeySystemAccess(videoCodec, audioCodec, keySystem) {
|
|
178
|
+
const DrmUtils = shaka.util.DrmUtils;
|
|
179
|
+
const key = DrmUtils.generateKeySystemCacheKey_(
|
|
180
|
+
videoCodec, audioCodec, keySystem);
|
|
181
|
+
return DrmUtils.memoizedMediaKeySystemAccessRequests_.get(key) || null;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Store MediaKeySystemAccess object associated with specified attributes.
|
|
186
|
+
*
|
|
187
|
+
* @param {string} videoCodec
|
|
188
|
+
* @param {string} audioCodec
|
|
189
|
+
* @param {string} keySystem
|
|
190
|
+
* @param {!MediaKeySystemAccess} mksa
|
|
191
|
+
*/
|
|
192
|
+
static setMediaKeySystemAccess(videoCodec, audioCodec, keySystem, mksa) {
|
|
193
|
+
const DrmUtils = shaka.util.DrmUtils;
|
|
194
|
+
const key = DrmUtils.generateKeySystemCacheKey_(
|
|
195
|
+
videoCodec, audioCodec, keySystem);
|
|
196
|
+
return DrmUtils.memoizedMediaKeySystemAccessRequests_.set(key, mksa);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Clears underlying cache.
|
|
201
|
+
*/
|
|
202
|
+
static clearMediaKeySystemAccessMap() {
|
|
203
|
+
const DrmUtils = shaka.util.DrmUtils;
|
|
204
|
+
DrmUtils.memoizedMediaKeySystemAccessRequests_.clear();
|
|
205
|
+
}
|
|
34
206
|
};
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Contains the suggested "default" key ID used by EME polyfills that do not
|
|
211
|
+
* have a per-key key status. See w3c/encrypted-media#32.
|
|
212
|
+
* @type {!shaka.util.Lazy<!ArrayBuffer>}
|
|
213
|
+
*/
|
|
214
|
+
shaka.util.DrmUtils.DUMMY_KEY_ID = new shaka.util.Lazy(
|
|
215
|
+
() => shaka.util.BufferUtils.toArrayBuffer(new Uint8Array([0])));
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* A cache that stores the MediaKeySystemAccess result of calling
|
|
220
|
+
* `navigator.requestMediaKeySystemAccess` by a key combination of
|
|
221
|
+
* video/audio codec and key system string.
|
|
222
|
+
*
|
|
223
|
+
* @private {!Map<string, !MediaKeySystemAccess>}
|
|
224
|
+
*/
|
|
225
|
+
shaka.util.DrmUtils.memoizedMediaKeySystemAccessRequests_ = new Map();
|
package/lib/util/periods.js
CHANGED
|
@@ -8,9 +8,9 @@ goog.provide('shaka.util.PeriodCombiner');
|
|
|
8
8
|
|
|
9
9
|
goog.require('goog.asserts');
|
|
10
10
|
goog.require('shaka.log');
|
|
11
|
-
goog.require('shaka.media.DrmEngine');
|
|
12
11
|
goog.require('shaka.media.MetaSegmentIndex');
|
|
13
12
|
goog.require('shaka.media.SegmentIndex');
|
|
13
|
+
goog.require('shaka.util.DrmUtils');
|
|
14
14
|
goog.require('shaka.util.Error');
|
|
15
15
|
goog.require('shaka.util.IReleasable');
|
|
16
16
|
goog.require('shaka.util.LanguageUtils');
|
|
@@ -282,7 +282,7 @@ shaka.util.PeriodCombiner = class {
|
|
|
282
282
|
} else {
|
|
283
283
|
for (const audio of this.audioStreams_) {
|
|
284
284
|
for (const video of this.videoStreams_) {
|
|
285
|
-
const commonDrmInfos = shaka.
|
|
285
|
+
const commonDrmInfos = shaka.util.DrmUtils.getCommonDrmInfos(
|
|
286
286
|
audio.drmInfos, video.drmInfos);
|
|
287
287
|
|
|
288
288
|
if (audio.drmInfos.length && video.drmInfos.length &&
|
|
@@ -855,7 +855,7 @@ shaka.util.PeriodCombiner = class {
|
|
|
855
855
|
output.originalId += ',' + (input.originalId || '');
|
|
856
856
|
}
|
|
857
857
|
|
|
858
|
-
const commonDrmInfos = shaka.
|
|
858
|
+
const commonDrmInfos = shaka.util.DrmUtils.getCommonDrmInfos(
|
|
859
859
|
output.drmInfos, input.drmInfos);
|
|
860
860
|
if (input.drmInfos.length && output.drmInfos.length &&
|
|
861
861
|
!commonDrmInfos.length) {
|
|
@@ -1115,7 +1115,7 @@ shaka.util.PeriodCombiner = class {
|
|
|
1115
1115
|
if (outputStream.drmInfos) {
|
|
1116
1116
|
// Check for compatible DRM systems. Note that clear streams are
|
|
1117
1117
|
// implicitly compatible with any DRM and with each other.
|
|
1118
|
-
if (!shaka.
|
|
1118
|
+
if (!shaka.util.DrmUtils.areDrmCompatible(outputStream.drmInfos,
|
|
1119
1119
|
candidate.drmInfos)) {
|
|
1120
1120
|
return false;
|
|
1121
1121
|
}
|
package/lib/util/ts_parser.js
CHANGED
|
@@ -726,7 +726,7 @@ shaka.util.TsParser = class {
|
|
|
726
726
|
}
|
|
727
727
|
|
|
728
728
|
/**
|
|
729
|
-
* Return the
|
|
729
|
+
* Return the video data
|
|
730
730
|
*
|
|
731
731
|
* @param {boolean=} naluProcessing
|
|
732
732
|
* @return {!Array.<shaka.extern.MPEG_PES>}
|
|
@@ -760,15 +760,15 @@ shaka.util.TsParser = class {
|
|
|
760
760
|
if (naluProcessing) {
|
|
761
761
|
let lastNalu;
|
|
762
762
|
let lastState;
|
|
763
|
+
const pesWithLength = [];
|
|
763
764
|
for (const pes of this.videoPes_) {
|
|
764
765
|
pes.nalus = this.parseNalus(pes, lastNalu, lastState);
|
|
765
766
|
if (pes.nalus.length) {
|
|
767
|
+
pesWithLength.push(pes);
|
|
766
768
|
lastNalu = pes.nalus[pes.nalus.length - 1];
|
|
767
769
|
}
|
|
768
770
|
}
|
|
769
|
-
this.videoPes_ =
|
|
770
|
-
return pes.nalus.length;
|
|
771
|
-
});
|
|
771
|
+
this.videoPes_ = pesWithLength;
|
|
772
772
|
}
|
|
773
773
|
if (sort) {
|
|
774
774
|
this.videoPes_ = this.videoPes_.sort((a, b) => {
|
package/package.json
CHANGED
package/ui/locales/fr.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"AD_DURATION": "Durée de l'annonce",
|
|
3
3
|
"AD_PROGRESS": "Annonce [AD_ON] sur [NUM_ADS]",
|
|
4
|
-
"AD_STATISTICS": "Statistiques de
|
|
4
|
+
"AD_STATISTICS": "Statistiques de l'annonce",
|
|
5
5
|
"AD_TIME": "Annonce : [AD_TIME]",
|
|
6
6
|
"AIRPLAY": "AirPlay",
|
|
7
7
|
"AUTO_QUALITY": "Automatique",
|
package/ui/statistics_button.js
CHANGED
|
@@ -241,8 +241,11 @@ shaka.ui.StatisticsButton = class extends shaka.ui.Element {
|
|
|
241
241
|
loadContainer_() {
|
|
242
242
|
for (const name of this.controls.getConfig().statisticsList) {
|
|
243
243
|
if (name in this.currentStats_ && !this.skippedStats_.includes(name)) {
|
|
244
|
-
this.
|
|
244
|
+
const element = this.generateComponent_(name);
|
|
245
|
+
this.container_.appendChild(element);
|
|
245
246
|
this.statisticsList_.push(name);
|
|
247
|
+
shaka.ui.Utils.setDisplay(element.parentElement,
|
|
248
|
+
!isNaN(this.currentStats_[name]));
|
|
246
249
|
} else {
|
|
247
250
|
shaka.log.alwaysWarn('Unrecognized statistic element:', name);
|
|
248
251
|
}
|
|
@@ -254,8 +257,12 @@ shaka.ui.StatisticsButton = class extends shaka.ui.Element {
|
|
|
254
257
|
this.currentStats_ = this.player.getStats();
|
|
255
258
|
|
|
256
259
|
for (const name of this.statisticsList_) {
|
|
257
|
-
this.displayedElements_[name]
|
|
258
|
-
|
|
260
|
+
const element = this.displayedElements_[name];
|
|
261
|
+
element.textContent = this.parseFrom_[name](name);
|
|
262
|
+
if (element && element.parentElement) {
|
|
263
|
+
shaka.ui.Utils.setDisplay(element.parentElement,
|
|
264
|
+
!isNaN(this.currentStats_[name]));
|
|
265
|
+
}
|
|
259
266
|
}
|
|
260
267
|
}
|
|
261
268
|
|