shaka-player 4.10.2 → 4.10.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 +5 -4
- package/dist/locales.js +36 -36
- package/dist/shaka-player.compiled.debug.externs.js +83 -83
- package/dist/shaka-player.compiled.debug.js +399 -396
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +83 -83
- package/dist/shaka-player.compiled.js +1100 -1097
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.debug.externs.js +83 -83
- package/dist/shaka-player.ui.debug.js +410 -407
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +83 -83
- package/dist/shaka-player.ui.js +1219 -1217
- package/dist/shaka-player.ui.map +4 -4
- package/lib/ads/interstitial_ad_manager.js +5 -4
- package/lib/hls/hls_parser.js +24 -14
- package/lib/media/media_source_engine.js +40 -1
- package/lib/media/playhead.js +15 -6
- package/lib/media/segment_utils.js +48 -10
- package/lib/media/streaming_engine.js +12 -62
- package/lib/player.js +12 -8
- package/lib/text/cue.js +1 -117
- package/lib/text/cue_region.js +123 -0
- package/lib/text/ui_text_displayer.js +20 -3
- package/lib/util/mp4_box_parsers.js +42 -0
- package/lib/util/platform.js +35 -16
- package/lib/util/stream_utils.js +4 -2
- package/package.json +1 -1
- package/ui/seek_bar.js +5 -6
|
@@ -108,7 +108,8 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
108
108
|
const interstitials = Array.from(this.interstitials_);
|
|
109
109
|
const seekRange = this.basePlayer_.seekRange();
|
|
110
110
|
for (const interstitial of interstitials) {
|
|
111
|
-
|
|
111
|
+
const comparisonTime = interstitial.endTime || interstitial.startTime;
|
|
112
|
+
if ((seekRange.start - comparisonTime) >= 1) {
|
|
112
113
|
if (this.preloadManagerInterstitials_.has(interstitial)) {
|
|
113
114
|
const preloadManager =
|
|
114
115
|
// eslint-disable-next-line no-await-in-loop
|
|
@@ -646,12 +647,12 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
646
647
|
const dataAsJson =
|
|
647
648
|
/** @type {!shaka.ads.InterstitialAdManager.AssetsList} */ (
|
|
648
649
|
JSON.parse(data));
|
|
649
|
-
for (const asset of dataAsJson
|
|
650
|
-
if (asset
|
|
650
|
+
for (const asset of dataAsJson['ASSETS']) {
|
|
651
|
+
if (asset['URI']) {
|
|
651
652
|
interstitialsAd.push({
|
|
652
653
|
startTime: interstitial.startTime,
|
|
653
654
|
endTime: interstitial.endTime,
|
|
654
|
-
uri: asset
|
|
655
|
+
uri: asset['URI'],
|
|
655
656
|
isSkippable,
|
|
656
657
|
canJump,
|
|
657
658
|
resumeOffset,
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -1019,7 +1019,7 @@ shaka.hls.HlsParser = class {
|
|
|
1019
1019
|
if (!segments.length) {
|
|
1020
1020
|
return defaultBasicInfo;
|
|
1021
1021
|
}
|
|
1022
|
-
const segment = this.getAvailableSegment_(segments);
|
|
1022
|
+
const {segment, segmentIndex} = this.getAvailableSegment_(segments);
|
|
1023
1023
|
const segmentUris = segment.getUris();
|
|
1024
1024
|
const segmentUri = segmentUris[0];
|
|
1025
1025
|
const parsedUri = new goog.Uri(segmentUri);
|
|
@@ -1044,6 +1044,10 @@ shaka.hls.HlsParser = class {
|
|
|
1044
1044
|
const initResponse = await this.makeNetworkRequest_(
|
|
1045
1045
|
initSegmentRequest, requestType, {type: initType});
|
|
1046
1046
|
initData = initResponse.data;
|
|
1047
|
+
if (initSegmentRef.aesKey) {
|
|
1048
|
+
initData = await shaka.media.SegmentUtils.aesDecrypt(
|
|
1049
|
+
initData, initSegmentRef.aesKey, 0);
|
|
1050
|
+
}
|
|
1047
1051
|
|
|
1048
1052
|
initMimeType = initResponse.headers['content-type'];
|
|
1049
1053
|
if (initMimeType) {
|
|
@@ -1058,6 +1062,11 @@ shaka.hls.HlsParser = class {
|
|
|
1058
1062
|
const type = shaka.net.NetworkingEngine.AdvancedRequestType.MEDIA_SEGMENT;
|
|
1059
1063
|
const response = await this.makeNetworkRequest_(
|
|
1060
1064
|
segmentRequest, requestType, {type});
|
|
1065
|
+
let data = response.data;
|
|
1066
|
+
if (segment.aesKey) {
|
|
1067
|
+
data = await shaka.media.SegmentUtils.aesDecrypt(
|
|
1068
|
+
data, segment.aesKey, segmentIndex);
|
|
1069
|
+
}
|
|
1061
1070
|
|
|
1062
1071
|
let contentMimeType = response.headers['content-type'];
|
|
1063
1072
|
if (contentMimeType) {
|
|
@@ -1085,9 +1094,9 @@ shaka.hls.HlsParser = class {
|
|
|
1085
1094
|
];
|
|
1086
1095
|
|
|
1087
1096
|
if (shaka.util.TsParser.probe(
|
|
1088
|
-
shaka.util.BufferUtils.toUint8(
|
|
1097
|
+
shaka.util.BufferUtils.toUint8(data))) {
|
|
1089
1098
|
const basicInfo =
|
|
1090
|
-
shaka.media.SegmentUtils.getBasicInfoFromTs(
|
|
1099
|
+
shaka.media.SegmentUtils.getBasicInfoFromTs(data);
|
|
1091
1100
|
if (basicInfo) {
|
|
1092
1101
|
return basicInfo;
|
|
1093
1102
|
}
|
|
@@ -1095,7 +1104,7 @@ shaka.hls.HlsParser = class {
|
|
|
1095
1104
|
validMp4MimeType.includes(contentMimeType) ||
|
|
1096
1105
|
(initMimeType && validMp4MimeType.includes(initMimeType))) {
|
|
1097
1106
|
const basicInfo = shaka.media.SegmentUtils.getBasicInfoFromMp4(
|
|
1098
|
-
initData,
|
|
1107
|
+
initData, data);
|
|
1099
1108
|
if (basicInfo) {
|
|
1100
1109
|
return basicInfo;
|
|
1101
1110
|
}
|
|
@@ -1579,7 +1588,7 @@ shaka.hls.HlsParser = class {
|
|
|
1579
1588
|
videoLayout = videoLayout || 'CH-MONO';
|
|
1580
1589
|
|
|
1581
1590
|
const streamInfos = this.createStreamInfosForVariantTags_(tags,
|
|
1582
|
-
mediaTags, resolution, frameRate
|
|
1591
|
+
mediaTags, resolution, frameRate);
|
|
1583
1592
|
|
|
1584
1593
|
goog.asserts.assert(streamInfos.audio.length ||
|
|
1585
1594
|
streamInfos.video.length, 'We should have created a stream!');
|
|
@@ -1607,12 +1616,10 @@ shaka.hls.HlsParser = class {
|
|
|
1607
1616
|
* @param {!Array.<!shaka.hls.Tag>} mediaTags
|
|
1608
1617
|
* @param {?string} resolution
|
|
1609
1618
|
* @param {?string} frameRate
|
|
1610
|
-
* @param {number} bandwidth
|
|
1611
1619
|
* @return {!shaka.hls.HlsParser.StreamInfos}
|
|
1612
1620
|
* @private
|
|
1613
1621
|
*/
|
|
1614
|
-
createStreamInfosForVariantTags_(
|
|
1615
|
-
tags, mediaTags, resolution, frameRate, bandwidth) {
|
|
1622
|
+
createStreamInfosForVariantTags_(tags, mediaTags, resolution, frameRate) {
|
|
1616
1623
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
1617
1624
|
|
|
1618
1625
|
/** @type {shaka.hls.HlsParser.StreamInfos} */
|
|
@@ -1747,9 +1754,6 @@ shaka.hls.HlsParser = class {
|
|
|
1747
1754
|
if (globalGroupId) {
|
|
1748
1755
|
streamInfo.stream.groupId = globalGroupId;
|
|
1749
1756
|
}
|
|
1750
|
-
if (!streamInfos.length) {
|
|
1751
|
-
streamInfo.stream.bandwidth = bandwidth;
|
|
1752
|
-
}
|
|
1753
1757
|
res[streamInfo.stream.type] = [streamInfo];
|
|
1754
1758
|
}
|
|
1755
1759
|
return res;
|
|
@@ -1971,6 +1975,12 @@ shaka.hls.HlsParser = class {
|
|
|
1971
1975
|
videoStream.drmInfos = drmInfos;
|
|
1972
1976
|
videoStream.keyIds = keyIds;
|
|
1973
1977
|
}
|
|
1978
|
+
if (videoStream && !audioStream) {
|
|
1979
|
+
videoStream.bandwidth = bandwidth;
|
|
1980
|
+
}
|
|
1981
|
+
if (!videoStream && audioStream) {
|
|
1982
|
+
audioStream.bandwidth = bandwidth;
|
|
1983
|
+
}
|
|
1974
1984
|
const audioDrmInfos = audioInfo ? audioInfo.stream.drmInfos : null;
|
|
1975
1985
|
const videoDrmInfos = videoInfo ? videoInfo.stream.drmInfos : null;
|
|
1976
1986
|
const videoStreamUri =
|
|
@@ -4224,7 +4234,7 @@ shaka.hls.HlsParser = class {
|
|
|
4224
4234
|
|
|
4225
4235
|
/**
|
|
4226
4236
|
* @param {!Array.<!shaka.media.SegmentReference>} segments
|
|
4227
|
-
* @return {!shaka.media.SegmentReference}
|
|
4237
|
+
* @return {{segment: !shaka.media.SegmentReference, segmentIndex: number}}
|
|
4228
4238
|
* @private
|
|
4229
4239
|
*/
|
|
4230
4240
|
getAvailableSegment_(segments) {
|
|
@@ -4241,7 +4251,7 @@ shaka.hls.HlsParser = class {
|
|
|
4241
4251
|
segmentIndex ++;
|
|
4242
4252
|
segment = segments[segmentIndex];
|
|
4243
4253
|
}
|
|
4244
|
-
return segment;
|
|
4254
|
+
return {segment, segmentIndex};
|
|
4245
4255
|
}
|
|
4246
4256
|
|
|
4247
4257
|
/**
|
|
@@ -4257,7 +4267,7 @@ shaka.hls.HlsParser = class {
|
|
|
4257
4267
|
const HlsParser = shaka.hls.HlsParser;
|
|
4258
4268
|
const requestType = shaka.net.NetworkingEngine.RequestType.SEGMENT;
|
|
4259
4269
|
|
|
4260
|
-
const segment = this.getAvailableSegment_(segments);
|
|
4270
|
+
const {segment} = this.getAvailableSegment_(segments);
|
|
4261
4271
|
|
|
4262
4272
|
if (segment.status == shaka.media.SegmentReference.Status.MISSING) {
|
|
4263
4273
|
return this.guessMimeTypeFallback_(contentType);
|
|
@@ -151,6 +151,15 @@ shaka.media.MediaSourceEngine = class {
|
|
|
151
151
|
|
|
152
152
|
/** @private {?shaka.util.TsParser} */
|
|
153
153
|
this.tsParser_ = null;
|
|
154
|
+
|
|
155
|
+
/** @private {?number} */
|
|
156
|
+
this.firstVideoTimestamp_ = null;
|
|
157
|
+
|
|
158
|
+
/** @private {?number} */
|
|
159
|
+
this.firstAudioTimestamp_ = null;
|
|
160
|
+
|
|
161
|
+
/** @private {!shaka.util.PublicPromise.<number>} */
|
|
162
|
+
this.audioCompensation_ = new shaka.util.PublicPromise();
|
|
154
163
|
}
|
|
155
164
|
|
|
156
165
|
/**
|
|
@@ -924,6 +933,24 @@ shaka.media.MediaSourceEngine = class {
|
|
|
924
933
|
const timestamp = this.getTimestampAndDispatchMetadata_(
|
|
925
934
|
contentType, data, reference, mimeType, timestampOffset);
|
|
926
935
|
if (timestamp != null) {
|
|
936
|
+
if (this.firstVideoTimestamp_ == null &&
|
|
937
|
+
contentType == ContentType.VIDEO) {
|
|
938
|
+
this.firstVideoTimestamp_ = timestamp;
|
|
939
|
+
if (this.firstAudioTimestamp_ != null) {
|
|
940
|
+
const compensation =
|
|
941
|
+
this.firstVideoTimestamp_ - this.firstAudioTimestamp_;
|
|
942
|
+
this.audioCompensation_.resolve(compensation);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
if (this.firstAudioTimestamp_ == null &&
|
|
946
|
+
contentType == ContentType.AUDIO) {
|
|
947
|
+
this.firstAudioTimestamp_ = timestamp;
|
|
948
|
+
if (this.firstVideoTimestamp_ != null) {
|
|
949
|
+
const compensation =
|
|
950
|
+
this.firstVideoTimestamp_ - this.firstAudioTimestamp_;
|
|
951
|
+
this.audioCompensation_.resolve(compensation);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
927
954
|
const calculatedTimestampOffset = reference.startTime - timestamp;
|
|
928
955
|
const timestampOffsetDifference =
|
|
929
956
|
Math.abs(timestampOffset - calculatedTimestampOffset);
|
|
@@ -992,7 +1019,19 @@ shaka.media.MediaSourceEngine = class {
|
|
|
992
1019
|
// and are either performing an unbuffered seek or handling an automatic
|
|
993
1020
|
// adaptation, we need to set a new timestampOffset on the sourceBuffer.
|
|
994
1021
|
if (seeked || adaptation) {
|
|
995
|
-
|
|
1022
|
+
let timestampOffset = reference.startTime;
|
|
1023
|
+
// Audio and video may not be aligned, so we will compensate for audio
|
|
1024
|
+
// if necessary.
|
|
1025
|
+
if (this.manifestType_ == shaka.media.ManifestParser.HLS &&
|
|
1026
|
+
!this.needSplitMuxedContent_ &&
|
|
1027
|
+
contentType == ContentType.AUDIO &&
|
|
1028
|
+
this.sourceBuffers_[ContentType.VIDEO]) {
|
|
1029
|
+
const compensation = await this.audioCompensation_;
|
|
1030
|
+
// Only apply compensation if the difference is greater than 100ms
|
|
1031
|
+
if (Math.abs(compensation) > 0.1) {
|
|
1032
|
+
timestampOffset -= compensation;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
996
1035
|
// The logic to call abort() before setting the timestampOffset is
|
|
997
1036
|
// extended during unbuffered seeks or automatic adaptations; it is
|
|
998
1037
|
// possible for the append state to be PARSING_MEDIA_SEGMENT from the
|
package/lib/media/playhead.js
CHANGED
|
@@ -18,6 +18,7 @@ goog.require('shaka.media.VideoWrapper');
|
|
|
18
18
|
goog.require('shaka.util.EventManager');
|
|
19
19
|
goog.require('shaka.util.IReleasable');
|
|
20
20
|
goog.require('shaka.util.MediaReadyState');
|
|
21
|
+
goog.require('shaka.util.Platform');
|
|
21
22
|
goog.require('shaka.util.Timer');
|
|
22
23
|
goog.requireType('shaka.media.PresentationTimeline');
|
|
23
24
|
|
|
@@ -420,12 +421,20 @@ shaka.media.MediaSourcePlayhead = class {
|
|
|
420
421
|
|
|
421
422
|
const gapLimit = shaka.media.GapJumpingController.BROWSER_GAP_TOLERANCE;
|
|
422
423
|
if (Math.abs(targetTime - currentTime) > gapLimit) {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
424
|
+
let canCorrectiveSeek = false;
|
|
425
|
+
if (shaka.util.Platform.isSeekingSlow()) {
|
|
426
|
+
// You can only seek like this every so often. This is to prevent an
|
|
427
|
+
// infinite loop on systems where changing currentTime takes a
|
|
428
|
+
// significant amount of time (e.g. Chromecast).
|
|
429
|
+
const time = Date.now() / 1000;
|
|
430
|
+
if (!this.lastCorrectiveSeek_ || this.lastCorrectiveSeek_ < time - 1) {
|
|
431
|
+
this.lastCorrectiveSeek_ = time;
|
|
432
|
+
canCorrectiveSeek = true;
|
|
433
|
+
}
|
|
434
|
+
} else {
|
|
435
|
+
canCorrectiveSeek = true;
|
|
436
|
+
}
|
|
437
|
+
if (canCorrectiveSeek) {
|
|
429
438
|
this.videoWrapper_.setTime(targetTime);
|
|
430
439
|
return;
|
|
431
440
|
}
|
|
@@ -218,21 +218,18 @@ shaka.media.SegmentUtils = class {
|
|
|
218
218
|
|
|
219
219
|
const genericVideoBox = (box) => {
|
|
220
220
|
baseBox = box.name;
|
|
221
|
-
|
|
221
|
+
const parsedVisualSampleEntryBox =
|
|
222
|
+
shaka.util.Mp4BoxParsers.visualSampleEntry(box.reader);
|
|
223
|
+
width = String(parsedVisualSampleEntryBox.width);
|
|
224
|
+
height = String(parsedVisualSampleEntryBox.height);
|
|
225
|
+
if (box.reader.hasMoreData()) {
|
|
226
|
+
Mp4Parser.children(box);
|
|
227
|
+
}
|
|
222
228
|
};
|
|
223
229
|
|
|
224
230
|
new Mp4Parser()
|
|
225
231
|
.box('moov', Mp4Parser.children)
|
|
226
232
|
.box('trak', Mp4Parser.children)
|
|
227
|
-
.fullBox('tkhd', (box) => {
|
|
228
|
-
goog.asserts.assert(
|
|
229
|
-
box.version != null,
|
|
230
|
-
'TKHD is a full box and should have a valid version.');
|
|
231
|
-
const parsedTKHDBox = shaka.util.Mp4BoxParsers.parseTKHD(
|
|
232
|
-
box.reader, box.version);
|
|
233
|
-
height = String(parsedTKHDBox.height);
|
|
234
|
-
width = String(parsedTKHDBox.width);
|
|
235
|
-
})
|
|
236
233
|
.box('mdia', Mp4Parser.children)
|
|
237
234
|
.fullBox('mdhd', (box) => {
|
|
238
235
|
goog.asserts.assert(
|
|
@@ -537,6 +534,47 @@ shaka.media.SegmentUtils = class {
|
|
|
537
534
|
.parse(data, /* partialOkay= */ true);
|
|
538
535
|
return defaultKID;
|
|
539
536
|
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* @param {!BufferSource} rawResult
|
|
540
|
+
* @param {shaka.extern.aesKey} aesKey
|
|
541
|
+
* @param {number} position
|
|
542
|
+
* @return {!Promise.<!BufferSource>}
|
|
543
|
+
*/
|
|
544
|
+
static async aesDecrypt(rawResult, aesKey, position) {
|
|
545
|
+
const key = aesKey;
|
|
546
|
+
if (!key.cryptoKey) {
|
|
547
|
+
goog.asserts.assert(key.fetchKey, 'If AES cryptoKey was not ' +
|
|
548
|
+
'preloaded, fetchKey function should be provided');
|
|
549
|
+
await key.fetchKey();
|
|
550
|
+
goog.asserts.assert(key.cryptoKey, 'AES cryptoKey should now be set');
|
|
551
|
+
}
|
|
552
|
+
let iv = key.iv;
|
|
553
|
+
if (!iv) {
|
|
554
|
+
iv = shaka.util.BufferUtils.toUint8(new ArrayBuffer(16));
|
|
555
|
+
let sequence = key.firstMediaSequenceNumber + position;
|
|
556
|
+
for (let i = iv.byteLength - 1; i >= 0; i--) {
|
|
557
|
+
iv[i] = sequence & 0xff;
|
|
558
|
+
sequence >>= 8;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
let algorithm;
|
|
562
|
+
if (aesKey.blockCipherMode == 'CBC') {
|
|
563
|
+
algorithm = {
|
|
564
|
+
name: 'AES-CBC',
|
|
565
|
+
iv,
|
|
566
|
+
};
|
|
567
|
+
} else {
|
|
568
|
+
algorithm = {
|
|
569
|
+
name: 'AES-CTR',
|
|
570
|
+
counter: iv,
|
|
571
|
+
// NIST SP800-38A standard suggests that the counter should occupy half
|
|
572
|
+
// of the counter block
|
|
573
|
+
length: 64,
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
return window.crypto.subtle.decrypt(algorithm, key.cryptoKey, rawResult);
|
|
577
|
+
}
|
|
540
578
|
};
|
|
541
579
|
|
|
542
580
|
|
|
@@ -18,9 +18,9 @@ goog.require('shaka.media.MediaSourceEngine');
|
|
|
18
18
|
goog.require('shaka.media.SegmentIterator');
|
|
19
19
|
goog.require('shaka.media.SegmentReference');
|
|
20
20
|
goog.require('shaka.media.SegmentPrefetch');
|
|
21
|
+
goog.require('shaka.media.SegmentUtils');
|
|
21
22
|
goog.require('shaka.net.Backoff');
|
|
22
23
|
goog.require('shaka.net.NetworkingEngine');
|
|
23
|
-
goog.require('shaka.util.BufferUtils');
|
|
24
24
|
goog.require('shaka.util.DelayedTick');
|
|
25
25
|
goog.require('shaka.util.Destroyer');
|
|
26
26
|
goog.require('shaka.util.Error');
|
|
@@ -769,25 +769,16 @@ shaka.media.StreamingEngine = class {
|
|
|
769
769
|
const mediaState = this.mediaStates_.get(type);
|
|
770
770
|
const logPrefix = shaka.media.StreamingEngine.logPrefix_(mediaState);
|
|
771
771
|
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
for (const prefetch of this.audioPrefetchMap_.values()) {
|
|
781
|
-
prefetch.resetPosition();
|
|
772
|
+
if (!newTimeIsBuffered(type)) {
|
|
773
|
+
if (mediaState.segmentPrefetch) {
|
|
774
|
+
mediaState.segmentPrefetch.resetPosition();
|
|
775
|
+
}
|
|
776
|
+
if (mediaState.type === ContentType.AUDIO) {
|
|
777
|
+
for (const prefetch of this.audioPrefetchMap_.values()) {
|
|
778
|
+
prefetch.resetPosition();
|
|
779
|
+
}
|
|
782
780
|
}
|
|
783
|
-
}
|
|
784
|
-
// Only reset the iterator if we seek outside the current segment.
|
|
785
|
-
if (!segment || segment.startTime > presentationTime ||
|
|
786
|
-
segment.endTime < presentationTime) {
|
|
787
781
|
mediaState.segmentIterator = null;
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
if (!newTimeIsBuffered(type)) {
|
|
791
782
|
const bufferEnd =
|
|
792
783
|
this.playerInterface_.mediaSourceEngine.bufferEnd(type);
|
|
793
784
|
const somethingBuffered = bufferEnd != null;
|
|
@@ -1400,7 +1391,7 @@ shaka.media.StreamingEngine = class {
|
|
|
1400
1391
|
|
|
1401
1392
|
if (mediaState.segmentPrefetch && mediaState.segmentIterator &&
|
|
1402
1393
|
!this.audioPrefetchMap_.has(mediaState.stream)) {
|
|
1403
|
-
mediaState.segmentPrefetch.evict(
|
|
1394
|
+
mediaState.segmentPrefetch.evict(reference.startTime);
|
|
1404
1395
|
mediaState.segmentPrefetch.prefetchSegmentsByTime(reference.startTime);
|
|
1405
1396
|
}
|
|
1406
1397
|
|
|
@@ -1758,48 +1749,6 @@ shaka.media.StreamingEngine = class {
|
|
|
1758
1749
|
}
|
|
1759
1750
|
}
|
|
1760
1751
|
|
|
1761
|
-
/**
|
|
1762
|
-
* @param {!BufferSource} rawResult
|
|
1763
|
-
* @param {shaka.extern.aesKey} aesKey
|
|
1764
|
-
* @param {number} position
|
|
1765
|
-
* @return {!Promise.<!BufferSource>} finalResult
|
|
1766
|
-
* @private
|
|
1767
|
-
*/
|
|
1768
|
-
async aesDecrypt_(rawResult, aesKey, position) {
|
|
1769
|
-
const key = aesKey;
|
|
1770
|
-
if (!key.cryptoKey) {
|
|
1771
|
-
goog.asserts.assert(key.fetchKey, 'If AES cryptoKey was not ' +
|
|
1772
|
-
'preloaded, fetchKey function should be provided');
|
|
1773
|
-
await key.fetchKey();
|
|
1774
|
-
goog.asserts.assert(key.cryptoKey, 'AES cryptoKey should now be set');
|
|
1775
|
-
}
|
|
1776
|
-
let iv = key.iv;
|
|
1777
|
-
if (!iv) {
|
|
1778
|
-
iv = shaka.util.BufferUtils.toUint8(new ArrayBuffer(16));
|
|
1779
|
-
let sequence = key.firstMediaSequenceNumber + position;
|
|
1780
|
-
for (let i = iv.byteLength - 1; i >= 0; i--) {
|
|
1781
|
-
iv[i] = sequence & 0xff;
|
|
1782
|
-
sequence >>= 8;
|
|
1783
|
-
}
|
|
1784
|
-
}
|
|
1785
|
-
let algorithm;
|
|
1786
|
-
if (aesKey.blockCipherMode == 'CBC') {
|
|
1787
|
-
algorithm = {
|
|
1788
|
-
name: 'AES-CBC',
|
|
1789
|
-
iv,
|
|
1790
|
-
};
|
|
1791
|
-
} else {
|
|
1792
|
-
algorithm = {
|
|
1793
|
-
name: 'AES-CTR',
|
|
1794
|
-
counter: iv,
|
|
1795
|
-
// NIST SP800-38A standard suggests that the counter should occupy half
|
|
1796
|
-
// of the counter block
|
|
1797
|
-
length: 64,
|
|
1798
|
-
};
|
|
1799
|
-
}
|
|
1800
|
-
return window.crypto.subtle.decrypt(algorithm, key.cryptoKey, rawResult);
|
|
1801
|
-
}
|
|
1802
|
-
|
|
1803
1752
|
|
|
1804
1753
|
/**
|
|
1805
1754
|
* Clear per-stream error states and retry any failed streams.
|
|
@@ -2576,7 +2525,8 @@ shaka.media.StreamingEngine = class {
|
|
|
2576
2525
|
mediaState.operation = null;
|
|
2577
2526
|
let result = response.data;
|
|
2578
2527
|
if (reference.aesKey) {
|
|
2579
|
-
result = await
|
|
2528
|
+
result = await shaka.media.SegmentUtils.aesDecrypt(
|
|
2529
|
+
result, reference.aesKey, position);
|
|
2580
2530
|
}
|
|
2581
2531
|
return result;
|
|
2582
2532
|
}
|
package/lib/player.js
CHANGED
|
@@ -4862,13 +4862,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4862
4862
|
*/
|
|
4863
4863
|
selectVariantTrack(track, clearBuffer = false, safeMargin = 0) {
|
|
4864
4864
|
if (this.manifest_ && this.streamingEngine_) {
|
|
4865
|
-
if (this.config_.abr.enabled) {
|
|
4866
|
-
shaka.log.alwaysWarn('Changing tracks while abr manager is enabled ' +
|
|
4867
|
-
'will likely result in the selected track ' +
|
|
4868
|
-
'being overriden. Consider disabling abr before ' +
|
|
4869
|
-
'calling selectVariantTrack().');
|
|
4870
|
-
}
|
|
4871
|
-
|
|
4872
4865
|
const variant = this.manifest_.variants.find(
|
|
4873
4866
|
(variant) => variant.id == track.id);
|
|
4874
4867
|
if (!variant) {
|
|
@@ -4885,6 +4878,17 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4885
4878
|
return;
|
|
4886
4879
|
}
|
|
4887
4880
|
|
|
4881
|
+
const active = this.streamingEngine_.getCurrentVariant();
|
|
4882
|
+
if (this.config_.abr.enabled && (active.video != variant.video ||
|
|
4883
|
+
(active.audio && variant.audio &&
|
|
4884
|
+
active.audio.language == variant.audio.language &&
|
|
4885
|
+
active.audio.channelsCount == variant.audio.channelsCount))) {
|
|
4886
|
+
shaka.log.alwaysWarn('Changing tracks while abr manager is enabled ' +
|
|
4887
|
+
'will likely result in the selected track ' +
|
|
4888
|
+
'being overriden. Consider disabling abr before ' +
|
|
4889
|
+
'calling selectVariantTrack().');
|
|
4890
|
+
}
|
|
4891
|
+
|
|
4888
4892
|
this.switchVariant_(
|
|
4889
4893
|
variant, /* fromAdaptation= */ false, clearBuffer, safeMargin);
|
|
4890
4894
|
|
|
@@ -7809,7 +7813,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
7809
7813
|
* @export
|
|
7810
7814
|
*/
|
|
7811
7815
|
// eslint-disable-next-line no-useless-concat
|
|
7812
|
-
shaka.Player.version = 'v4.10.
|
|
7816
|
+
shaka.Player.version = 'v4.10.4' + '-uncompiled'; // x-release-please-version
|
|
7813
7817
|
|
|
7814
7818
|
// Initialize the deprecation system using the version string we just set
|
|
7815
7819
|
// on the player.
|
package/lib/text/cue.js
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
goog.provide('shaka.text.Cue');
|
|
8
|
-
goog.provide('shaka.text.CueRegion');
|
|
9
8
|
|
|
9
|
+
goog.require('shaka.text.CueRegion');
|
|
10
10
|
goog.require('shaka.util.ArrayUtils');
|
|
11
11
|
|
|
12
12
|
|
|
@@ -553,119 +553,3 @@ shaka.text.Cue.textDecoration = {
|
|
|
553
553
|
'LINE_THROUGH': 'lineThrough',
|
|
554
554
|
'OVERLINE': 'overline',
|
|
555
555
|
};
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
/**
|
|
559
|
-
* @export
|
|
560
|
-
*/
|
|
561
|
-
shaka.text.CueRegion = class {
|
|
562
|
-
/** */
|
|
563
|
-
constructor() {
|
|
564
|
-
const CueRegion = shaka.text.CueRegion;
|
|
565
|
-
|
|
566
|
-
/**
|
|
567
|
-
* Region identifier.
|
|
568
|
-
* @type {string}
|
|
569
|
-
* @export
|
|
570
|
-
*/
|
|
571
|
-
this.id = '';
|
|
572
|
-
|
|
573
|
-
/**
|
|
574
|
-
* The X offset to start the rendering area in viewportAnchorUnits of the
|
|
575
|
-
* video width.
|
|
576
|
-
* @type {number}
|
|
577
|
-
* @export
|
|
578
|
-
*/
|
|
579
|
-
this.viewportAnchorX = 0;
|
|
580
|
-
|
|
581
|
-
/**
|
|
582
|
-
* The X offset to start the rendering area in viewportAnchorUnits of the
|
|
583
|
-
* video height.
|
|
584
|
-
* @type {number}
|
|
585
|
-
* @export
|
|
586
|
-
*/
|
|
587
|
-
this.viewportAnchorY = 0;
|
|
588
|
-
|
|
589
|
-
/**
|
|
590
|
-
* The X offset to start the rendering area in percentage (0-100) of this
|
|
591
|
-
* region width.
|
|
592
|
-
* @type {number}
|
|
593
|
-
* @export
|
|
594
|
-
*/
|
|
595
|
-
this.regionAnchorX = 0;
|
|
596
|
-
|
|
597
|
-
/**
|
|
598
|
-
* The Y offset to start the rendering area in percentage (0-100) of the
|
|
599
|
-
* region height.
|
|
600
|
-
* @type {number}
|
|
601
|
-
* @export
|
|
602
|
-
*/
|
|
603
|
-
this.regionAnchorY = 0;
|
|
604
|
-
|
|
605
|
-
/**
|
|
606
|
-
* The width of the rendering area in widthUnits.
|
|
607
|
-
* @type {number}
|
|
608
|
-
* @export
|
|
609
|
-
*/
|
|
610
|
-
this.width = 100;
|
|
611
|
-
|
|
612
|
-
/**
|
|
613
|
-
* The width of the rendering area in heightUnits.
|
|
614
|
-
* @type {number}
|
|
615
|
-
* @export
|
|
616
|
-
*/
|
|
617
|
-
this.height = 100;
|
|
618
|
-
|
|
619
|
-
/**
|
|
620
|
-
* The units (percentage, pixels or lines) the region height is in.
|
|
621
|
-
* @type {shaka.text.CueRegion.units}
|
|
622
|
-
* @export
|
|
623
|
-
*/
|
|
624
|
-
this.heightUnits = CueRegion.units.PERCENTAGE;
|
|
625
|
-
|
|
626
|
-
/**
|
|
627
|
-
* The units (percentage or pixels) the region width is in.
|
|
628
|
-
* @type {shaka.text.CueRegion.units}
|
|
629
|
-
* @export
|
|
630
|
-
*/
|
|
631
|
-
this.widthUnits = CueRegion.units.PERCENTAGE;
|
|
632
|
-
|
|
633
|
-
/**
|
|
634
|
-
* The units (percentage or pixels) the region viewportAnchors are in.
|
|
635
|
-
* @type {shaka.text.CueRegion.units}
|
|
636
|
-
* @export
|
|
637
|
-
*/
|
|
638
|
-
this.viewportAnchorUnits = CueRegion.units.PERCENTAGE;
|
|
639
|
-
|
|
640
|
-
/**
|
|
641
|
-
* If scroll=UP, it means that cues in the region will be added to the
|
|
642
|
-
* bottom of the region and will push any already displayed cues in the
|
|
643
|
-
* region up. Otherwise (scroll=NONE) cues will stay fixed at the location
|
|
644
|
-
* they were first painted in.
|
|
645
|
-
* @type {shaka.text.CueRegion.scrollMode}
|
|
646
|
-
* @export
|
|
647
|
-
*/
|
|
648
|
-
this.scroll = CueRegion.scrollMode.NONE;
|
|
649
|
-
}
|
|
650
|
-
};
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
/**
|
|
654
|
-
* @enum {number}
|
|
655
|
-
* @export
|
|
656
|
-
*/
|
|
657
|
-
shaka.text.CueRegion.units = {
|
|
658
|
-
'PX': 0,
|
|
659
|
-
'PERCENTAGE': 1,
|
|
660
|
-
'LINES': 2,
|
|
661
|
-
};
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
/**
|
|
665
|
-
* @enum {string}
|
|
666
|
-
* @export
|
|
667
|
-
*/
|
|
668
|
-
shaka.text.CueRegion.scrollMode = {
|
|
669
|
-
'NONE': '',
|
|
670
|
-
'UP': 'up',
|
|
671
|
-
};
|