shaka-player 3.2.6 → 3.2.9
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/workflows/build-and-test.yaml +0 -1
- package/.github/workflows/release-please.yaml +4 -3
- package/.github/workflows/selenium-lab-tests.yaml +0 -1
- package/AUTHORS +1 -1
- package/CHANGELOG.md +39 -0
- package/CONTRIBUTORS +2 -1
- package/README.md +4 -4
- package/build/README.md +2 -2
- package/build/generateTsDefs.py +0 -2
- package/build/test.py +8 -2
- package/demo/common/assets.js +1 -1
- package/demo/demo.less +0 -1
- package/demo/main.js +3 -3
- package/dist/controls.css +2 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +3 -3
- package/dist/demo.compiled.debug.map +2 -2
- package/dist/demo.compiled.js +3 -3
- package/dist/demo.compiled.map +2 -2
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +1 -1
- package/dist/locales.js +28 -28
- package/dist/receiver.compiled.debug.js +1 -1
- package/dist/receiver.compiled.debug.map +1 -1
- package/dist/receiver.compiled.js +1 -1
- package/dist/receiver.compiled.map +1 -1
- package/dist/shaka-player.compiled.d.ts +1 -2
- package/dist/shaka-player.compiled.debug.d.ts +1 -2
- package/dist/shaka-player.compiled.debug.externs.js +1 -0
- package/dist/shaka-player.compiled.debug.js +213 -207
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +1 -0
- package/dist/shaka-player.compiled.js +775 -769
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +1 -2
- package/dist/shaka-player.ui.debug.d.ts +1 -2
- package/dist/shaka-player.ui.debug.externs.js +1 -0
- package/dist/shaka-player.ui.debug.js +241 -236
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +1 -0
- package/dist/shaka-player.ui.js +898 -891
- package/dist/shaka-player.ui.map +4 -4
- package/karma.conf.js +4 -0
- package/lib/abr/simple_abr_manager.js +2 -1
- package/lib/dash/dash_parser.js +2 -3
- package/lib/hls/hls_parser.js +45 -18
- package/lib/media/drm_engine.js +3 -0
- package/lib/media/media_source_engine.js +7 -1
- package/lib/offline/indexeddb/storage_mechanism.js +4 -2
- package/lib/player.js +165 -107
- package/lib/util/config_utils.js +25 -0
- package/lib/util/error.js +7 -0
- package/lib/util/manifest_parser_utils.js +1 -1
- package/lib/util/mime_utils.js +62 -6
- package/lib/util/periods.js +5 -4
- package/lib/util/player_configuration.js +9 -14
- package/lib/util/stream_utils.js +5 -2
- package/package.json +6 -3
- package/test/cast/cast_utils_unit.js +1 -0
- package/test/dash/dash_parser_manifest_unit.js +0 -24
- package/test/hls/hls_live_unit.js +86 -7
- package/test/hls/manifest_text_parser_unit.js +19 -0
- package/test/media/media_source_engine_integration.js +1 -0
- package/test/media/media_source_engine_unit.js +4 -4
- package/test/media/streaming_engine_integration.js +2 -0
- package/test/offline/indexeddb_storage_unit.js +1 -1
- package/test/offline/storage_compatibility_unit.js +1 -1
- package/test/player_external.js +7 -1
- package/test/player_integration.js +6 -10
- package/test/player_src_equals_integration.js +81 -83
- package/test/player_unit.js +98 -1
- package/test/test/boot.js +9 -0
- package/test/test/externs/filters.js +4 -0
- package/test/test/util/simple_fakes.js +31 -2
- package/test/util/mime_utils_unit.js +54 -0
- package/test/util/periods_unit.js +79 -0
- package/ui/less/containers.less +1 -1
- package/ui/less/general.less +1 -1
- package/ui/less/range_elements.less +1 -0
- package/.github/pull_request_template.md +0 -38
- package/docs/tutorials/gsoc-ideas-list.md +0 -3
package/karma.conf.js
CHANGED
|
@@ -363,6 +363,8 @@ module.exports = (config) => {
|
|
|
363
363
|
// If testing custom assets, we don't serve other unit or integration tests.
|
|
364
364
|
// External asset tests are the basis for custom asset testing, so this file
|
|
365
365
|
// is automatically included.
|
|
366
|
+
clientArgs.testFiles.push('demo/common/asset.js');
|
|
367
|
+
clientArgs.testFiles.push('demo/common/assets.js');
|
|
366
368
|
clientArgs.testFiles.push('test/player_external.js');
|
|
367
369
|
} else {
|
|
368
370
|
// In a normal test run, we serve unit tests.
|
|
@@ -374,6 +376,8 @@ module.exports = (config) => {
|
|
|
374
376
|
}
|
|
375
377
|
if (settings.external) {
|
|
376
378
|
// If --external is present, we serve external asset tests.
|
|
379
|
+
clientArgs.testFiles.push('demo/common/asset.js');
|
|
380
|
+
clientArgs.testFiles.push('demo/common/assets.js');
|
|
377
381
|
clientArgs.testFiles.push('test/**/*_external.js');
|
|
378
382
|
}
|
|
379
383
|
}
|
|
@@ -216,8 +216,9 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
216
216
|
* @export
|
|
217
217
|
*/
|
|
218
218
|
getBandwidthEstimate() {
|
|
219
|
+
const defaultBandwidthEstimate = this.getDefaultBandwidth_();
|
|
219
220
|
return this.bandwidthEstimator_.getBandwidthEstimate(
|
|
220
|
-
|
|
221
|
+
defaultBandwidthEstimate);
|
|
221
222
|
}
|
|
222
223
|
|
|
223
224
|
|
package/lib/dash/dash_parser.js
CHANGED
|
@@ -755,8 +755,8 @@ shaka.dash.DashParser = class {
|
|
|
755
755
|
// currently support that. Just choose one.
|
|
756
756
|
// TODO: https://github.com/shaka-project/shaka-player/issues/1528
|
|
757
757
|
stream.trickModeVideo = trickModeSet.streams.find((trickStream) =>
|
|
758
|
-
shaka.util.MimeUtils.
|
|
759
|
-
shaka.util.MimeUtils.
|
|
758
|
+
shaka.util.MimeUtils.getNormalizedCodec(stream.codecs) ==
|
|
759
|
+
shaka.util.MimeUtils.getNormalizedCodec(trickStream.codecs));
|
|
760
760
|
}
|
|
761
761
|
}
|
|
762
762
|
}
|
|
@@ -1218,7 +1218,6 @@ shaka.dash.DashParser = class {
|
|
|
1218
1218
|
});
|
|
1219
1219
|
let spatialAudio = false;
|
|
1220
1220
|
if (hasJoc) {
|
|
1221
|
-
context.representation.mimeType = 'audio/eac3-joc';
|
|
1222
1221
|
spatialAudio = true;
|
|
1223
1222
|
}
|
|
1224
1223
|
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -1736,8 +1736,8 @@ shaka.hls.HlsParser = class {
|
|
|
1736
1736
|
* @param {number} timestampOffset
|
|
1737
1737
|
* @param {!Map.<string, string>} variables
|
|
1738
1738
|
* @param {string} absoluteMediaPlaylistUri
|
|
1739
|
-
* @return {!shaka.media.SegmentReference}
|
|
1740
1739
|
* @param {string} type
|
|
1740
|
+
* @return {shaka.media.SegmentReference}
|
|
1741
1741
|
* @private
|
|
1742
1742
|
*/
|
|
1743
1743
|
createSegmentReference_(
|
|
@@ -1753,17 +1753,42 @@ shaka.hls.HlsParser = class {
|
|
|
1753
1753
|
let startByte = 0;
|
|
1754
1754
|
let endByte = null;
|
|
1755
1755
|
|
|
1756
|
+
if (!extinfTag) {
|
|
1757
|
+
if (hlsSegment.partialSegments.length == 0) {
|
|
1758
|
+
// EXTINF tag must be available if the segment has no partial segments.
|
|
1759
|
+
throw new shaka.util.Error(
|
|
1760
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
1761
|
+
shaka.util.Error.Category.MANIFEST,
|
|
1762
|
+
shaka.util.Error.Code.HLS_REQUIRED_TAG_MISSING, 'EXTINF');
|
|
1763
|
+
} else if (!this.lowLatencyMode_) {
|
|
1764
|
+
// Without EXTINF and without low-latency mode, partial segments get
|
|
1765
|
+
// ignored.
|
|
1766
|
+
return null;
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1756
1770
|
// Create SegmentReferences for the partial segments.
|
|
1757
1771
|
const partialSegmentRefs = [];
|
|
1758
|
-
if (this.lowLatencyMode_
|
|
1772
|
+
if (this.lowLatencyMode_) {
|
|
1759
1773
|
for (let i = 0; i < hlsSegment.partialSegments.length; i++) {
|
|
1760
1774
|
const item = hlsSegment.partialSegments[i];
|
|
1761
1775
|
const pPreviousReference = i == 0 ?
|
|
1762
1776
|
previousReference : partialSegmentRefs[partialSegmentRefs.length - 1];
|
|
1763
1777
|
const pStartTime = (i == 0) ? startTime : pPreviousReference.endTime;
|
|
1764
|
-
|
|
1765
|
-
//
|
|
1766
|
-
//
|
|
1778
|
+
|
|
1779
|
+
// If DURATION is missing from this partial segment, use the target
|
|
1780
|
+
// partial duration from the top of the playlist, which is a required
|
|
1781
|
+
// attribute for content with partial segments.
|
|
1782
|
+
const pDuration = Number(item.getAttributeValue('DURATION')) ||
|
|
1783
|
+
this.partialTargetDuration_;
|
|
1784
|
+
|
|
1785
|
+
// If for some reason we have neither an explicit duration, nor a target
|
|
1786
|
+
// partial duration, we should SKIP this partial segment to avoid
|
|
1787
|
+
// duplicating content in the presentation timeline.
|
|
1788
|
+
if (!pDuration) {
|
|
1789
|
+
continue;
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1767
1792
|
const pEndTime = pStartTime + pDuration;
|
|
1768
1793
|
|
|
1769
1794
|
let pStartByte = 0;
|
|
@@ -1796,14 +1821,6 @@ shaka.hls.HlsParser = class {
|
|
|
1796
1821
|
/* appendWindowEnd= */ Infinity);
|
|
1797
1822
|
partialSegmentRefs.push(partial);
|
|
1798
1823
|
} // for-loop of hlsSegment.partialSegments
|
|
1799
|
-
} else {
|
|
1800
|
-
// EXTINF tag must be available if the segment has no partial segments.
|
|
1801
|
-
if (!extinfTag) {
|
|
1802
|
-
throw new shaka.util.Error(
|
|
1803
|
-
shaka.util.Error.Severity.CRITICAL,
|
|
1804
|
-
shaka.util.Error.Category.MANIFEST,
|
|
1805
|
-
shaka.util.Error.Code.HLS_REQUIRED_TAG_MISSING, 'EXTINF');
|
|
1806
|
-
}
|
|
1807
1824
|
}
|
|
1808
1825
|
|
|
1809
1826
|
// If the segment has EXTINF tag, set the segment's end time, start byte
|
|
@@ -1822,6 +1839,7 @@ shaka.hls.HlsParser = class {
|
|
|
1822
1839
|
} else {
|
|
1823
1840
|
endTime = partialSegmentRefs[partialSegmentRefs.length - 1].endTime;
|
|
1824
1841
|
}
|
|
1842
|
+
|
|
1825
1843
|
// If the segment has EXT-X-BYTERANGE tag, set the start byte and end byte
|
|
1826
1844
|
// base on the byterange information. If segment has no EXT-X-BYTERANGE tag
|
|
1827
1845
|
// and has partial segments, set the start byte and end byte base on the
|
|
@@ -2047,7 +2065,9 @@ shaka.hls.HlsParser = class {
|
|
|
2047
2065
|
playlist.absoluteUri,
|
|
2048
2066
|
type);
|
|
2049
2067
|
|
|
2050
|
-
|
|
2068
|
+
if (reference) {
|
|
2069
|
+
references.push(reference);
|
|
2070
|
+
}
|
|
2051
2071
|
} else if (!this.lowLatencyMode_) {
|
|
2052
2072
|
// If a segment has no extinfTag, it must contain partial segments.
|
|
2053
2073
|
shaka.log.alwaysWarn('Low-latency HLS live stream detected, but ' +
|
|
@@ -2191,6 +2211,9 @@ shaka.hls.HlsParser = class {
|
|
|
2191
2211
|
variables,
|
|
2192
2212
|
/* absoluteMediaPlaylistUri= */ '',
|
|
2193
2213
|
type);
|
|
2214
|
+
goog.asserts.assert(
|
|
2215
|
+
segmentRef != null, 'Segment reference should not be null!');
|
|
2216
|
+
|
|
2194
2217
|
// If we are updating the manifest, we can usually skip fetching the segment
|
|
2195
2218
|
// by examining the references we already have. This won't be possible if
|
|
2196
2219
|
// there was some kind of lag or delay updating the manifest on the server,
|
|
@@ -2539,12 +2562,16 @@ shaka.hls.HlsParser = class {
|
|
|
2539
2562
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
2540
2563
|
const requestType = shaka.net.NetworkingEngine.RequestType.SEGMENT;
|
|
2541
2564
|
|
|
2565
|
+
// If you wait long enough, requesting the first segment can fail
|
|
2566
|
+
// because it has fallen off the left edge of DVR, so to be safer,
|
|
2567
|
+
// let's request the middle segment.
|
|
2542
2568
|
goog.asserts.assert(playlist.segments.length,
|
|
2543
2569
|
'Playlist should have segments!');
|
|
2544
|
-
const
|
|
2545
|
-
|
|
2570
|
+
const middleSegmentIdx = Math.trunc((playlist.segments.length - 1) / 2);
|
|
2571
|
+
const middleSegmentUri = this.variableSubstitution_(
|
|
2572
|
+
playlist.segments[middleSegmentIdx].absoluteUri, variables);
|
|
2546
2573
|
|
|
2547
|
-
const parsedUri = new goog.Uri(
|
|
2574
|
+
const parsedUri = new goog.Uri(middleSegmentUri);
|
|
2548
2575
|
const extension = parsedUri.getPath().split('.').pop();
|
|
2549
2576
|
const map = HlsParser.EXTENSION_MAP_BY_CONTENT_TYPE_[contentType];
|
|
2550
2577
|
|
|
@@ -2575,7 +2602,7 @@ shaka.hls.HlsParser = class {
|
|
|
2575
2602
|
// If unable to guess mime type, request a segment and try getting it
|
|
2576
2603
|
// from the response.
|
|
2577
2604
|
const headRequest = shaka.net.NetworkingEngine.makeRequest(
|
|
2578
|
-
[
|
|
2605
|
+
[middleSegmentUri], this.config_.retryParameters);
|
|
2579
2606
|
headRequest.method = 'HEAD';
|
|
2580
2607
|
|
|
2581
2608
|
const response = await this.makeNetworkRequest_(
|
package/lib/media/drm_engine.js
CHANGED
|
@@ -1372,6 +1372,9 @@ shaka.media.DrmEngine = class {
|
|
|
1372
1372
|
}
|
|
1373
1373
|
return;
|
|
1374
1374
|
}
|
|
1375
|
+
if (this.destroyer_.destroyed()) {
|
|
1376
|
+
return;
|
|
1377
|
+
}
|
|
1375
1378
|
|
|
1376
1379
|
const updateEvent = new shaka.util.FakeEvent('drmsessionupdate');
|
|
1377
1380
|
this.playerInterface_.onEvent(updateEvent);
|
|
@@ -63,6 +63,11 @@ shaka.media.MediaSourceEngine = class {
|
|
|
63
63
|
string>} */
|
|
64
64
|
this.sourceBufferTypes_ = {};
|
|
65
65
|
|
|
66
|
+
|
|
67
|
+
/** @private {!Object.<shaka.util.ManifestParserUtils.ContentType,
|
|
68
|
+
boolean>} */
|
|
69
|
+
this.expectedEncryption_ = {};
|
|
70
|
+
|
|
66
71
|
/** @private {shaka.text.TextEngine} */
|
|
67
72
|
this.textEngine_ = null;
|
|
68
73
|
|
|
@@ -345,6 +350,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
345
350
|
this.sourceBuffers_[contentType] = sourceBuffer;
|
|
346
351
|
this.sourceBufferTypes_[contentType] = mimeType;
|
|
347
352
|
this.queues_[contentType] = [];
|
|
353
|
+
this.expectedEncryption_[contentType] = !!stream.drmInfos.length;
|
|
348
354
|
}
|
|
349
355
|
}
|
|
350
356
|
}
|
|
@@ -1091,7 +1097,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1091
1097
|
*/
|
|
1092
1098
|
workAroundBrokenPlatforms_(segment, startTime, contentType) {
|
|
1093
1099
|
const isInitSegment = startTime == null;
|
|
1094
|
-
const encryptionExpected = this.
|
|
1100
|
+
const encryptionExpected = this.expectedEncryption_[contentType];
|
|
1095
1101
|
|
|
1096
1102
|
// If:
|
|
1097
1103
|
// 1. this is an init segment,
|
|
@@ -368,8 +368,10 @@ shaka.offline.indexeddb.StorageMechanism.SESSION_ID_STORE = 'session-ids';
|
|
|
368
368
|
shaka.offline.StorageMuxer.register(
|
|
369
369
|
'idb',
|
|
370
370
|
() => {
|
|
371
|
-
// Offline storage is not supported on the Chromecast
|
|
372
|
-
|
|
371
|
+
// Offline storage is not supported on the Chromecast or Xbox One
|
|
372
|
+
// platforms.
|
|
373
|
+
if (shaka.util.Platform.isChromecast() ||
|
|
374
|
+
shaka.util.Platform.isXboxOne()) {
|
|
373
375
|
return null;
|
|
374
376
|
}
|
|
375
377
|
// Offline storage requires the IndexedDB API.
|