shaka-player 4.12.4 → 4.12.6
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 +2 -2
- package/dist/locales.js +35 -35
- package/dist/shaka-player.compiled.d.ts +11 -3
- package/dist/shaka-player.compiled.debug.d.ts +11 -3
- package/dist/shaka-player.compiled.debug.externs.js +8 -5
- package/dist/shaka-player.compiled.debug.js +340 -331
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.externs.js +8 -5
- package/dist/shaka-player.compiled.js +1383 -1378
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +11 -3
- package/dist/shaka-player.ui.debug.d.ts +11 -3
- package/dist/shaka-player.ui.debug.externs.js +8 -5
- package/dist/shaka-player.ui.debug.js +357 -348
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.externs.js +8 -5
- package/dist/shaka-player.ui.js +1605 -1599
- package/dist/shaka-player.ui.map +3 -3
- package/externs/shaka/codecs.js +21 -0
- package/externs/shaka/offline.js +4 -0
- package/lib/cast/cast_utils.js +1 -0
- package/lib/dash/dash_parser.js +3 -0
- package/lib/hls/hls_parser.js +26 -5
- package/lib/media/drm_engine.js +70 -29
- package/lib/media/manifest_filterer.js +2 -1
- package/lib/media/media_source_engine.js +138 -129
- package/lib/media/segment_utils.js +50 -44
- package/lib/media/streaming_engine.js +9 -1
- package/lib/offline/download_info.js +5 -0
- package/lib/offline/download_manager.js +54 -0
- package/lib/offline/manifest_converter.js +1 -0
- package/lib/offline/storage.js +12 -3
- package/lib/player.js +52 -29
- package/lib/polyfill/media_capabilities.js +1 -1
- package/lib/text/simple_text_displayer.js +9 -1
- package/lib/text/ui_text_displayer.js +2 -14
- package/lib/transmuxer/aac_transmuxer.js +11 -3
- package/lib/transmuxer/ac3_transmuxer.js +11 -3
- package/lib/transmuxer/ec3_transmuxer.js +11 -3
- package/lib/transmuxer/h264.js +143 -70
- package/lib/transmuxer/mp3_transmuxer.js +11 -3
- package/lib/transmuxer/ts_transmuxer.js +68 -28
- package/lib/util/drm_utils.js +20 -0
- package/lib/util/mime_utils.js +3 -0
- package/lib/util/object_utils.js +83 -0
- package/lib/util/platform.js +48 -40
- package/lib/util/stream_utils.js +37 -113
- package/lib/util/ts_parser.js +111 -85
- package/package.json +1 -1
- package/ui/ad_counter.js +5 -0
- package/ui/controls.js +4 -2
- package/ui/fast_forward_button.js +7 -0
- package/ui/play_button.js +1 -1
- package/ui/playback_rate_selection.js +1 -1
- package/ui/rewind_button.js +7 -0
package/externs/shaka/codecs.js
CHANGED
|
@@ -27,6 +27,27 @@
|
|
|
27
27
|
shaka.extern.MPEG_PES;
|
|
28
28
|
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* @typedef {{
|
|
32
|
+
* data: !Uint8Array,
|
|
33
|
+
* frame: boolean,
|
|
34
|
+
* isKeyframe: boolean,
|
|
35
|
+
* pts: ?number,
|
|
36
|
+
* dts: ?number,
|
|
37
|
+
* nalus: !Array.<!shaka.extern.VideoNalu>
|
|
38
|
+
* }}
|
|
39
|
+
*
|
|
40
|
+
* @summary VideoSample.
|
|
41
|
+
* @property {!Uint8Array} data
|
|
42
|
+
* @property {boolean} frame
|
|
43
|
+
* @property {boolean} isKeyframe
|
|
44
|
+
* @property {?number} pts
|
|
45
|
+
* @property {?number} dts
|
|
46
|
+
* @property {!Array.<!shaka.extern.VideoNalu>} nalus
|
|
47
|
+
*/
|
|
48
|
+
shaka.extern.VideoSample;
|
|
49
|
+
|
|
50
|
+
|
|
30
51
|
/**
|
|
31
52
|
* @typedef {{
|
|
32
53
|
* data: !Uint8Array,
|
package/externs/shaka/offline.js
CHANGED
|
@@ -141,6 +141,7 @@ shaka.extern.ManifestDB;
|
|
|
141
141
|
* spatialAudio: boolean,
|
|
142
142
|
* closedCaptions: Map.<string, string>,
|
|
143
143
|
* tilesLayout: (string|undefined),
|
|
144
|
+
* mssPrivateData: (shaka.extern.MssPrivateData|undefined),
|
|
144
145
|
* external: boolean,
|
|
145
146
|
* fastSwitching: boolean,
|
|
146
147
|
* isAudioMuxedInVideo: boolean
|
|
@@ -214,6 +215,9 @@ shaka.extern.ManifestDB;
|
|
|
214
215
|
* The value is a grid-item-dimension consisting of two positive decimal
|
|
215
216
|
* integers in the format: column-x-row ('4x3'). It describes the arrangement
|
|
216
217
|
* of Images in a Grid. The minimum valid LAYOUT is '1x1'.
|
|
218
|
+
* @property {(shaka.extern.MssPrivateData|undefined)} mssPrivateData
|
|
219
|
+
* <i>Microsoft Smooth Streaming only.</i> <br>
|
|
220
|
+
* Private MSS data that is necessary to be able to do transmuxing.
|
|
217
221
|
* @property {boolean} external
|
|
218
222
|
* Indicate if the stream was added externally.
|
|
219
223
|
* Eg: external text tracks.
|
package/lib/cast/cast_utils.js
CHANGED
package/lib/dash/dash_parser.js
CHANGED
|
@@ -1505,6 +1505,9 @@ shaka.dash.DashParser = class {
|
|
|
1505
1505
|
let shouldDeleteIndex = true;
|
|
1506
1506
|
for (const contextId of this.indexStreamMap_[pId]) {
|
|
1507
1507
|
const stream = this.streamMap_[contextId];
|
|
1508
|
+
if (!stream) {
|
|
1509
|
+
continue;
|
|
1510
|
+
}
|
|
1508
1511
|
if (stream.segmentIndex && !stream.segmentIndex.isEmpty()) {
|
|
1509
1512
|
shouldDeleteIndex = false;
|
|
1510
1513
|
continue;
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -1136,8 +1136,8 @@ shaka.hls.HlsParser = class {
|
|
|
1136
1136
|
|
|
1137
1137
|
if (shaka.util.TsParser.probe(
|
|
1138
1138
|
shaka.util.BufferUtils.toUint8(data))) {
|
|
1139
|
-
const basicInfo =
|
|
1140
|
-
|
|
1139
|
+
const basicInfo = shaka.media.SegmentUtils.getBasicInfoFromTs(
|
|
1140
|
+
data, this.config_.disableAudio, this.config_.disableVideo);
|
|
1141
1141
|
if (basicInfo) {
|
|
1142
1142
|
return basicInfo;
|
|
1143
1143
|
}
|
|
@@ -2763,12 +2763,23 @@ shaka.hls.HlsParser = class {
|
|
|
2763
2763
|
}
|
|
2764
2764
|
}
|
|
2765
2765
|
this.notifySegmentsForStreams_(streamInfos.map((s) => s.stream));
|
|
2766
|
-
|
|
2766
|
+
|
|
2767
|
+
const activeStreamInfos = Array.from(this.uriToStreamInfosMap_.values())
|
|
2768
|
+
.filter((s) => s.stream.segmentIndex);
|
|
2769
|
+
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
2770
|
+
const hasAudio =
|
|
2771
|
+
activeStreamInfos.some((s) => s.stream.type == ContentType.AUDIO);
|
|
2772
|
+
const hasVideo =
|
|
2773
|
+
activeStreamInfos.some((s) => s.stream.type == ContentType.VIDEO);
|
|
2774
|
+
|
|
2775
|
+
const liveWithNoProgramDateTime =
|
|
2767
2776
|
this.isLive_() && !this.usesProgramDateTime_;
|
|
2777
|
+
const vodWithOnlyAudioOrVideo = !this.isLive_() &&
|
|
2778
|
+
this.usesProgramDateTime_ && !(hasAudio && hasVideo);
|
|
2768
2779
|
if (this.config_.hls.ignoreManifestProgramDateTime ||
|
|
2769
|
-
|
|
2780
|
+
liveWithNoProgramDateTime || vodWithOnlyAudioOrVideo) {
|
|
2770
2781
|
this.syncStreamsWithSequenceNumber_(
|
|
2771
|
-
streamInfos,
|
|
2782
|
+
streamInfos, liveWithNoProgramDateTime);
|
|
2772
2783
|
} else {
|
|
2773
2784
|
this.syncStreamsWithProgramDateTime_(streamInfos);
|
|
2774
2785
|
if (this.config_.hls.ignoreManifestProgramDateTimeForTypes.length > 0) {
|
|
@@ -2906,6 +2917,16 @@ shaka.hls.HlsParser = class {
|
|
|
2906
2917
|
|
|
2907
2918
|
if (!mimeType) {
|
|
2908
2919
|
mimeType = await this.guessMimeType_(type, codecs, segments);
|
|
2920
|
+
|
|
2921
|
+
// Some manifests don't say what text codec they use, this is a problem
|
|
2922
|
+
// if the cmft extension is used because we identify the mimeType as
|
|
2923
|
+
// application/mp4. In this case if we don't detect initialization
|
|
2924
|
+
// segments, we assume that the mimeType is text/vtt.
|
|
2925
|
+
if (type == shaka.util.ManifestParserUtils.ContentType.TEXT &&
|
|
2926
|
+
!codecs && mimeType == 'application/mp4' &&
|
|
2927
|
+
segments[0] && !segments[0].initSegmentReference) {
|
|
2928
|
+
mimeType = 'text/vtt';
|
|
2929
|
+
}
|
|
2909
2930
|
}
|
|
2910
2931
|
|
|
2911
2932
|
const {drmInfos, keyIds, encrypted, aesEncrypted} =
|
package/lib/media/drm_engine.js
CHANGED
|
@@ -928,14 +928,16 @@ shaka.media.DrmEngine = class {
|
|
|
928
928
|
'Got MediaKeySystemAccess with configuration',
|
|
929
929
|
realConfig);
|
|
930
930
|
|
|
931
|
+
const keySystem =
|
|
932
|
+
this.config_.keySystemsMapping[mediaKeySystemAccess.keySystem] ||
|
|
933
|
+
mediaKeySystemAccess.keySystem;
|
|
934
|
+
|
|
931
935
|
if (variants.length) {
|
|
932
936
|
this.currentDrmInfo_ = this.createDrmInfoByInfos_(
|
|
933
|
-
|
|
934
|
-
drmInfosByKeySystem.get(mediaKeySystemAccess.keySystem));
|
|
937
|
+
keySystem, drmInfosByKeySystem.get(keySystem));
|
|
935
938
|
} else {
|
|
936
939
|
this.currentDrmInfo_ = shaka.media.DrmEngine.createDrmInfoByConfigs_(
|
|
937
|
-
|
|
938
|
-
configsByKeySystem.get(mediaKeySystemAccess.keySystem));
|
|
940
|
+
keySystem, configsByKeySystem.get(keySystem));
|
|
939
941
|
}
|
|
940
942
|
if (!this.currentDrmInfo_.licenseServerUri) {
|
|
941
943
|
throw new shaka.util.Error(
|
|
@@ -1050,8 +1052,12 @@ shaka.media.DrmEngine = class {
|
|
|
1050
1052
|
if (!decodingInfo.supported || !decodingInfo.keySystemAccess) {
|
|
1051
1053
|
continue;
|
|
1052
1054
|
}
|
|
1053
|
-
const
|
|
1054
|
-
|
|
1055
|
+
const originalKeySystem = decodingInfo.keySystemAccess.keySystem;
|
|
1056
|
+
let drmInfos = drmInfosByKeySystem.get(originalKeySystem);
|
|
1057
|
+
if (!drmInfos && this.config_.keySystemsMapping[originalKeySystem]) {
|
|
1058
|
+
drmInfos = drmInfosByKeySystem.get(
|
|
1059
|
+
this.config_.keySystemsMapping[originalKeySystem]);
|
|
1060
|
+
}
|
|
1055
1061
|
for (const info of drmInfos) {
|
|
1056
1062
|
if (!!info.licenseServerUri == shouldHaveLicenseServer) {
|
|
1057
1063
|
return decodingInfo.keySystemAccess;
|
|
@@ -1450,6 +1456,11 @@ shaka.media.DrmEngine = class {
|
|
|
1450
1456
|
}
|
|
1451
1457
|
// NOTE: allowCrossSiteCredentials can be set in a request filter.
|
|
1452
1458
|
|
|
1459
|
+
if (shaka.util.DrmUtils.isClearKeySystem(
|
|
1460
|
+
this.currentDrmInfo_.keySystem)) {
|
|
1461
|
+
this.fixClearKeyRequest_(request, this.currentDrmInfo_);
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1453
1464
|
if (shaka.util.DrmUtils.isPlayReadyKeySystem(
|
|
1454
1465
|
this.currentDrmInfo_.keySystem)) {
|
|
1455
1466
|
this.unpackPlayReadyRequest_(request);
|
|
@@ -1603,6 +1614,31 @@ shaka.media.DrmEngine = class {
|
|
|
1603
1614
|
/** @type{string} */(shaka.util.TXml.getTextContents(challenge)));
|
|
1604
1615
|
}
|
|
1605
1616
|
|
|
1617
|
+
/**
|
|
1618
|
+
* Some old ClearKey CDMs don't include the type in the body request.
|
|
1619
|
+
*
|
|
1620
|
+
* @param {shaka.extern.Request} request
|
|
1621
|
+
* @param {shaka.extern.DrmInfo} drmInfo
|
|
1622
|
+
* @private
|
|
1623
|
+
*/
|
|
1624
|
+
fixClearKeyRequest_(request, drmInfo) {
|
|
1625
|
+
try {
|
|
1626
|
+
const body = shaka.util.StringUtils.fromBytesAutoDetect(request.body);
|
|
1627
|
+
if (body) {
|
|
1628
|
+
const licenseBody =
|
|
1629
|
+
/** @type {shaka.media.DrmEngine.ClearKeyLicenceRequestFormat} */ (
|
|
1630
|
+
JSON.parse(body));
|
|
1631
|
+
if (!licenseBody.type) {
|
|
1632
|
+
licenseBody.type = drmInfo.sessionType;
|
|
1633
|
+
request.body =
|
|
1634
|
+
shaka.util.StringUtils.toUTF8(JSON.stringify(licenseBody));
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
} catch (e) {
|
|
1638
|
+
shaka.log.info('Error unpacking ClearKey license', e);
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1606
1642
|
/**
|
|
1607
1643
|
* @param {!Event} event
|
|
1608
1644
|
* @private
|
|
@@ -2001,18 +2037,10 @@ shaka.media.DrmEngine = class {
|
|
|
2001
2037
|
* @private
|
|
2002
2038
|
*/
|
|
2003
2039
|
async closeSession_(session) {
|
|
2004
|
-
const DrmEngine = shaka.media.DrmEngine;
|
|
2005
|
-
|
|
2006
|
-
const timeout = new Promise((resolve, reject) => {
|
|
2007
|
-
const timer = new shaka.util.Timer(reject);
|
|
2008
|
-
timer.tickAfter(DrmEngine.CLOSE_TIMEOUT_);
|
|
2009
|
-
});
|
|
2010
|
-
|
|
2011
2040
|
try {
|
|
2012
|
-
await
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
]);
|
|
2041
|
+
await shaka.util.Functional.promiseWithTimeout(
|
|
2042
|
+
shaka.media.DrmEngine.CLOSE_TIMEOUT_,
|
|
2043
|
+
Promise.all([session.close(), session.closed]));
|
|
2016
2044
|
} catch (e) {
|
|
2017
2045
|
shaka.log.warning('Timeout waiting for session close');
|
|
2018
2046
|
}
|
|
@@ -2452,26 +2480,24 @@ shaka.media.DrmEngine = class {
|
|
|
2452
2480
|
// The order of preference for drmInfo:
|
|
2453
2481
|
// 1. Clear Key config, used for debugging, should override everything else.
|
|
2454
2482
|
// (The application can still specify a clearkey license server.)
|
|
2455
|
-
// 2. Application-configured servers, if
|
|
2456
|
-
// anything from the manifest.
|
|
2457
|
-
// manifest and key system B is in the player config, only B will be
|
|
2458
|
-
// used, not A.
|
|
2483
|
+
// 2. Application-configured servers, if present, override
|
|
2484
|
+
// anything from the manifest.
|
|
2459
2485
|
// 3. Manifest-provided license servers are only used if nothing else is
|
|
2460
2486
|
// specified.
|
|
2461
2487
|
// This is important because it allows the application a clear way to
|
|
2462
|
-
// indicate which DRM systems should be
|
|
2463
|
-
// systems.
|
|
2464
|
-
//
|
|
2465
|
-
//
|
|
2488
|
+
// indicate which DRM systems should be ignored on platforms with multiple
|
|
2489
|
+
// DRM systems.
|
|
2490
|
+
// Alternatively, use config.preferredKeySystems to specify the preferred
|
|
2491
|
+
// key system.
|
|
2466
2492
|
|
|
2467
2493
|
if (originalKeySystem == 'org.w3.clearkey' && drmInfo.licenseServerUri) {
|
|
2468
2494
|
// Preference 1: Clear Key with pre-configured keys will have a data URI
|
|
2469
2495
|
// assigned as its license server. Don't change anything.
|
|
2470
2496
|
return;
|
|
2471
|
-
} else if (servers.size) {
|
|
2472
|
-
// Preference 2: If
|
|
2473
|
-
// override whatever was in the manifest.
|
|
2474
|
-
const server = servers.get(originalKeySystem)
|
|
2497
|
+
} else if (servers.size && servers.get(originalKeySystem)) {
|
|
2498
|
+
// Preference 2: If a license server for this keySystem is configured at
|
|
2499
|
+
// the application level, override whatever was in the manifest.
|
|
2500
|
+
const server = servers.get(originalKeySystem);
|
|
2475
2501
|
|
|
2476
2502
|
drmInfo.licenseServerUri = server;
|
|
2477
2503
|
} else {
|
|
@@ -2632,6 +2658,21 @@ shaka.media.DrmEngine.SessionMetaData;
|
|
|
2632
2658
|
*/
|
|
2633
2659
|
shaka.media.DrmEngine.PlayerInterface;
|
|
2634
2660
|
|
|
2661
|
+
/**
|
|
2662
|
+
* @typedef {{
|
|
2663
|
+
* kids: !Array.<string>,
|
|
2664
|
+
* type: string
|
|
2665
|
+
* }}
|
|
2666
|
+
*
|
|
2667
|
+
* @property {!Array.<string>} kids
|
|
2668
|
+
* An array of key IDs. Each element of the array is the base64url encoding of
|
|
2669
|
+
* the octet sequence containing the key ID value.
|
|
2670
|
+
* @property {string} type
|
|
2671
|
+
* The requested MediaKeySessionType.
|
|
2672
|
+
* @see https://www.w3.org/TR/encrypted-media/#clear-key-request-format
|
|
2673
|
+
*/
|
|
2674
|
+
shaka.media.DrmEngine.ClearKeyLicenceRequestFormat;
|
|
2675
|
+
|
|
2635
2676
|
/**
|
|
2636
2677
|
* The amount of time, in seconds, we wait to consider a session closed.
|
|
2637
2678
|
* This allows us to work around Chrome bug https://crbug.com/1108158.
|
|
@@ -50,7 +50,8 @@ shaka.media.ManifestFilterer = class {
|
|
|
50
50
|
async filterManifest(manifest) {
|
|
51
51
|
goog.asserts.assert(manifest, 'Manifest should exist!');
|
|
52
52
|
await shaka.util.StreamUtils.filterManifest(this.drmEngine_, manifest,
|
|
53
|
-
this.config_.drm.preferredKeySystems
|
|
53
|
+
this.config_.drm.preferredKeySystems,
|
|
54
|
+
this.config_.drm.keySystemsMapping);
|
|
54
55
|
if (!this.config_.streaming.dontChooseCodecs) {
|
|
55
56
|
shaka.util.StreamUtils.chooseCodecsAndFilterManifest(
|
|
56
57
|
manifest,
|