shaka-player 4.12.1 → 4.12.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/.eslintrc.js +1 -0
- package/AUTHORS +1 -0
- package/CONTRIBUTORS +1 -0
- package/dist/locales.js +35 -35
- package/dist/shaka-player.compiled.d.ts +7 -7
- package/dist/shaka-player.compiled.debug.d.ts +7 -7
- package/dist/shaka-player.compiled.debug.js +142 -140
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.js +1253 -1253
- package/dist/shaka-player.compiled.map +2 -2
- package/dist/shaka-player.ui.d.ts +7 -7
- package/dist/shaka-player.ui.debug.d.ts +7 -7
- package/dist/shaka-player.ui.debug.js +130 -128
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.js +1459 -1459
- package/dist/shaka-player.ui.map +2 -2
- package/externs/shaka/abortable.js +36 -36
- package/lib/ads/interstitial_ad_manager.js +2 -0
- package/lib/hls/hls_parser.js +1 -1
- package/lib/media/drm_engine.js +2 -0
- package/lib/media/media_source_engine.js +61 -3
- package/lib/media/preload_manager.js +6 -1
- package/lib/media/segment_reference.js +1 -1
- package/lib/media/streaming_engine.js +9 -11
- package/lib/player.js +1 -1
- package/lib/polyfill/media_capabilities.js +46 -8
- package/lib/text/vtt_text_parser.js +2 -8
- package/lib/util/abortable_operation.js +8 -6
- package/lib/util/platform.js +18 -7
- package/package.json +2 -2
- package/ui/chapter_selection.js +6 -2
|
@@ -18,39 +18,39 @@
|
|
|
18
18
|
* @template T
|
|
19
19
|
* @exportDoc
|
|
20
20
|
*/
|
|
21
|
-
shaka.extern.IAbortableOperation =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
21
|
+
shaka.extern.IAbortableOperation = class {
|
|
22
|
+
constructor() {
|
|
23
|
+
/**
|
|
24
|
+
* A Promise which represents the underlying operation. It is resolved when
|
|
25
|
+
* the operation is complete, and rejected if the operation fails or is
|
|
26
|
+
* aborted. Aborted operations should be rejected with a shaka.util.Error
|
|
27
|
+
* object using the error code OPERATION_ABORTED.
|
|
28
|
+
*
|
|
29
|
+
* @const {!Promise.<T>}
|
|
30
|
+
* @exportDoc
|
|
31
|
+
*/
|
|
32
|
+
this.promise;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Can be called by anyone holding this object to abort the underlying
|
|
37
|
+
* operation. This is not cancelation, and will not necessarily result in
|
|
38
|
+
* any work being undone. abort() should return a Promise which is resolved
|
|
39
|
+
* when the underlying operation has been aborted. The returned Promise
|
|
40
|
+
* should never be rejected.
|
|
41
|
+
*
|
|
42
|
+
* @return {!Promise}
|
|
43
|
+
* @exportDoc
|
|
44
|
+
*/
|
|
45
|
+
abort() {}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @param {function(boolean)} onFinal A callback to be invoked after the
|
|
50
|
+
* operation succeeds or fails. The boolean argument is true
|
|
51
|
+
* if the operation succeeded and false if it failed.
|
|
52
|
+
* @return {!shaka.extern.IAbortableOperation.<T>} Returns this.
|
|
53
|
+
* @exportDoc
|
|
54
|
+
*/
|
|
55
|
+
finally(onFinal) {}
|
|
56
|
+
};
|
|
@@ -1000,6 +1000,8 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
1000
1000
|
goog.asserts.assert(this.player_, 'Must have player');
|
|
1001
1001
|
goog.asserts.assert(this.basePlayer_, 'Must have base player');
|
|
1002
1002
|
this.player_.configure(this.basePlayer_.getNonDefaultConfiguration());
|
|
1003
|
+
this.player_.configure('ads.disableHLSInterstitial', true);
|
|
1004
|
+
this.player_.configure('ads.disableDASHInterstitial', true);
|
|
1003
1005
|
const netEngine = this.player_.getNetworkingEngine();
|
|
1004
1006
|
goog.asserts.assert(netEngine, 'Need networking engine');
|
|
1005
1007
|
netEngine.clearAllRequestFilters();
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -4127,7 +4127,7 @@ shaka.hls.HlsParser = class {
|
|
|
4127
4127
|
let aesKey = undefined;
|
|
4128
4128
|
|
|
4129
4129
|
let discontinuitySequence = shaka.hls.Utils.getFirstTagWithNameAsNumber(
|
|
4130
|
-
playlist.tags, 'EXT-X-DISCONTINUITY-SEQUENCE',
|
|
4130
|
+
playlist.tags, 'EXT-X-DISCONTINUITY-SEQUENCE', -1);
|
|
4131
4131
|
const mediaSequenceNumber = shaka.hls.Utils.getFirstTagWithNameAsNumber(
|
|
4132
4132
|
playlist.tags, 'EXT-X-MEDIA-SEQUENCE', 0);
|
|
4133
4133
|
const skipTag = shaka.hls.Utils.getFirstTagWithName(
|
package/lib/media/drm_engine.js
CHANGED
|
@@ -1717,6 +1717,7 @@ shaka.media.DrmEngine = class {
|
|
|
1717
1717
|
const testKeySystems = [
|
|
1718
1718
|
'org.w3.clearkey',
|
|
1719
1719
|
'com.widevine.alpha',
|
|
1720
|
+
'com.widevine.alpha.experiment', // Widevine L1 in Windows
|
|
1720
1721
|
'com.microsoft.playready',
|
|
1721
1722
|
'com.microsoft.playready.hardware',
|
|
1722
1723
|
'com.microsoft.playready.recommendation',
|
|
@@ -1741,6 +1742,7 @@ shaka.media.DrmEngine = class {
|
|
|
1741
1742
|
|
|
1742
1743
|
const testRobustness = {
|
|
1743
1744
|
'com.widevine.alpha': widevineRobustness,
|
|
1745
|
+
'com.widevine.alpha.experiment': widevineRobustness,
|
|
1744
1746
|
'com.microsoft.playready.recommendation': playreadyRobustness,
|
|
1745
1747
|
};
|
|
1746
1748
|
|
|
@@ -1139,7 +1139,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1139
1139
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
1140
1140
|
|
|
1141
1141
|
if (contentType == ContentType.TEXT) {
|
|
1142
|
-
if (this.
|
|
1142
|
+
if (this.manifestType_ == shaka.media.ManifestParser.HLS &&
|
|
1143
|
+
reference.discontinuitySequence >= 0) {
|
|
1143
1144
|
// This won't be known until the first video segment is appended.
|
|
1144
1145
|
const offset = await this.textSequenceModeOffset_;
|
|
1145
1146
|
this.textEngine_.setTimestampOffset(offset);
|
|
@@ -1233,7 +1234,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1233
1234
|
const isBestSourceBufferForTimestamps =
|
|
1234
1235
|
contentType == ContentType.VIDEO ||
|
|
1235
1236
|
!(ContentType.VIDEO in this.sourceBuffers_);
|
|
1236
|
-
if (
|
|
1237
|
+
if (isBestSourceBufferForTimestamps) {
|
|
1237
1238
|
this.textSequenceModeOffset_.resolve(timestampOffset);
|
|
1238
1239
|
}
|
|
1239
1240
|
}
|
|
@@ -1562,6 +1563,10 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1562
1563
|
this.textSequenceModeOffset_ = new shaka.util.PublicPromise();
|
|
1563
1564
|
}
|
|
1564
1565
|
|
|
1566
|
+
if (!this.sequenceMode_) {
|
|
1567
|
+
return;
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1565
1570
|
// Queue an abort() to help MSE splice together overlapping segments.
|
|
1566
1571
|
// We set appendWindowEnd when we change periods in DASH content, and the
|
|
1567
1572
|
// period transition may result in overlap.
|
|
@@ -2095,6 +2100,48 @@ shaka.media.MediaSourceEngine = class {
|
|
|
2095
2100
|
null);
|
|
2096
2101
|
}
|
|
2097
2102
|
|
|
2103
|
+
/**
|
|
2104
|
+
* Returns the source buffer parameters
|
|
2105
|
+
* @param {shaka.util.ManifestParserUtils.ContentType} contentType
|
|
2106
|
+
* @return {?shaka.media.MediaSourceEngine.SourceBufferParams}
|
|
2107
|
+
* @private
|
|
2108
|
+
*/
|
|
2109
|
+
getSourceBufferParams_(contentType) {
|
|
2110
|
+
if (!this.sourceBuffers_[contentType]) {
|
|
2111
|
+
return null;
|
|
2112
|
+
}
|
|
2113
|
+
return {
|
|
2114
|
+
timestampOffset: this.sourceBuffers_[contentType].timestampOffset,
|
|
2115
|
+
appendWindowStart: this.sourceBuffers_[contentType].appendWindowStart,
|
|
2116
|
+
appendWindowEnd: this.sourceBuffers_[contentType].appendWindowEnd,
|
|
2117
|
+
};
|
|
2118
|
+
}
|
|
2119
|
+
|
|
2120
|
+
/**
|
|
2121
|
+
* Restore source buffer parameters
|
|
2122
|
+
* @param {shaka.util.ManifestParserUtils.ContentType} contentType
|
|
2123
|
+
* @param {?shaka.media.MediaSourceEngine.SourceBufferParams} params
|
|
2124
|
+
* @private
|
|
2125
|
+
*/
|
|
2126
|
+
restoreSourceBufferParams_(contentType, params) {
|
|
2127
|
+
if (!params) {
|
|
2128
|
+
return;
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
if (!this.sourceBuffers_[contentType]) {
|
|
2132
|
+
shaka.log.warning('Attempted to restore a non-existent source buffer');
|
|
2133
|
+
return;
|
|
2134
|
+
}
|
|
2135
|
+
|
|
2136
|
+
this.sourceBuffers_[contentType].timestampOffset =
|
|
2137
|
+
params.timestampOffset;
|
|
2138
|
+
// `end` needs to be set before `start`
|
|
2139
|
+
this.sourceBuffers_[contentType].appendWindowEnd =
|
|
2140
|
+
params.appendWindowEnd;
|
|
2141
|
+
this.sourceBuffers_[contentType].appendWindowStart =
|
|
2142
|
+
params.appendWindowStart;
|
|
2143
|
+
}
|
|
2144
|
+
|
|
2098
2145
|
/**
|
|
2099
2146
|
* Resets the MediaSource and re-adds source buffers due to codec mismatch
|
|
2100
2147
|
*
|
|
@@ -2155,7 +2202,6 @@ shaka.media.MediaSourceEngine = class {
|
|
|
2155
2202
|
}
|
|
2156
2203
|
await Promise.all(cleanup);
|
|
2157
2204
|
this.transmuxers_ = {};
|
|
2158
|
-
this.sourceBuffers_ = {};
|
|
2159
2205
|
|
|
2160
2206
|
const previousDuration = this.mediaSource_.duration;
|
|
2161
2207
|
this.mediaSourceOpen_ = new shaka.util.PublicPromise();
|
|
@@ -2186,6 +2232,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
2186
2232
|
onSourceBufferAdded);
|
|
2187
2233
|
|
|
2188
2234
|
for (const contentType of streamsByType.keys()) {
|
|
2235
|
+
const previousParams = this.getSourceBufferParams_(contentType);
|
|
2189
2236
|
const stream = streamsByType.get(contentType);
|
|
2190
2237
|
// eslint-disable-next-line no-await-in-loop
|
|
2191
2238
|
await this.initSourceBuffer_(contentType, stream, stream.codecs);
|
|
@@ -2195,6 +2242,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
2195
2242
|
} else {
|
|
2196
2243
|
this.queues_[contentType] = [];
|
|
2197
2244
|
}
|
|
2245
|
+
|
|
2246
|
+
this.restoreSourceBufferParams_(contentType, previousParams);
|
|
2198
2247
|
}
|
|
2199
2248
|
const audio = streamsByType.get(ContentType.AUDIO);
|
|
2200
2249
|
if (audio && audio.isAudioMuxedInVideo) {
|
|
@@ -2492,3 +2541,12 @@ shaka.media.MediaSourceEngine.SourceBufferMode_ = {
|
|
|
2492
2541
|
* Called when an embedded 'emsg' box should trigger a manifest update.
|
|
2493
2542
|
*/
|
|
2494
2543
|
shaka.media.MediaSourceEngine.PlayerInterface;
|
|
2544
|
+
|
|
2545
|
+
/**
|
|
2546
|
+
* @typedef {{
|
|
2547
|
+
* timestampOffset: number,
|
|
2548
|
+
* appendWindowStart: number,
|
|
2549
|
+
* appendWindowEnd: number
|
|
2550
|
+
* }}
|
|
2551
|
+
*/
|
|
2552
|
+
shaka.media.MediaSourceEngine.SourceBufferParams;
|
|
@@ -403,7 +403,12 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
403
403
|
|
|
404
404
|
this.successPromise_.resolve();
|
|
405
405
|
} catch (error) {
|
|
406
|
-
|
|
406
|
+
// Ignore OPERATION_ABORTED and OBJECT_DESTROYED errors.
|
|
407
|
+
if (!(error instanceof shaka.util.Error) ||
|
|
408
|
+
(error.code != shaka.util.Error.Code.OPERATION_ABORTED &&
|
|
409
|
+
error.code != shaka.util.Error.Code.OBJECT_DESTROYED)) {
|
|
410
|
+
this.successPromise_.reject(error);
|
|
411
|
+
}
|
|
407
412
|
}
|
|
408
413
|
})();
|
|
409
414
|
}
|
|
@@ -295,7 +295,7 @@ shaka.media.SegmentReference = class {
|
|
|
295
295
|
this.thumbnailSprite = null;
|
|
296
296
|
|
|
297
297
|
/** @type {number} */
|
|
298
|
-
this.discontinuitySequence =
|
|
298
|
+
this.discontinuitySequence = -1;
|
|
299
299
|
|
|
300
300
|
/** @type {boolean} */
|
|
301
301
|
this.allPartialSegments = allPartialSegments;
|
|
@@ -2156,17 +2156,15 @@ shaka.media.StreamingEngine = class {
|
|
|
2156
2156
|
}
|
|
2157
2157
|
}
|
|
2158
2158
|
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
mediaState.type, reference.startTime));
|
|
2169
|
-
}
|
|
2159
|
+
const lastDiscontinuitySequence =
|
|
2160
|
+
mediaState.lastSegmentReference ?
|
|
2161
|
+
mediaState.lastSegmentReference.discontinuitySequence : null;
|
|
2162
|
+
// Across discontinuity bounds, we should resync timestamps. The next
|
|
2163
|
+
// segment appended should land at its theoretical timestamp from the
|
|
2164
|
+
// segment index.
|
|
2165
|
+
if (reference.discontinuitySequence != lastDiscontinuitySequence) {
|
|
2166
|
+
operations.push(this.playerInterface_.mediaSourceEngine.resync(
|
|
2167
|
+
mediaState.type, reference.startTime));
|
|
2170
2168
|
}
|
|
2171
2169
|
|
|
2172
2170
|
await Promise.all(operations);
|
package/lib/player.js
CHANGED
|
@@ -8269,7 +8269,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
8269
8269
|
* @export
|
|
8270
8270
|
*/
|
|
8271
8271
|
// eslint-disable-next-line no-useless-concat, max-len
|
|
8272
|
-
shaka.Player.version = 'v4.12.
|
|
8272
|
+
shaka.Player.version = 'v4.12.2' + '-uncompiled'; // x-release-please-version
|
|
8273
8273
|
|
|
8274
8274
|
// Initialize the deprecation system using the version string we just set
|
|
8275
8275
|
// on the player.
|
|
@@ -327,18 +327,56 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
327
327
|
|
|
328
328
|
let displayType = videoConfig.contentType;
|
|
329
329
|
if (videoConfig.width && videoConfig.height) {
|
|
330
|
-
|
|
331
|
-
|
|
330
|
+
// All Chromecast can support 720p videos
|
|
331
|
+
if (videoConfig.width > 1280 || videoConfig.height > 720) {
|
|
332
|
+
displayType +=
|
|
333
|
+
`; width=${videoConfig.width}; height=${videoConfig.height}`;
|
|
334
|
+
}
|
|
332
335
|
}
|
|
333
336
|
if (videoConfig.framerate) {
|
|
334
|
-
|
|
337
|
+
// All Chromecast can support a framerate of 24, 25 or 30.
|
|
338
|
+
const framerate = Math.round(videoConfig.framerate);
|
|
339
|
+
if (framerate < 24 || framerate > 30) {
|
|
340
|
+
displayType += `; framerate=${videoConfig.framerate}`;
|
|
341
|
+
}
|
|
335
342
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
343
|
+
|
|
344
|
+
// Don't trust Closure types here. Although transferFunction is string or
|
|
345
|
+
// undefined, we don't want to count on the input type. A switch statement
|
|
346
|
+
// will, however, differentiate between null and undefined. So we default
|
|
347
|
+
// to a blank string.
|
|
348
|
+
const transferFunction = videoConfig.transferFunction || '';
|
|
349
|
+
|
|
350
|
+
// Based on internal sources. Googlers, see go/cast-hdr-queries for source.
|
|
351
|
+
switch (transferFunction) {
|
|
352
|
+
// The empty case falls through to SDR.
|
|
353
|
+
case '':
|
|
354
|
+
// These are the only 3 values defined by MCap as of November 2024.
|
|
355
|
+
case 'srgb':
|
|
356
|
+
// https://en.wikipedia.org/wiki/Standard-dynamic-range_video
|
|
357
|
+
// https://en.wikipedia.org/wiki/SRGB
|
|
358
|
+
// https://en.wikipedia.org/wiki/Rec._709
|
|
359
|
+
// This is SDR, standardized in BT 709.
|
|
360
|
+
// The platform recognizes "eotf=bt709", but we can also omit it.
|
|
361
|
+
break;
|
|
362
|
+
|
|
363
|
+
case 'pq':
|
|
364
|
+
// https://en.wikipedia.org/wiki/Perceptual_quantizer
|
|
365
|
+
// This HDR transfer function is standardized as SMPTE ST 2084.
|
|
366
|
+
displayType += '; eotf=smpte2084';
|
|
367
|
+
break;
|
|
368
|
+
|
|
369
|
+
case 'hlg':
|
|
370
|
+
// https://en.wikipedia.org/wiki/Hybrid_log%E2%80%93gamma
|
|
371
|
+
// This HDR transfer function is standardized as ARIB STD-B67.
|
|
372
|
+
displayType += '; eotf=arib-std-b67';
|
|
373
|
+
break;
|
|
374
|
+
|
|
375
|
+
default:
|
|
376
|
+
// An unrecognized transfer function. Reject this query.
|
|
377
|
+
return false;
|
|
341
378
|
}
|
|
379
|
+
|
|
342
380
|
let result = false;
|
|
343
381
|
if (displayType in shaka.polyfill.MediaCapabilities
|
|
344
382
|
.memoizedCanDisplayTypeRequests_) {
|
|
@@ -86,13 +86,7 @@ shaka.text.VttTextParser = class {
|
|
|
86
86
|
// Only use 'X-TIMESTAMP-MAP' with HLS. This overrides offset above.
|
|
87
87
|
if (blocks[0].includes('X-TIMESTAMP-MAP') &&
|
|
88
88
|
this.manifestType_ == shaka.media.ManifestParser.HLS) {
|
|
89
|
-
|
|
90
|
-
// Compute a different, rollover-based offset for sequence mode.
|
|
91
|
-
offset = this.computeHlsSequenceModeOffset_(blocks[0], time);
|
|
92
|
-
} else {
|
|
93
|
-
// Calculate the offset from the segment startTime.
|
|
94
|
-
offset = time.segmentStart;
|
|
95
|
-
}
|
|
89
|
+
offset = this.computeHlsOffset_(blocks[0], time);
|
|
96
90
|
}
|
|
97
91
|
|
|
98
92
|
// Parse VTT regions.
|
|
@@ -129,7 +123,7 @@ shaka.text.VttTextParser = class {
|
|
|
129
123
|
* @return {number}
|
|
130
124
|
* @private
|
|
131
125
|
*/
|
|
132
|
-
|
|
126
|
+
computeHlsOffset_(headerBlock, time) {
|
|
133
127
|
// https://bit.ly/2K92l7y
|
|
134
128
|
// The 'X-TIMESTAMP-MAP' header is used in HLS to align text with
|
|
135
129
|
// the rest of the media.
|
|
@@ -39,8 +39,8 @@ shaka.util.AbortableOperation = class {
|
|
|
39
39
|
/** @private {function():!Promise} */
|
|
40
40
|
this.onAbort_ = onAbort;
|
|
41
41
|
|
|
42
|
-
/** @private {
|
|
43
|
-
this.
|
|
42
|
+
/** @private {?Promise} */
|
|
43
|
+
this.abortPromise_ = null;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/**
|
|
@@ -48,7 +48,7 @@ shaka.util.AbortableOperation = class {
|
|
|
48
48
|
* @export
|
|
49
49
|
*/
|
|
50
50
|
get aborted() {
|
|
51
|
-
return this.
|
|
51
|
+
return this.abortPromise_ !== null;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/**
|
|
@@ -118,8 +118,10 @@ shaka.util.AbortableOperation = class {
|
|
|
118
118
|
* @export
|
|
119
119
|
*/
|
|
120
120
|
abort() {
|
|
121
|
-
this.
|
|
122
|
-
|
|
121
|
+
if (!this.abortPromise_) {
|
|
122
|
+
this.abortPromise_ = this.onAbort_();
|
|
123
|
+
}
|
|
124
|
+
return this.abortPromise_;
|
|
123
125
|
}
|
|
124
126
|
|
|
125
127
|
/**
|
|
@@ -174,7 +176,7 @@ shaka.util.AbortableOperation = class {
|
|
|
174
176
|
|
|
175
177
|
const makeCallback = (isSuccess) => {
|
|
176
178
|
return (value) => {
|
|
177
|
-
if (this.
|
|
179
|
+
if (this.abortPromise_ && isSuccess) {
|
|
178
180
|
// If "this" is not abortable(), or if abort() is called after "this"
|
|
179
181
|
// is complete but before the next stage in the chain begins, we
|
|
180
182
|
// should stop right away.
|
package/lib/util/platform.js
CHANGED
|
@@ -205,6 +205,17 @@ shaka.util.Platform = class {
|
|
|
205
205
|
shaka.util.Platform.chromeVersion() === 68;
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Check if the current platform is a WebOS 6.
|
|
210
|
+
*
|
|
211
|
+
* @return {boolean}
|
|
212
|
+
*/
|
|
213
|
+
static isWebOS6() {
|
|
214
|
+
// See: https://webostv.developer.lge.com/develop/specifications/web-api-and-web-engine#useragent-string
|
|
215
|
+
return shaka.util.Platform.isWebOS() &&
|
|
216
|
+
shaka.util.Platform.chromeVersion() === 79;
|
|
217
|
+
}
|
|
218
|
+
|
|
208
219
|
/**
|
|
209
220
|
* Check if the current platform is a Google Chromecast.
|
|
210
221
|
*
|
|
@@ -642,19 +653,19 @@ shaka.util.Platform = class {
|
|
|
642
653
|
/**
|
|
643
654
|
* Returns if codec switching SMOOTH is known reliable device support.
|
|
644
655
|
*
|
|
645
|
-
* Some devices are known not to support
|
|
656
|
+
* Some devices are known not to support <code>SourceBuffer.changeType</code>
|
|
646
657
|
* well. These devices should use the reload strategy. If a device
|
|
647
|
-
* reports that it supports
|
|
648
|
-
* it should be
|
|
658
|
+
* reports that it supports <code<changeType</code> but supports it unreliably
|
|
659
|
+
* it should be disallowed in this method.
|
|
649
660
|
*
|
|
650
661
|
* @return {boolean}
|
|
651
662
|
*/
|
|
652
663
|
static supportsSmoothCodecSwitching() {
|
|
653
664
|
const Platform = shaka.util.Platform;
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
Platform.
|
|
665
|
+
// All Tizen versions (up to Tizen 8) do not support SMOOTH so far.
|
|
666
|
+
// webOS seems to support SMOOTH from webOS 22.
|
|
667
|
+
if (Platform.isTizen() || Platform.isPS4() || Platform.isPS5() ||
|
|
668
|
+
Platform.isWebOS6()) {
|
|
658
669
|
return false;
|
|
659
670
|
}
|
|
660
671
|
// Older chromecasts without GoogleTV seem to not support SMOOTH properly.
|
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.12.
|
|
4
|
+
"version": "4.12.2",
|
|
5
5
|
"homepage": "https://github.com/shaka-project/shaka-player",
|
|
6
6
|
"author": "Google",
|
|
7
7
|
"maintainers": [
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"core-js": "^3.21.1",
|
|
27
27
|
"dialog-polyfill": "^0.5.6",
|
|
28
28
|
"es6-promise-polyfill": "^1.2.0",
|
|
29
|
-
"eslint": "^8.
|
|
29
|
+
"eslint": "^8.57.1",
|
|
30
30
|
"eslint-config-google": "^0.14.0",
|
|
31
31
|
"eslint-plugin-shaka-rules": "file:./build/eslint-plugin-shaka-rules",
|
|
32
32
|
"esprima": "^4.0.1",
|
package/ui/chapter_selection.js
CHANGED
|
@@ -119,14 +119,18 @@ shaka.ui.ChapterSelection = class extends shaka.ui.SettingsMenu {
|
|
|
119
119
|
const currentLocales = this.localization.getCurrentLocales();
|
|
120
120
|
for (const locale of Array.from(currentLocales)) {
|
|
121
121
|
nextLanguage = locale;
|
|
122
|
-
|
|
122
|
+
// If player is a proxy, and the cast receiver doesn't support this
|
|
123
|
+
// method, you get back undefined.
|
|
124
|
+
nextChapters = this.player.getChapters(nextLanguage) || [];
|
|
123
125
|
if (nextChapters.length) {
|
|
124
126
|
break;
|
|
125
127
|
}
|
|
126
128
|
}
|
|
127
129
|
if (!nextChapters.length) {
|
|
128
130
|
nextLanguage = 'und';
|
|
129
|
-
|
|
131
|
+
// If player is a proxy, and the cast receiver doesn't support this
|
|
132
|
+
// method, you get back undefined.
|
|
133
|
+
nextChapters = this.player.getChapters(nextLanguage) || [];
|
|
130
134
|
}
|
|
131
135
|
|
|
132
136
|
const languageChanged = nextLanguage !== this.chaptersLanguage_;
|