shaka-player 4.9.2 → 4.9.4
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 +3 -2
- package/dist/locales.js +33 -33
- package/dist/shaka-player.compiled.d.ts +1 -1
- package/dist/shaka-player.compiled.debug.d.ts +1 -1
- package/dist/shaka-player.compiled.debug.js +54 -55
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.js +1165 -1164
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +1 -1
- package/dist/shaka-player.ui.debug.d.ts +1 -1
- package/dist/shaka-player.ui.debug.js +57 -58
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.js +1354 -1354
- package/dist/shaka-player.ui.map +3 -3
- package/externs/polyfill.js +1 -1
- package/lib/abr/simple_abr_manager.js +19 -1
- package/lib/hls/hls_parser.js +3 -3
- package/lib/media/content_workarounds.js +22 -7
- package/lib/media/drm_engine.js +10 -25
- package/lib/media/media_source_engine.js +31 -14
- package/lib/media/presentation_timeline.js +1 -1
- package/lib/player.js +17 -22
- package/lib/polyfill/patchedmediakeys_apple.js +9 -2
- package/lib/polyfill/patchedmediakeys_nop.js +8 -1
- package/lib/polyfill/patchedmediakeys_webkit.js +12 -2
- package/lib/util/drm_utils.js +34 -0
- package/lib/util/platform.js +12 -7
- package/package.json +1 -1
package/externs/polyfill.js
CHANGED
|
@@ -268,7 +268,8 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
268
268
|
|
|
269
269
|
if (currentBandwidth >= minBandwidth &&
|
|
270
270
|
currentBandwidth <= maxBandwidth &&
|
|
271
|
-
chosen.bandwidth != item.bandwidth
|
|
271
|
+
(chosen.bandwidth != item.bandwidth ||
|
|
272
|
+
this.isSameBandwidthAndHigherResolution_(chosen, item))) {
|
|
272
273
|
chosen = item;
|
|
273
274
|
}
|
|
274
275
|
}
|
|
@@ -537,6 +538,23 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
537
538
|
return v1.width - v2.width;
|
|
538
539
|
});
|
|
539
540
|
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* @param {shaka.extern.Variant} chosenVariant
|
|
544
|
+
* @param {shaka.extern.Variant} newVariant
|
|
545
|
+
* @return {boolean}
|
|
546
|
+
* @private
|
|
547
|
+
*/
|
|
548
|
+
isSameBandwidthAndHigherResolution_(chosenVariant, newVariant) {
|
|
549
|
+
if (chosenVariant.bandwidth != newVariant.bandwidth) {
|
|
550
|
+
return false;
|
|
551
|
+
}
|
|
552
|
+
if (!chosenVariant.video || !newVariant.video) {
|
|
553
|
+
return false;
|
|
554
|
+
}
|
|
555
|
+
return chosenVariant.video.width < newVariant.video.width ||
|
|
556
|
+
chosenVariant.video.height < newVariant.video.height;
|
|
557
|
+
}
|
|
540
558
|
};
|
|
541
559
|
|
|
542
560
|
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -489,7 +489,7 @@ shaka.hls.HlsParser = class {
|
|
|
489
489
|
mediaSequenceNumber);
|
|
490
490
|
stream.segmentIndex.evict(playlistStartTime);
|
|
491
491
|
}
|
|
492
|
-
const oldSegment =
|
|
492
|
+
const oldSegment = stream.segmentIndex.earliestReference();
|
|
493
493
|
goog.asserts.assert(oldSegment, 'Should have segments!');
|
|
494
494
|
|
|
495
495
|
streamInfo.minTimestamp = oldSegment.startTime;
|
|
@@ -4282,7 +4282,7 @@ shaka.hls.HlsParser = class {
|
|
|
4282
4282
|
}
|
|
4283
4283
|
|
|
4284
4284
|
const uri = drmTag.getRequiredAttrValue('URI');
|
|
4285
|
-
const parsedData = shaka.net.DataUriPlugin.parseRaw(uri);
|
|
4285
|
+
const parsedData = shaka.net.DataUriPlugin.parseRaw(uri.split('?')[0]);
|
|
4286
4286
|
|
|
4287
4287
|
// The data encoded in the URI is a PSSH box to be used as init data.
|
|
4288
4288
|
const pssh = shaka.util.BufferUtils.toUint8(parsedData.data);
|
|
@@ -4325,7 +4325,7 @@ shaka.hls.HlsParser = class {
|
|
|
4325
4325
|
}
|
|
4326
4326
|
|
|
4327
4327
|
const uri = drmTag.getRequiredAttrValue('URI');
|
|
4328
|
-
const parsedData = shaka.net.DataUriPlugin.parseRaw(uri);
|
|
4328
|
+
const parsedData = shaka.net.DataUriPlugin.parseRaw(uri.split('?')[0]);
|
|
4329
4329
|
|
|
4330
4330
|
// The data encoded in the URI is a PlayReady Pro Object, so we need
|
|
4331
4331
|
// convert it to pssh.
|
|
@@ -36,7 +36,8 @@ shaka.media.ContentWorkarounds = class {
|
|
|
36
36
|
*/
|
|
37
37
|
static fakeEncryption(initSegmentBuffer, uri) {
|
|
38
38
|
const ContentWorkarounds = shaka.media.ContentWorkarounds;
|
|
39
|
-
|
|
39
|
+
const initSegment = shaka.util.BufferUtils.toUint8(initSegmentBuffer);
|
|
40
|
+
let modifiedInitSegment = initSegment;
|
|
40
41
|
let isEncrypted = false;
|
|
41
42
|
/** @type {shaka.extern.ParsedBox} */
|
|
42
43
|
let stsdBox;
|
|
@@ -166,11 +167,24 @@ shaka.media.ContentWorkarounds = class {
|
|
|
166
167
|
const insertedBoxType =
|
|
167
168
|
shaka.util.Mp4Parser.typeToString(workItem.newType);
|
|
168
169
|
shaka.log.debug(`Inserting "${insertedBoxType}" box into init segment.`);
|
|
169
|
-
|
|
170
|
-
|
|
170
|
+
modifiedInitSegment = ContentWorkarounds.insertEncryptionMetadata_(
|
|
171
|
+
modifiedInitSegment, stsdBox, workItem.box, ancestorBoxes,
|
|
172
|
+
workItem.newType);
|
|
171
173
|
}
|
|
172
174
|
|
|
173
|
-
|
|
175
|
+
// Edge Windows needs the unmodified init segment to be appended after the
|
|
176
|
+
// patched one, otherwise video element throws following error:
|
|
177
|
+
// CHUNK_DEMUXER_ERROR_APPEND_FAILED: Sample encryption info is not
|
|
178
|
+
// available.
|
|
179
|
+
if (shaka.util.Platform.isEdge() && shaka.util.Platform.isWindows()) {
|
|
180
|
+
const doubleInitSegment = new Uint8Array(initSegment.byteLength +
|
|
181
|
+
modifiedInitSegment.byteLength);
|
|
182
|
+
doubleInitSegment.set(modifiedInitSegment);
|
|
183
|
+
doubleInitSegment.set(initSegment, modifiedInitSegment.byteLength);
|
|
184
|
+
return doubleInitSegment;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return modifiedInitSegment;
|
|
174
188
|
}
|
|
175
189
|
|
|
176
190
|
/**
|
|
@@ -197,11 +211,12 @@ shaka.media.ContentWorkarounds = class {
|
|
|
197
211
|
const newInitSegment =
|
|
198
212
|
new Uint8Array(initSegment.byteLength + metadataBoxArray.byteLength);
|
|
199
213
|
|
|
200
|
-
// For Xbox One, we cut and insert at the start of the source box.
|
|
201
|
-
// other platforms, we cut and insert at the end of the source box.
|
|
214
|
+
// For Xbox One & Edge, we cut and insert at the start of the source box.
|
|
215
|
+
// For other platforms, we cut and insert at the end of the source box. It's
|
|
202
216
|
// not clear why this is necessary on Xbox One, but it seems to be evidence
|
|
203
217
|
// of another bug in the firmware implementation of MediaSource & EME.
|
|
204
|
-
const cutPoint =
|
|
218
|
+
const cutPoint =
|
|
219
|
+
(shaka.util.Platform.isXboxOne() || shaka.util.Platform.isEdge()) ?
|
|
205
220
|
sourceBox.start :
|
|
206
221
|
sourceBox.start + sourceBox.size;
|
|
207
222
|
|
package/lib/media/drm_engine.js
CHANGED
|
@@ -12,6 +12,7 @@ goog.require('shaka.net.NetworkingEngine');
|
|
|
12
12
|
goog.require('shaka.transmuxer.TransmuxerEngine');
|
|
13
13
|
goog.require('shaka.util.BufferUtils');
|
|
14
14
|
goog.require('shaka.util.Destroyer');
|
|
15
|
+
goog.require('shaka.util.DrmUtils');
|
|
15
16
|
goog.require('shaka.util.Error');
|
|
16
17
|
goog.require('shaka.util.EventManager');
|
|
17
18
|
goog.require('shaka.util.FakeEvent');
|
|
@@ -178,12 +179,18 @@ shaka.media.DrmEngine = class {
|
|
|
178
179
|
|
|
179
180
|
// |video_| will be |null| if we never attached to a video element.
|
|
180
181
|
if (this.video_) {
|
|
181
|
-
|
|
182
|
+
// Webkit EME implementation requires the src to be defined to clear
|
|
183
|
+
// the MediaKeys.
|
|
184
|
+
if (!shaka.util.Platform.isMediaKeysPolyfilled('webkit')) {
|
|
185
|
+
goog.asserts.assert(!this.video_.src,
|
|
186
|
+
'video src must be removed first!');
|
|
187
|
+
}
|
|
182
188
|
|
|
183
189
|
try {
|
|
184
190
|
await this.video_.setMediaKeys(null);
|
|
185
191
|
} catch (error) {
|
|
186
192
|
// Ignore any failures while removing media keys from the video element.
|
|
193
|
+
shaka.log.debug(`DrmEngine.destroyNow_ exception`, error);
|
|
187
194
|
}
|
|
188
195
|
|
|
189
196
|
this.video_ = null;
|
|
@@ -762,28 +769,6 @@ shaka.media.DrmEngine = class {
|
|
|
762
769
|
return drmInfo ? drmInfo.keySystem : '';
|
|
763
770
|
}
|
|
764
771
|
|
|
765
|
-
/**
|
|
766
|
-
* @param {?string} keySystem
|
|
767
|
-
* @return {boolean} */
|
|
768
|
-
static isPlayReadyKeySystem(keySystem) {
|
|
769
|
-
if (keySystem) {
|
|
770
|
-
return !!keySystem.match(/^com\.(microsoft|chromecast)\.playready/);
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
return false;
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
/**
|
|
777
|
-
* @param {?string} keySystem
|
|
778
|
-
* @return {boolean} */
|
|
779
|
-
static isFairPlayKeySystem(keySystem) {
|
|
780
|
-
if (keySystem) {
|
|
781
|
-
return !!keySystem.match(/^com\.apple\.fps/);
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
return false;
|
|
785
|
-
}
|
|
786
|
-
|
|
787
772
|
/**
|
|
788
773
|
* Check if DrmEngine (as initialized) will likely be able to support the
|
|
789
774
|
* given content type.
|
|
@@ -1502,7 +1487,7 @@ shaka.media.DrmEngine = class {
|
|
|
1502
1487
|
}
|
|
1503
1488
|
// NOTE: allowCrossSiteCredentials can be set in a request filter.
|
|
1504
1489
|
|
|
1505
|
-
if (shaka.
|
|
1490
|
+
if (shaka.util.DrmUtils.isPlayReadyKeySystem(
|
|
1506
1491
|
this.currentDrmInfo_.keySystem)) {
|
|
1507
1492
|
this.unpackPlayReadyRequest_(request);
|
|
1508
1493
|
}
|
|
@@ -1686,7 +1671,7 @@ shaka.media.DrmEngine = class {
|
|
|
1686
1671
|
// NOTE that we skip this if byteLength != 16. This is used for Edge
|
|
1687
1672
|
// which uses single-byte dummy key IDs.
|
|
1688
1673
|
// However, unlike Edge and Chromecast, Tizen doesn't have this problem.
|
|
1689
|
-
if (shaka.
|
|
1674
|
+
if (shaka.util.DrmUtils.isPlayReadyKeySystem(
|
|
1690
1675
|
this.currentDrmInfo_.keySystem) &&
|
|
1691
1676
|
keyId.byteLength == 16 &&
|
|
1692
1677
|
(shaka.util.Platform.isEdge() || shaka.util.Platform.isPS4())) {
|
|
@@ -53,15 +53,17 @@ shaka.media.MediaSourceEngine = class {
|
|
|
53
53
|
* The text displayer that will be used with the text engine.
|
|
54
54
|
* MediaSourceEngine takes ownership of the displayer. When
|
|
55
55
|
* MediaSourceEngine is destroyed, it will destroy the displayer.
|
|
56
|
-
* @param {!
|
|
57
|
-
*
|
|
56
|
+
* @param {!shaka.media.MediaSourceEngine.PlayerInterface} playerInterface
|
|
57
|
+
* Interface for common player methods.
|
|
58
58
|
* @param {?shaka.lcevc.Dec} [lcevcDec] Optional - LCEVC Decoder Object
|
|
59
|
-
*
|
|
60
59
|
*/
|
|
61
|
-
constructor(video, textDisplayer,
|
|
60
|
+
constructor(video, textDisplayer, playerInterface, lcevcDec) {
|
|
62
61
|
/** @private {HTMLMediaElement} */
|
|
63
62
|
this.video_ = video;
|
|
64
63
|
|
|
64
|
+
/** @private {?shaka.media.MediaSourceEngine.PlayerInterface} */
|
|
65
|
+
this.playerInterface_ = playerInterface;
|
|
66
|
+
|
|
65
67
|
/** @private {?shaka.extern.MediaSourceConfiguration} */
|
|
66
68
|
this.config_ = null;
|
|
67
69
|
|
|
@@ -87,12 +89,6 @@ shaka.media.MediaSourceEngine = class {
|
|
|
87
89
|
/** @private {boolean} */
|
|
88
90
|
this.segmentRelativeVttTiming_ = false;
|
|
89
91
|
|
|
90
|
-
const onMetadataNoOp = (metadata, timestampOffset, segmentEnd) => {};
|
|
91
|
-
|
|
92
|
-
/** @private {!function(!Array.<shaka.extern.ID3Metadata>,
|
|
93
|
-
number, ?number)} */
|
|
94
|
-
this.onMetadata_ = onMetadata || onMetadataNoOp;
|
|
95
|
-
|
|
96
92
|
/** @private {?shaka.lcevc.Dec} */
|
|
97
93
|
this.lcevcDec_ = lcevcDec || null;
|
|
98
94
|
|
|
@@ -316,7 +312,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
316
312
|
'audio/mp4; codecs="mp4a.40.2"',
|
|
317
313
|
'audio/mp4; codecs="ac-3"',
|
|
318
314
|
'audio/mp4; codecs="ec-3"',
|
|
319
|
-
'audio/mp4; codecs="ac-4"',
|
|
315
|
+
'audio/mp4; codecs="ac-4.02.01.01"',
|
|
320
316
|
'audio/mp4; codecs="opus"',
|
|
321
317
|
'audio/mp4; codecs="flac"',
|
|
322
318
|
'audio/mp4; codecs="dtsc"', // DTS Digital Surround
|
|
@@ -438,6 +434,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
438
434
|
this.lcevcDec_ = null;
|
|
439
435
|
|
|
440
436
|
this.tsParser_ = null;
|
|
437
|
+
this.playerInterface_ = null;
|
|
441
438
|
}
|
|
442
439
|
|
|
443
440
|
/**
|
|
@@ -813,7 +810,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
813
810
|
dts: reference.startTime,
|
|
814
811
|
pts: reference.startTime,
|
|
815
812
|
};
|
|
816
|
-
this.
|
|
813
|
+
this.playerInterface_.onMetadata(
|
|
814
|
+
[metadata], /* offset= */ 0, reference.endTime);
|
|
817
815
|
}
|
|
818
816
|
} else if (mimeType.includes('/mp4') &&
|
|
819
817
|
reference && reference.timestampOffset == 0 &&
|
|
@@ -855,7 +853,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
855
853
|
}
|
|
856
854
|
const metadata = tsParser.getMetadata();
|
|
857
855
|
if (metadata.length) {
|
|
858
|
-
this.
|
|
856
|
+
this.playerInterface_.onMetadata(metadata, timestampOffset,
|
|
859
857
|
reference ? reference.endTime : null);
|
|
860
858
|
}
|
|
861
859
|
}
|
|
@@ -1719,8 +1717,11 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1719
1717
|
* @private
|
|
1720
1718
|
*/
|
|
1721
1719
|
workAroundBrokenPlatforms_(segment, startTime, contentType, uri) {
|
|
1720
|
+
const Platform = shaka.util.Platform;
|
|
1721
|
+
|
|
1722
1722
|
const isInitSegment = startTime == null;
|
|
1723
1723
|
const encryptionExpected = this.expectedEncryption_[contentType];
|
|
1724
|
+
const keySystem = this.playerInterface_.getKeySystem();
|
|
1724
1725
|
|
|
1725
1726
|
// If:
|
|
1726
1727
|
// 1. the configuration tells to insert fake encryption,
|
|
@@ -1735,7 +1736,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1735
1736
|
if (this.config_.insertFakeEncryptionInInit &&
|
|
1736
1737
|
isInitSegment &&
|
|
1737
1738
|
encryptionExpected &&
|
|
1738
|
-
|
|
1739
|
+
Platform.requiresEncryptionInfoInAllInitSegments(keySystem) &&
|
|
1739
1740
|
shaka.util.MimeUtils.getContainerType(
|
|
1740
1741
|
this.sourceBufferTypes_[contentType]) == 'mp4') {
|
|
1741
1742
|
shaka.log.debug('Forcing fake encryption information in init segment.');
|
|
@@ -2151,3 +2152,19 @@ shaka.media.MediaSourceEngine.SourceBufferMode_ = {
|
|
|
2151
2152
|
SEQUENCE: 'sequence',
|
|
2152
2153
|
SEGMENTS: 'segments',
|
|
2153
2154
|
};
|
|
2155
|
+
|
|
2156
|
+
|
|
2157
|
+
/**
|
|
2158
|
+
* @typedef {{
|
|
2159
|
+
* getKeySystem: function():?string,
|
|
2160
|
+
* onMetadata: function(!Array<shaka.extern.ID3Metadata>, number, ?number)
|
|
2161
|
+
* }}
|
|
2162
|
+
*
|
|
2163
|
+
* @summary Player interface
|
|
2164
|
+
* @property {function():?string} getKeySystem
|
|
2165
|
+
* Gets currently used key system or null if not used.
|
|
2166
|
+
* @property {function(
|
|
2167
|
+
* !Array<shaka.extern.ID3Metadata>, number, ?number)} onMetadata
|
|
2168
|
+
* Callback to use when metadata arrives.
|
|
2169
|
+
*/
|
|
2170
|
+
shaka.media.MediaSourceEngine.PlayerInterface;
|
package/lib/player.js
CHANGED
|
@@ -901,21 +901,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
901
901
|
*/
|
|
902
902
|
setupLcevc_(config) {
|
|
903
903
|
if (config.lcevc.enabled) {
|
|
904
|
-
const tracks = this.getVariantTracks();
|
|
905
|
-
if (tracks && tracks[0] && tracks[0].videoMimeType == 'video/mp2t') {
|
|
906
|
-
const edge = shaka.util.Platform.isEdge() ||
|
|
907
|
-
shaka.util.Platform.isLegacyEdge();
|
|
908
|
-
if (edge) {
|
|
909
|
-
if (!config.mediaSource.forceTransmux) {
|
|
910
|
-
// If forceTransmux is disabled for Microsoft Edge, LCEVC data
|
|
911
|
-
// is stripped out in case of a MPEG-2 TS container.
|
|
912
|
-
// Hence the warning for Microsoft Edge when playing content with
|
|
913
|
-
// MPEG-2 TS container.
|
|
914
|
-
shaka.log.alwaysWarn('LCEVC Warning: For MPEG-2 TS decoding '+
|
|
915
|
-
'the config.mediaSource.forceTransmux must be enabled.');
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
904
|
this.closeLcevcDec_();
|
|
920
905
|
this.createLcevcDec_(config.lcevc);
|
|
921
906
|
} else {
|
|
@@ -1371,6 +1356,13 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1371
1356
|
this.playhead_ = null;
|
|
1372
1357
|
}
|
|
1373
1358
|
|
|
1359
|
+
// EME v0.1b requires the media element to clear the MediaKeys
|
|
1360
|
+
if (shaka.util.Platform.isMediaKeysPolyfilled('webkit') &&
|
|
1361
|
+
this.drmEngine_) {
|
|
1362
|
+
await this.drmEngine_.destroy();
|
|
1363
|
+
this.drmEngine_ = null;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1374
1366
|
// Media source engine holds onto the media element, and in order to
|
|
1375
1367
|
// detach the media keys (with drm engine), we need to break the
|
|
1376
1368
|
// connection between media source engine and the media element.
|
|
@@ -2268,8 +2260,11 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2268
2260
|
const mediaSourceEngine = this.createMediaSourceEngine(
|
|
2269
2261
|
this.video_,
|
|
2270
2262
|
textDisplayer,
|
|
2271
|
-
|
|
2272
|
-
this.
|
|
2263
|
+
{
|
|
2264
|
+
getKeySystem: () => this.keySystem(),
|
|
2265
|
+
onMetadata: (metadata, offset, endTime) => {
|
|
2266
|
+
this.processTimedMetadataMediaSrc_(metadata, offset, endTime);
|
|
2267
|
+
},
|
|
2273
2268
|
},
|
|
2274
2269
|
this.lcevcDec_);
|
|
2275
2270
|
mediaSourceEngine.configure(this.config_.mediaSource);
|
|
@@ -3403,17 +3398,17 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3403
3398
|
*
|
|
3404
3399
|
* @param {!HTMLMediaElement} mediaElement
|
|
3405
3400
|
* @param {!shaka.extern.TextDisplayer} textDisplayer
|
|
3406
|
-
* @param {!
|
|
3407
|
-
* onMetadata
|
|
3401
|
+
* @param {!shaka.media.MediaSourceEngine.PlayerInterface} playerInterface
|
|
3408
3402
|
* @param {shaka.lcevc.Dec} lcevcDec
|
|
3409
3403
|
*
|
|
3410
3404
|
* @return {!shaka.media.MediaSourceEngine}
|
|
3411
3405
|
*/
|
|
3412
|
-
createMediaSourceEngine(mediaElement, textDisplayer,
|
|
3406
|
+
createMediaSourceEngine(mediaElement, textDisplayer, playerInterface,
|
|
3407
|
+
lcevcDec) {
|
|
3413
3408
|
return new shaka.media.MediaSourceEngine(
|
|
3414
3409
|
mediaElement,
|
|
3415
3410
|
textDisplayer,
|
|
3416
|
-
|
|
3411
|
+
playerInterface,
|
|
3417
3412
|
lcevcDec);
|
|
3418
3413
|
}
|
|
3419
3414
|
|
|
@@ -7454,7 +7449,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
7454
7449
|
* @export
|
|
7455
7450
|
*/
|
|
7456
7451
|
// eslint-disable-next-line no-useless-concat
|
|
7457
|
-
shaka.Player.version = 'v4.9.
|
|
7452
|
+
shaka.Player.version = 'v4.9.4' + '-uncompiled'; // x-release-please-version
|
|
7458
7453
|
|
|
7459
7454
|
// Initialize the deprecation system using the version string we just set
|
|
7460
7455
|
// on the player.
|
|
@@ -76,7 +76,7 @@ shaka.polyfill.PatchedMediaKeysApple = class {
|
|
|
76
76
|
navigator.requestMediaKeySystemAccess =
|
|
77
77
|
PatchedMediaKeysApple.requestMediaKeySystemAccess;
|
|
78
78
|
|
|
79
|
-
window.shakaMediaKeysPolyfill =
|
|
79
|
+
window.shakaMediaKeysPolyfill = PatchedMediaKeysApple.apiName_;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/**
|
|
@@ -115,7 +115,7 @@ shaka.polyfill.PatchedMediaKeysApple = class {
|
|
|
115
115
|
PatchedMediaKeysApple.originalNavigatorRequestMediaKeySystemAccess = null;
|
|
116
116
|
PatchedMediaKeysApple.originalHTMLMediaElementPrototypeMediaKeys = null;
|
|
117
117
|
|
|
118
|
-
window.shakaMediaKeysPolyfill =
|
|
118
|
+
window.shakaMediaKeysPolyfill = '';
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
/**
|
|
@@ -791,3 +791,10 @@ shaka.polyfill.PatchedMediaKeysApple.MediaKeyStatusMap = class {
|
|
|
791
791
|
goog.asserts.assert(false, 'Not used! Provided only for the compiler.');
|
|
792
792
|
}
|
|
793
793
|
};
|
|
794
|
+
|
|
795
|
+
/**
|
|
796
|
+
* API name.
|
|
797
|
+
*
|
|
798
|
+
* @private {string}
|
|
799
|
+
*/
|
|
800
|
+
shaka.polyfill.PatchedMediaKeysApple.apiName_ = 'apple';
|
|
@@ -50,7 +50,7 @@ shaka.polyfill.PatchedMediaKeysNop = class {
|
|
|
50
50
|
window.MediaKeys = PatchedMediaKeysNop.MediaKeys;
|
|
51
51
|
window.MediaKeySystemAccess = PatchedMediaKeysNop.MediaKeySystemAccess;
|
|
52
52
|
|
|
53
|
-
window.shakaMediaKeysPolyfill =
|
|
53
|
+
window.shakaMediaKeysPolyfill = PatchedMediaKeysNop.apiName_;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/**
|
|
@@ -136,6 +136,13 @@ shaka.polyfill.PatchedMediaKeysNop.MediaKeySystemAccess = class {
|
|
|
136
136
|
createMediaKeys() {}
|
|
137
137
|
};
|
|
138
138
|
|
|
139
|
+
/**
|
|
140
|
+
* API name.
|
|
141
|
+
*
|
|
142
|
+
* @private {string}
|
|
143
|
+
*/
|
|
144
|
+
shaka.polyfill.PatchedMediaKeysNop.apiName_ = 'nop';
|
|
145
|
+
|
|
139
146
|
|
|
140
147
|
// A low priority ensures this is the last and acts as a fallback.
|
|
141
148
|
shaka.polyfill.register(shaka.polyfill.PatchedMediaKeysNop.install, -10);
|
|
@@ -73,7 +73,7 @@ shaka.polyfill.PatchedMediaKeysWebkit = class {
|
|
|
73
73
|
window.MediaKeys = PatchedMediaKeysWebkit.MediaKeys;
|
|
74
74
|
window.MediaKeySystemAccess = PatchedMediaKeysWebkit.MediaKeySystemAccess;
|
|
75
75
|
|
|
76
|
-
window.shakaMediaKeysPolyfill =
|
|
76
|
+
window.shakaMediaKeysPolyfill = PatchedMediaKeysWebkit.apiName_;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
/**
|
|
@@ -860,7 +860,9 @@ class extends shaka.util.FakeEventTarget {
|
|
|
860
860
|
PatchedMediaKeysWebkit.prefixApi_('cancelKeyRequest');
|
|
861
861
|
try {
|
|
862
862
|
this.media_[cancelKeyRequestName](this.keySystem_, this.sessionId);
|
|
863
|
-
} catch (exception) {
|
|
863
|
+
} catch (exception) {
|
|
864
|
+
shaka.log.debug(`${cancelKeyRequestName} exception`, exception);
|
|
865
|
+
}
|
|
864
866
|
}
|
|
865
867
|
|
|
866
868
|
// Resolve the 'closed' promise and return it.
|
|
@@ -977,4 +979,12 @@ shaka.polyfill.PatchedMediaKeysWebkit.MediaKeyStatusMap = class {
|
|
|
977
979
|
shaka.polyfill.PatchedMediaKeysWebkit.prefix_ = '';
|
|
978
980
|
|
|
979
981
|
|
|
982
|
+
/**
|
|
983
|
+
* API name.
|
|
984
|
+
*
|
|
985
|
+
* @private {string}
|
|
986
|
+
*/
|
|
987
|
+
shaka.polyfill.PatchedMediaKeysWebkit.apiName_ = 'webkit';
|
|
988
|
+
|
|
989
|
+
|
|
980
990
|
shaka.polyfill.register(shaka.polyfill.PatchedMediaKeysWebkit.install);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
goog.provide('shaka.util.DrmUtils');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
shaka.util.DrmUtils = class {
|
|
11
|
+
/**
|
|
12
|
+
* @param {?string} keySystem
|
|
13
|
+
* @return {boolean}
|
|
14
|
+
*/
|
|
15
|
+
static isPlayReadyKeySystem(keySystem) {
|
|
16
|
+
if (keySystem) {
|
|
17
|
+
return !!keySystem.match(/^com\.(microsoft|chromecast)\.playready/);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {?string} keySystem
|
|
25
|
+
* @return {boolean}
|
|
26
|
+
*/
|
|
27
|
+
static isFairPlayKeySystem(keySystem) {
|
|
28
|
+
if (keySystem) {
|
|
29
|
+
return !!keySystem.match(/^com\.apple\.fps/);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
};
|
package/lib/util/platform.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
goog.provide('shaka.util.Platform');
|
|
8
8
|
|
|
9
9
|
goog.require('shaka.log');
|
|
10
|
+
goog.require('shaka.util.DrmUtils');
|
|
10
11
|
goog.require('shaka.util.Timer');
|
|
11
12
|
|
|
12
13
|
|
|
@@ -590,12 +591,15 @@ shaka.util.Platform = class {
|
|
|
590
591
|
* around a lack of such info by inserting fake encryption information into
|
|
591
592
|
* initialization segments.
|
|
592
593
|
*
|
|
594
|
+
* @param {?string} keySystem
|
|
593
595
|
* @return {boolean}
|
|
594
596
|
* @see https://github.com/shaka-project/shaka-player/issues/2759
|
|
595
597
|
*/
|
|
596
|
-
static requiresEncryptionInfoInAllInitSegments() {
|
|
598
|
+
static requiresEncryptionInfoInAllInitSegments(keySystem) {
|
|
597
599
|
const Platform = shaka.util.Platform;
|
|
598
|
-
|
|
600
|
+
const isPlayReady = shaka.util.DrmUtils.isPlayReadyKeySystem(keySystem);
|
|
601
|
+
return Platform.isTizen() || Platform.isXboxOne() || Platform.isOrange() ||
|
|
602
|
+
(Platform.isEdge() && Platform.isWindows() && isPlayReady);
|
|
599
603
|
}
|
|
600
604
|
|
|
601
605
|
/**
|
|
@@ -644,16 +648,17 @@ shaka.util.Platform = class {
|
|
|
644
648
|
/**
|
|
645
649
|
* Returns true if MediaKeys is polyfilled
|
|
646
650
|
*
|
|
651
|
+
* @param {string=} polyfillType
|
|
647
652
|
* @return {boolean}
|
|
648
653
|
*/
|
|
649
|
-
static isMediaKeysPolyfilled() {
|
|
650
|
-
if (
|
|
651
|
-
return
|
|
654
|
+
static isMediaKeysPolyfilled(polyfillType) {
|
|
655
|
+
if (polyfillType) {
|
|
656
|
+
return polyfillType === window.shakaMediaKeysPolyfill;
|
|
652
657
|
}
|
|
653
|
-
|
|
654
|
-
return false;
|
|
658
|
+
return !!window.shakaMediaKeysPolyfill;
|
|
655
659
|
}
|
|
656
660
|
|
|
661
|
+
|
|
657
662
|
/**
|
|
658
663
|
* Detect the maximum resolution that the platform's hardware can handle.
|
|
659
664
|
*
|