shaka-player 4.7.6 → 4.7.8
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/AUTHORS +2 -0
- package/CONTRIBUTORS +2 -0
- package/dist/locales.js +30 -30
- 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.externs.js +2 -1
- package/dist/shaka-player.compiled.debug.js +94 -93
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.externs.js +2 -1
- package/dist/shaka-player.compiled.js +1105 -1099
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.d.ts +13 -2
- package/dist/shaka-player.ui.debug.d.ts +13 -2
- package/dist/shaka-player.ui.debug.externs.js +3 -1
- package/dist/shaka-player.ui.debug.js +257 -256
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.externs.js +3 -1
- package/dist/shaka-player.ui.js +1229 -1223
- package/dist/shaka-player.ui.map +3 -3
- package/lib/hls/hls_parser.js +14 -6
- package/lib/media/drm_engine.js +9 -0
- package/lib/mss/mss_parser.js +2 -0
- package/lib/offline/storage.js +4 -0
- package/lib/player.js +14 -3
- package/lib/polyfill/media_capabilities.js +23 -3
- package/lib/transmuxer/aac_transmuxer.js +2 -0
- package/lib/transmuxer/ac3_transmuxer.js +2 -0
- package/lib/transmuxer/ec3_transmuxer.js +2 -0
- package/lib/transmuxer/h264.js +28 -1
- package/lib/transmuxer/h265.js +25 -5
- package/lib/transmuxer/mp3_transmuxer.js +2 -0
- package/lib/transmuxer/ts_transmuxer.js +12 -0
- package/lib/util/cmcd_manager.js +13 -0
- package/lib/util/manifest_parser_utils.js +2 -0
- package/lib/util/mp4_generator.js +31 -2
- package/lib/util/stream_utils.js +2 -10
- package/lib/util/ts_parser.js +7 -4
- package/package.json +1 -1
- package/ui/externs/ui.js +24 -0
- package/ui/play_button.js +3 -0
package/lib/hls/hls_parser.js
CHANGED
|
@@ -447,8 +447,9 @@ shaka.hls.HlsParser = class {
|
|
|
447
447
|
const {segments, bandwidth} = this.createSegments_(
|
|
448
448
|
playlist, stream, mediaSequenceToStartTime, mediaVariables,
|
|
449
449
|
streamInfo.getUris);
|
|
450
|
-
|
|
451
|
-
|
|
450
|
+
if (bandwidth) {
|
|
451
|
+
stream.bandwidth = bandwidth;
|
|
452
|
+
}
|
|
452
453
|
|
|
453
454
|
stream.segmentIndex.mergeAndEvict(
|
|
454
455
|
segments, this.presentationTimeline_.getSegmentAvailabilityStart());
|
|
@@ -1383,7 +1384,7 @@ shaka.hls.HlsParser = class {
|
|
|
1383
1384
|
videoLayout = videoLayout || 'CH-MONO';
|
|
1384
1385
|
|
|
1385
1386
|
const streamInfos = this.createStreamInfosForVariantTags_(tags,
|
|
1386
|
-
mediaTags, resolution, frameRate);
|
|
1387
|
+
mediaTags, resolution, frameRate, bandwidth);
|
|
1387
1388
|
|
|
1388
1389
|
goog.asserts.assert(streamInfos.audio.length ||
|
|
1389
1390
|
streamInfos.video.length, 'We should have created a stream!');
|
|
@@ -1411,10 +1412,12 @@ shaka.hls.HlsParser = class {
|
|
|
1411
1412
|
* @param {!Array.<!shaka.hls.Tag>} mediaTags
|
|
1412
1413
|
* @param {?string} resolution
|
|
1413
1414
|
* @param {?string} frameRate
|
|
1415
|
+
* @param {number} bandwidth
|
|
1414
1416
|
* @return {!shaka.hls.HlsParser.StreamInfos}
|
|
1415
1417
|
* @private
|
|
1416
1418
|
*/
|
|
1417
|
-
createStreamInfosForVariantTags_(
|
|
1419
|
+
createStreamInfosForVariantTags_(
|
|
1420
|
+
tags, mediaTags, resolution, frameRate, bandwidth) {
|
|
1418
1421
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
1419
1422
|
|
|
1420
1423
|
/** @type {shaka.hls.HlsParser.StreamInfos} */
|
|
@@ -1549,6 +1552,9 @@ shaka.hls.HlsParser = class {
|
|
|
1549
1552
|
if (globalGroupId) {
|
|
1550
1553
|
streamInfo.stream.groupId = globalGroupId;
|
|
1551
1554
|
}
|
|
1555
|
+
if (!streamInfos.length) {
|
|
1556
|
+
streamInfo.stream.bandwidth = bandwidth;
|
|
1557
|
+
}
|
|
1552
1558
|
res[streamInfo.stream.type] = [streamInfo];
|
|
1553
1559
|
}
|
|
1554
1560
|
return res;
|
|
@@ -2252,7 +2258,7 @@ shaka.hls.HlsParser = class {
|
|
|
2252
2258
|
stream.drmInfos = realStream.drmInfos;
|
|
2253
2259
|
stream.keyIds = realStream.keyIds;
|
|
2254
2260
|
stream.mimeType = realStream.mimeType;
|
|
2255
|
-
stream.bandwidth = realStream.bandwidth;
|
|
2261
|
+
stream.bandwidth = stream.bandwidth || realStream.bandwidth;
|
|
2256
2262
|
stream.codecs = stream.codecs || realStream.codecs;
|
|
2257
2263
|
|
|
2258
2264
|
// Since we lazy-loaded this content, the player may need to create new
|
|
@@ -2531,7 +2537,9 @@ shaka.hls.HlsParser = class {
|
|
|
2531
2537
|
|
|
2532
2538
|
const {segments, bandwidth} = this.createSegments_(
|
|
2533
2539
|
playlist, stream, mediaSequenceToStartTime, mediaVariables, getUris);
|
|
2534
|
-
|
|
2540
|
+
if (bandwidth) {
|
|
2541
|
+
stream.bandwidth = bandwidth;
|
|
2542
|
+
}
|
|
2535
2543
|
|
|
2536
2544
|
// This new calculation is necessary for Low Latency streams.
|
|
2537
2545
|
if (this.isLive_()) {
|
package/lib/media/drm_engine.js
CHANGED
|
@@ -542,6 +542,15 @@ shaka.media.DrmEngine = class {
|
|
|
542
542
|
}
|
|
543
543
|
}
|
|
544
544
|
|
|
545
|
+
/**
|
|
546
|
+
* Returns true if the manifest has init data.
|
|
547
|
+
*
|
|
548
|
+
* @return {boolean}
|
|
549
|
+
*/
|
|
550
|
+
hasManifestInitData() {
|
|
551
|
+
return !!this.manifestInitData_;
|
|
552
|
+
}
|
|
553
|
+
|
|
545
554
|
/**
|
|
546
555
|
* Sets the server certificate based on the current DrmInfo.
|
|
547
556
|
*
|
package/lib/mss/mss_parser.js
CHANGED
|
@@ -661,6 +661,8 @@ shaka.mss.MssParser = class {
|
|
|
661
661
|
videoNalus: videoNalus,
|
|
662
662
|
audioConfig: new Uint8Array([]),
|
|
663
663
|
videoConfig: new Uint8Array([]),
|
|
664
|
+
hSpacing: 0,
|
|
665
|
+
vSpacing: 0,
|
|
664
666
|
data: null, // Data is not necessary for init segement.
|
|
665
667
|
stream: stream,
|
|
666
668
|
};
|
package/lib/offline/storage.js
CHANGED
|
@@ -400,6 +400,10 @@ shaka.offline.Storage = class {
|
|
|
400
400
|
downloader, config, activeHandle.cell, manifest, drmEngine);
|
|
401
401
|
this.ensureNotDestroyed_();
|
|
402
402
|
|
|
403
|
+
this.setManifestDrmFields_(manifest, manifestDB, drmEngine, config);
|
|
404
|
+
await activeHandle.cell.updateManifest(manifestId, manifestDB);
|
|
405
|
+
this.ensureNotDestroyed_();
|
|
406
|
+
|
|
403
407
|
const offlineUri = shaka.offline.OfflineUri.manifest(
|
|
404
408
|
activeHandle.path.mechanism, activeHandle.path.cell, manifestId);
|
|
405
409
|
|
package/lib/player.js
CHANGED
|
@@ -723,6 +723,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
723
723
|
|
|
724
724
|
if (shaka.Player.adManagerFactory_) {
|
|
725
725
|
this.adManager_ = shaka.Player.adManagerFactory_();
|
|
726
|
+
this.adManager_.configure(this.config_.ads);
|
|
726
727
|
}
|
|
727
728
|
|
|
728
729
|
// If the browser comes back online after being offline, then try to play
|
|
@@ -4691,6 +4692,12 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4691
4692
|
shaka.util.Error.Code.CONTENT_NOT_LOADED);
|
|
4692
4693
|
}
|
|
4693
4694
|
|
|
4695
|
+
if (kind != 'subtitles' && kind != 'captions') {
|
|
4696
|
+
shaka.log.alwaysWarn(
|
|
4697
|
+
'Using a kind value different of `subtitles` or `captions` can ' +
|
|
4698
|
+
'cause unwanted issues.');
|
|
4699
|
+
}
|
|
4700
|
+
|
|
4694
4701
|
if (!mimeType) {
|
|
4695
4702
|
mimeType = await this.getTextMimetype_(uri);
|
|
4696
4703
|
}
|
|
@@ -6494,6 +6501,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
6494
6501
|
const restrictedStatuses = shaka.Player.restrictedStatuses_;
|
|
6495
6502
|
let tracksChanged = false;
|
|
6496
6503
|
|
|
6504
|
+
goog.asserts.assert(this.drmEngine_, 'drmEngine should be non-null here.');
|
|
6505
|
+
|
|
6497
6506
|
// Only filter tracks for keys if we have some key statuses to look at.
|
|
6498
6507
|
if (keyIds.length) {
|
|
6499
6508
|
for (const variant of this.manifest_.variants) {
|
|
@@ -6509,8 +6518,10 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
6509
6518
|
|
|
6510
6519
|
for (const keyId of stream.keyIds) {
|
|
6511
6520
|
const keyStatus = keyStatusMap[isGlobalStatus ? '00' : keyId];
|
|
6512
|
-
|
|
6513
|
-
|
|
6521
|
+
if (keyStatus || this.drmEngine_.hasManifestInitData()) {
|
|
6522
|
+
variant.allowedByKeySystem = variant.allowedByKeySystem &&
|
|
6523
|
+
!!keyStatus && !restrictedStatuses.includes(keyStatus);
|
|
6524
|
+
}
|
|
6514
6525
|
}
|
|
6515
6526
|
}
|
|
6516
6527
|
|
|
@@ -6914,7 +6925,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
6914
6925
|
* @export
|
|
6915
6926
|
*/
|
|
6916
6927
|
// eslint-disable-next-line no-useless-concat
|
|
6917
|
-
shaka.Player.version = 'v4.7.
|
|
6928
|
+
shaka.Player.version = 'v4.7.8' + '-uncompiled'; // x-release-please-version
|
|
6918
6929
|
|
|
6919
6930
|
// Initialize the deprecation system using the version string we just set
|
|
6920
6931
|
// on the player.
|
|
@@ -141,8 +141,15 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
if (audioConfig) {
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
let isSupported;
|
|
145
|
+
if (shaka.util.Platform.isChromecast() &&
|
|
146
|
+
audioConfig.spatialRendering) {
|
|
147
|
+
const extendedType =
|
|
148
|
+
audioConfig.contentType + '; spatialRendering=true';
|
|
149
|
+
isSupported = Capabilities.isTypeSupported(extendedType);
|
|
150
|
+
} else {
|
|
151
|
+
isSupported = Capabilities.isTypeSupported(audioConfig.contentType);
|
|
152
|
+
}
|
|
146
153
|
if (!isSupported) {
|
|
147
154
|
return res;
|
|
148
155
|
}
|
|
@@ -184,10 +191,23 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
184
191
|
const videoCapabilities = [];
|
|
185
192
|
|
|
186
193
|
if (mediaCapkeySystemConfig.audio) {
|
|
187
|
-
|
|
194
|
+
let capability = {
|
|
188
195
|
robustness: mediaCapkeySystemConfig.audio.robustness || '',
|
|
189
196
|
contentType: mediaDecodingConfig.audio.contentType,
|
|
190
197
|
};
|
|
198
|
+
|
|
199
|
+
// Some Tizen devices seem to misreport AC-3 support, but correctly
|
|
200
|
+
// report EC-3 support. So query EC-3 as a fallback for AC-3.
|
|
201
|
+
// See https://github.com/shaka-project/shaka-player/issues/2989 for
|
|
202
|
+
// details.
|
|
203
|
+
if (shaka.util.Platform.isTizen() &&
|
|
204
|
+
mediaDecodingConfig.audio.contentType.includes('codecs="ac-3"')) {
|
|
205
|
+
capability = {
|
|
206
|
+
robustness: capability.robustness,
|
|
207
|
+
contentType: 'audio/mp4; codecs="ec-3"',
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
191
211
|
audioCapabilities.push(capability);
|
|
192
212
|
}
|
|
193
213
|
|
|
@@ -195,6 +195,8 @@ shaka.transmuxer.AacTransmuxer = class {
|
|
|
195
195
|
videoNalus: [],
|
|
196
196
|
audioConfig: new Uint8Array([]),
|
|
197
197
|
videoConfig: new Uint8Array([]),
|
|
198
|
+
hSpacing: 0,
|
|
199
|
+
vSpacing: 0,
|
|
198
200
|
data: {
|
|
199
201
|
sequenceNumber: this.frameIndex_,
|
|
200
202
|
baseMediaDecodeTime: baseMediaDecodeTime,
|
|
@@ -184,6 +184,8 @@ shaka.transmuxer.Ac3Transmuxer = class {
|
|
|
184
184
|
videoNalus: [],
|
|
185
185
|
audioConfig: audioConfig,
|
|
186
186
|
videoConfig: new Uint8Array([]),
|
|
187
|
+
hSpacing: 0,
|
|
188
|
+
vSpacing: 0,
|
|
187
189
|
data: {
|
|
188
190
|
sequenceNumber: this.frameIndex_,
|
|
189
191
|
baseMediaDecodeTime: baseMediaDecodeTime,
|
|
@@ -184,6 +184,8 @@ shaka.transmuxer.Ec3Transmuxer = class {
|
|
|
184
184
|
videoNalus: [],
|
|
185
185
|
audioConfig: audioConfig,
|
|
186
186
|
videoConfig: new Uint8Array([]),
|
|
187
|
+
hSpacing: 0,
|
|
188
|
+
vSpacing: 0,
|
|
187
189
|
data: {
|
|
188
190
|
sequenceNumber: this.frameIndex_,
|
|
189
191
|
baseMediaDecodeTime: baseMediaDecodeTime,
|
package/lib/transmuxer/h264.js
CHANGED
|
@@ -20,7 +20,8 @@ shaka.transmuxer.H264 = class {
|
|
|
20
20
|
* describes the properties of upcoming video frames.
|
|
21
21
|
*
|
|
22
22
|
* @param {!Array.<shaka.extern.VideoNalu>} nalus
|
|
23
|
-
* @return {?{height: number, width: number, videoConfig: !Uint8Array
|
|
23
|
+
* @return {?{height: number, width: number, videoConfig: !Uint8Array,
|
|
24
|
+
* hSpacing: number, vSpacing: number}}
|
|
24
25
|
*/
|
|
25
26
|
static parseInfo(nalus) {
|
|
26
27
|
const H264 = shaka.transmuxer.H264;
|
|
@@ -129,6 +130,30 @@ shaka.transmuxer.H264 = class {
|
|
|
129
130
|
frameCropBottomOffset = expGolombDecoder.readUnsignedExpGolomb();
|
|
130
131
|
}
|
|
131
132
|
|
|
133
|
+
let hSpacing = 1;
|
|
134
|
+
let vSpacing = 1;
|
|
135
|
+
|
|
136
|
+
// vui_parameters_present_flag
|
|
137
|
+
if (expGolombDecoder.readBoolean()) {
|
|
138
|
+
// aspect_ratio_info_present_flag
|
|
139
|
+
if (expGolombDecoder.readBoolean()) {
|
|
140
|
+
const aspectRatioIdc = expGolombDecoder.readUnsignedByte();
|
|
141
|
+
const hSpacingTable = [
|
|
142
|
+
1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2,
|
|
143
|
+
];
|
|
144
|
+
const vSpacingTable = [
|
|
145
|
+
1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1,
|
|
146
|
+
];
|
|
147
|
+
if (aspectRatioIdc > 0 && aspectRatioIdc < 16) {
|
|
148
|
+
hSpacing = hSpacingTable[aspectRatioIdc - 1];
|
|
149
|
+
vSpacing = vSpacingTable[aspectRatioIdc - 1];
|
|
150
|
+
} else if (aspectRatioIdc === 255) {
|
|
151
|
+
hSpacing = expGolombDecoder.readBits(16);
|
|
152
|
+
vSpacing = expGolombDecoder.readBits(16);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
132
157
|
const height = ((2 - frameMbsOnlyFlag) *
|
|
133
158
|
(picHeightInMapUnitsMinus1 + 1) * 16) - (frameCropTopOffset * 2) -
|
|
134
159
|
(frameCropBottomOffset * 2);
|
|
@@ -165,6 +190,8 @@ shaka.transmuxer.H264 = class {
|
|
|
165
190
|
height,
|
|
166
191
|
width,
|
|
167
192
|
videoConfig,
|
|
193
|
+
hSpacing,
|
|
194
|
+
vSpacing,
|
|
168
195
|
};
|
|
169
196
|
}
|
|
170
197
|
|
package/lib/transmuxer/h265.js
CHANGED
|
@@ -20,7 +20,8 @@ shaka.transmuxer.H265 = class {
|
|
|
20
20
|
* describes the properties of upcoming video frames.
|
|
21
21
|
*
|
|
22
22
|
* @param {!Array.<shaka.extern.VideoNalu>} nalus
|
|
23
|
-
* @return {?{height: number, width: number, videoConfig: !Uint8Array
|
|
23
|
+
* @return {?{height: number, width: number, videoConfig: !Uint8Array,
|
|
24
|
+
* hSpacing: number, vSpacing: number}}
|
|
24
25
|
*/
|
|
25
26
|
static parseInfo(nalus) {
|
|
26
27
|
const H265 = shaka.transmuxer.H265;
|
|
@@ -87,6 +88,8 @@ shaka.transmuxer.H265 = class {
|
|
|
87
88
|
height: spsConfiguration.height,
|
|
88
89
|
width: spsConfiguration.width,
|
|
89
90
|
videoConfig,
|
|
91
|
+
hSpacing: spsConfiguration.sarWidth,
|
|
92
|
+
vSpacing: spsConfiguration.sarHeight,
|
|
90
93
|
};
|
|
91
94
|
}
|
|
92
95
|
|
|
@@ -298,6 +301,8 @@ shaka.transmuxer.H265 = class {
|
|
|
298
301
|
}
|
|
299
302
|
}
|
|
300
303
|
let defaultDisplayWindowFlag = false; // for calc offset
|
|
304
|
+
let sarWidth = 1;
|
|
305
|
+
let sarHeight = 1;
|
|
301
306
|
let minSpatialSegmentationIdc = 0; // for hvcC
|
|
302
307
|
gb.readBoolean(); // sps_temporal_mvp_enabled_flag
|
|
303
308
|
gb.readBoolean(); // strong_intra_smoothing_enabled_flag
|
|
@@ -306,9 +311,18 @@ shaka.transmuxer.H265 = class {
|
|
|
306
311
|
const aspectRatioInfoPresentFlag = gb.readBoolean();
|
|
307
312
|
if (aspectRatioInfoPresentFlag) {
|
|
308
313
|
const aspectRatioIdc = gb.readUnsignedByte();
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
314
|
+
const sarWidthTable = [
|
|
315
|
+
1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2,
|
|
316
|
+
];
|
|
317
|
+
const sarHeightTable = [
|
|
318
|
+
1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1,
|
|
319
|
+
];
|
|
320
|
+
if (aspectRatioIdc > 0 && aspectRatioIdc < 16) {
|
|
321
|
+
sarWidth = sarWidthTable[aspectRatioIdc - 1];
|
|
322
|
+
sarHeight = sarHeightTable[aspectRatioIdc - 1];
|
|
323
|
+
} else if (aspectRatioIdc === 255) {
|
|
324
|
+
sarWidth = gb.readBits(16);
|
|
325
|
+
sarHeight = gb.readBits(16);
|
|
312
326
|
}
|
|
313
327
|
}
|
|
314
328
|
const overscanInfoPresentFlag = gb.readBoolean();
|
|
@@ -459,6 +473,8 @@ shaka.transmuxer.H265 = class {
|
|
|
459
473
|
bitDepthChromaMinus8,
|
|
460
474
|
width: codecWidth,
|
|
461
475
|
height: codecHeight,
|
|
476
|
+
sarWidth: sarWidth,
|
|
477
|
+
sarHeight: sarHeight,
|
|
462
478
|
};
|
|
463
479
|
}
|
|
464
480
|
|
|
@@ -773,7 +789,9 @@ shaka.transmuxer.H265.VPSConfiguration;
|
|
|
773
789
|
* bitDepthLumaMinus8: number,
|
|
774
790
|
* bitDepthChromaMinus8: number,
|
|
775
791
|
* width: number,
|
|
776
|
-
* height: number
|
|
792
|
+
* height: number,
|
|
793
|
+
* sarWidth: number,
|
|
794
|
+
* sarHeight: number
|
|
777
795
|
* }}
|
|
778
796
|
*
|
|
779
797
|
* @property {number} generalProfileSpace
|
|
@@ -797,6 +815,8 @@ shaka.transmuxer.H265.VPSConfiguration;
|
|
|
797
815
|
* @property {number} bitDepthChromaMinus8
|
|
798
816
|
* @property {number} width
|
|
799
817
|
* @property {number} height
|
|
818
|
+
* @property {number} sarWidth
|
|
819
|
+
* @property {number} sarHeight
|
|
800
820
|
*/
|
|
801
821
|
shaka.transmuxer.H265.SPSConfiguration;
|
|
802
822
|
|
|
@@ -176,6 +176,8 @@ shaka.transmuxer.Mp3Transmuxer = class {
|
|
|
176
176
|
videoNalus: [],
|
|
177
177
|
audioConfig: new Uint8Array([]),
|
|
178
178
|
videoConfig: new Uint8Array([]),
|
|
179
|
+
hSpacing: 0,
|
|
180
|
+
vSpacing: 0,
|
|
179
181
|
data: {
|
|
180
182
|
sequenceNumber: this.frameIndex_,
|
|
181
183
|
baseMediaDecodeTime: baseMediaDecodeTime,
|
|
@@ -409,6 +409,8 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
409
409
|
videoNalus: [],
|
|
410
410
|
audioConfig: new Uint8Array([]),
|
|
411
411
|
videoConfig: new Uint8Array([]),
|
|
412
|
+
hSpacing: 0,
|
|
413
|
+
vSpacing: 0,
|
|
412
414
|
data: {
|
|
413
415
|
sequenceNumber: this.frameIndex_,
|
|
414
416
|
baseMediaDecodeTime: baseMediaDecodeTime,
|
|
@@ -500,6 +502,8 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
500
502
|
videoNalus: [],
|
|
501
503
|
audioConfig: audioConfig,
|
|
502
504
|
videoConfig: new Uint8Array([]),
|
|
505
|
+
hSpacing: 0,
|
|
506
|
+
vSpacing: 0,
|
|
503
507
|
data: {
|
|
504
508
|
sequenceNumber: this.frameIndex_,
|
|
505
509
|
baseMediaDecodeTime: baseMediaDecodeTime,
|
|
@@ -591,6 +595,8 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
591
595
|
videoNalus: [],
|
|
592
596
|
audioConfig: audioConfig,
|
|
593
597
|
videoConfig: new Uint8Array([]),
|
|
598
|
+
hSpacing: 0,
|
|
599
|
+
vSpacing: 0,
|
|
594
600
|
data: {
|
|
595
601
|
sequenceNumber: this.frameIndex_,
|
|
596
602
|
baseMediaDecodeTime: baseMediaDecodeTime,
|
|
@@ -677,6 +683,8 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
677
683
|
videoNalus: [],
|
|
678
684
|
audioConfig: new Uint8Array([]),
|
|
679
685
|
videoConfig: new Uint8Array([]),
|
|
686
|
+
hSpacing: 0,
|
|
687
|
+
vSpacing: 0,
|
|
680
688
|
data: {
|
|
681
689
|
sequenceNumber: this.frameIndex_,
|
|
682
690
|
baseMediaDecodeTime: baseMediaDecodeTime,
|
|
@@ -769,6 +777,8 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
769
777
|
videoNalus: [],
|
|
770
778
|
audioConfig: new Uint8Array([]),
|
|
771
779
|
videoConfig: info.videoConfig,
|
|
780
|
+
hSpacing: info.hSpacing,
|
|
781
|
+
vSpacing: info.vSpacing,
|
|
772
782
|
data: {
|
|
773
783
|
sequenceNumber: this.frameIndex_,
|
|
774
784
|
baseMediaDecodeTime: baseMediaDecodeTime,
|
|
@@ -861,6 +871,8 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
861
871
|
videoNalus: [],
|
|
862
872
|
audioConfig: new Uint8Array([]),
|
|
863
873
|
videoConfig: info.videoConfig,
|
|
874
|
+
hSpacing: info.hSpacing,
|
|
875
|
+
vSpacing: info.vSpacing,
|
|
864
876
|
data: {
|
|
865
877
|
sequenceNumber: this.frameIndex_,
|
|
866
878
|
baseMediaDecodeTime: baseMediaDecodeTime,
|
package/lib/util/cmcd_manager.js
CHANGED
|
@@ -65,6 +65,9 @@ shaka.util.CmcdManager = class {
|
|
|
65
65
|
*/
|
|
66
66
|
configure(config) {
|
|
67
67
|
this.config_ = config;
|
|
68
|
+
if (this.config_.sessionId && this.config_.sessionId != this.sid_) {
|
|
69
|
+
this.sid_ = '';
|
|
70
|
+
}
|
|
68
71
|
}
|
|
69
72
|
|
|
70
73
|
/**
|
|
@@ -407,6 +410,15 @@ shaka.util.CmcdManager = class {
|
|
|
407
410
|
*/
|
|
408
411
|
getObjectTypeFromMimeType_(mimeType) {
|
|
409
412
|
switch (mimeType.toLowerCase()) {
|
|
413
|
+
case 'audio/mp4':
|
|
414
|
+
case 'audio/webm':
|
|
415
|
+
case 'audio/ogg':
|
|
416
|
+
case 'audio/mpeg':
|
|
417
|
+
case 'audio/aac':
|
|
418
|
+
case 'audio/flac':
|
|
419
|
+
case 'audio/wav':
|
|
420
|
+
return shaka.util.CmcdManager.ObjectType.AUDIO;
|
|
421
|
+
|
|
410
422
|
case 'video/webm':
|
|
411
423
|
case 'video/mp4':
|
|
412
424
|
case 'video/mpeg':
|
|
@@ -417,6 +429,7 @@ shaka.util.CmcdManager = class {
|
|
|
417
429
|
case 'application/vnd.apple.mpegurl':
|
|
418
430
|
case 'application/dash+xml':
|
|
419
431
|
case 'video/vnd.mpeg.dash.mpd':
|
|
432
|
+
case 'application/vnd.ms-sstr+xml':
|
|
420
433
|
return shaka.util.CmcdManager.ObjectType.MANIFEST;
|
|
421
434
|
|
|
422
435
|
default:
|
|
@@ -371,12 +371,13 @@ shaka.util.Mp4Generator = class {
|
|
|
371
371
|
]);
|
|
372
372
|
|
|
373
373
|
let boxName = 'avc1';
|
|
374
|
+
const paspBox = this.pasp_(streamInfo);
|
|
374
375
|
let sinfBox = new Uint8Array([]);
|
|
375
376
|
if (streamInfo.encrypted) {
|
|
376
377
|
sinfBox = this.sinf_(streamInfo);
|
|
377
378
|
boxName = 'encv';
|
|
378
379
|
}
|
|
379
|
-
return Mp4Generator.box(boxName, avc1Bytes, avcCBox, sinfBox);
|
|
380
|
+
return Mp4Generator.box(boxName, avc1Bytes, avcCBox, paspBox, sinfBox);
|
|
380
381
|
}
|
|
381
382
|
|
|
382
383
|
/**
|
|
@@ -500,12 +501,34 @@ shaka.util.Mp4Generator = class {
|
|
|
500
501
|
]);
|
|
501
502
|
|
|
502
503
|
let boxName = 'hvc1';
|
|
504
|
+
const paspBox = this.pasp_(streamInfo);
|
|
503
505
|
let sinfBox = new Uint8Array([]);
|
|
504
506
|
if (streamInfo.encrypted) {
|
|
505
507
|
sinfBox = this.sinf_(streamInfo);
|
|
506
508
|
boxName = 'encv';
|
|
507
509
|
}
|
|
508
|
-
return Mp4Generator.box(boxName, hvc1Bytes, hvcCBox, sinfBox);
|
|
510
|
+
return Mp4Generator.box(boxName, hvc1Bytes, hvcCBox, paspBox, sinfBox);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Generate a PASP box
|
|
515
|
+
*
|
|
516
|
+
* @param {shaka.util.Mp4Generator.StreamInfo} streamInfo
|
|
517
|
+
* @return {!Uint8Array}
|
|
518
|
+
* @private
|
|
519
|
+
*/
|
|
520
|
+
pasp_(streamInfo) {
|
|
521
|
+
if (!streamInfo.hSpacing && !streamInfo.vSpacing) {
|
|
522
|
+
return new Uint8Array([]);
|
|
523
|
+
}
|
|
524
|
+
const Mp4Generator = shaka.util.Mp4Generator;
|
|
525
|
+
const hSpacing = streamInfo.hSpacing;
|
|
526
|
+
const vSpacing = streamInfo.vSpacing;
|
|
527
|
+
const bytes = new Uint8Array([
|
|
528
|
+
...this.breakNumberIntoBytes_(hSpacing, 4), // hSpacing
|
|
529
|
+
...this.breakNumberIntoBytes_(vSpacing, 4), // vSpacing
|
|
530
|
+
]);
|
|
531
|
+
return Mp4Generator.box('pasp', bytes);
|
|
509
532
|
}
|
|
510
533
|
|
|
511
534
|
/**
|
|
@@ -1301,6 +1324,8 @@ shaka.util.Mp4Generator.DINF_ = new Uint8Array([]);
|
|
|
1301
1324
|
* videoNalus: !Array.<string>,
|
|
1302
1325
|
* audioConfig: !Uint8Array,
|
|
1303
1326
|
* videoConfig: !Uint8Array,
|
|
1327
|
+
* hSpacing: number,
|
|
1328
|
+
* vSpacing: number,
|
|
1304
1329
|
* data: ?shaka.util.Mp4Generator.Data,
|
|
1305
1330
|
* stream: !shaka.extern.Stream
|
|
1306
1331
|
* }}
|
|
@@ -1325,6 +1350,10 @@ shaka.util.Mp4Generator.DINF_ = new Uint8Array([]);
|
|
|
1325
1350
|
* The stream's audio config.
|
|
1326
1351
|
* @property {!Uint8Array} videoConfig
|
|
1327
1352
|
* The stream's video config.
|
|
1353
|
+
* @property {number} hSpacing
|
|
1354
|
+
* The stream's video horizontal spacing of pixels.
|
|
1355
|
+
* @property {number} vSpacing
|
|
1356
|
+
* The stream's video vertial spacing of pixels.
|
|
1328
1357
|
* @property {?shaka.util.Mp4Generator.Data} data
|
|
1329
1358
|
* The stream's data.
|
|
1330
1359
|
* @property {!shaka.extern.Stream} stream
|
package/lib/util/stream_utils.js
CHANGED
|
@@ -162,7 +162,7 @@ shaka.util.StreamUtils = class {
|
|
|
162
162
|
const currentCodec =
|
|
163
163
|
MimeUtils.getNormalizedCodec(stream.codecs);
|
|
164
164
|
if (previousCodec == currentCodec) {
|
|
165
|
-
if (stream.bandwidth
|
|
165
|
+
if (stream.bandwidth > previousStream.bandwidth) {
|
|
166
166
|
validVideoStreams.push(stream);
|
|
167
167
|
validVideoIds.push(stream.id);
|
|
168
168
|
}
|
|
@@ -917,15 +917,7 @@ shaka.util.StreamUtils = class {
|
|
|
917
917
|
return 'opus';
|
|
918
918
|
}
|
|
919
919
|
|
|
920
|
-
|
|
921
|
-
// report EC-3 support. So query EC-3 as a fallback for AC-3.
|
|
922
|
-
// See https://github.com/shaka-project/shaka-player/issues/2989 for
|
|
923
|
-
// details.
|
|
924
|
-
if (shaka.util.Platform.isTizen()) {
|
|
925
|
-
return codecs.toLowerCase() == 'ac-3' ? 'ec-3' : codecs;
|
|
926
|
-
} else {
|
|
927
|
-
return codecs;
|
|
928
|
-
}
|
|
920
|
+
return codecs;
|
|
929
921
|
}
|
|
930
922
|
|
|
931
923
|
|
package/lib/util/ts_parser.js
CHANGED
|
@@ -446,10 +446,11 @@ shaka.util.TsParser = class {
|
|
|
446
446
|
*
|
|
447
447
|
* @param {shaka.extern.MPEG_PES} pes
|
|
448
448
|
* @param {?shaka.extern.VideoNalu=} lastNalu
|
|
449
|
+
* @param {?number=} lastState
|
|
449
450
|
* @return {!Array.<shaka.extern.VideoNalu>}
|
|
450
451
|
* @export
|
|
451
452
|
*/
|
|
452
|
-
parseNalus(pes, lastNalu) {
|
|
453
|
+
parseNalus(pes, lastNalu, lastState) {
|
|
453
454
|
const timescale = shaka.util.TsParser.Timescale;
|
|
454
455
|
const time = pes.pts ? pes.pts / timescale : null;
|
|
455
456
|
const data = pes.data;
|
|
@@ -465,7 +466,7 @@ shaka.util.TsParser = class {
|
|
|
465
466
|
// precede each NALU. A start code is 2 or 3 0x00 bytes followed with a
|
|
466
467
|
// 0x01 byte. e.g. 0x000001 or 0x00000001.
|
|
467
468
|
// More info in: https://stackoverflow.com/questions/24884827/possible-locations-for-sequence-picture-parameter-sets-for-h-264-stream/24890903#24890903
|
|
468
|
-
let numZeros = 0;
|
|
469
|
+
let numZeros = lastState || 0;
|
|
469
470
|
|
|
470
471
|
/** @type {!Array.<shaka.extern.VideoNalu>} */
|
|
471
472
|
const nalus = [];
|
|
@@ -490,7 +491,7 @@ shaka.util.TsParser = class {
|
|
|
490
491
|
const startCodeSize = numZeros > 3 ? 3 : numZeros;
|
|
491
492
|
const lastByteToKeep = i - startCodeSize;
|
|
492
493
|
// Optimization
|
|
493
|
-
if (lastByteToKeep != 0) {
|
|
494
|
+
if (lastState && lastByteToKeep != 0) {
|
|
494
495
|
const prevData = data.subarray(0, lastByteToKeep);
|
|
495
496
|
lastNalu.data = shaka.util.Uint8ArrayUtils.concat(
|
|
496
497
|
lastNalu.data, prevData);
|
|
@@ -572,6 +573,7 @@ shaka.util.TsParser = class {
|
|
|
572
573
|
lastNalu.fullData = shaka.util.Uint8ArrayUtils.concat(
|
|
573
574
|
lastNalu.fullData, data);
|
|
574
575
|
}
|
|
576
|
+
lastState = Math.min(3, numZeros);
|
|
575
577
|
return nalus;
|
|
576
578
|
}
|
|
577
579
|
|
|
@@ -676,8 +678,9 @@ shaka.util.TsParser = class {
|
|
|
676
678
|
}
|
|
677
679
|
if (naluProcessing) {
|
|
678
680
|
let lastNalu;
|
|
681
|
+
let lastState;
|
|
679
682
|
for (const pes of this.videoPes_) {
|
|
680
|
-
pes.nalus = this.parseNalus(pes, lastNalu);
|
|
683
|
+
pes.nalus = this.parseNalus(pes, lastNalu, lastState);
|
|
681
684
|
if (pes.nalus.length) {
|
|
682
685
|
lastNalu = pes.nalus[pes.nalus.length - 1];
|
|
683
686
|
}
|
package/package.json
CHANGED
package/ui/externs/ui.js
CHANGED
|
@@ -486,3 +486,27 @@ shaka.extern.IUISeekBar.Factory = class {
|
|
|
486
486
|
*/
|
|
487
487
|
create(rootElement, controls) {}
|
|
488
488
|
};
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* @interface
|
|
492
|
+
* @exportDoc
|
|
493
|
+
*/
|
|
494
|
+
shaka.extern.IUIPlayButton = class {
|
|
495
|
+
/**
|
|
496
|
+
* @param {!HTMLElement} parent
|
|
497
|
+
* @param {!shaka.ui.Controls} controls
|
|
498
|
+
*/
|
|
499
|
+
constructor(parent, controls) {
|
|
500
|
+
/**
|
|
501
|
+
* @protected {!HTMLButtonElement}
|
|
502
|
+
* @exportDoc
|
|
503
|
+
*/
|
|
504
|
+
this.button;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/** @return {boolean} */
|
|
508
|
+
isPaused() {}
|
|
509
|
+
|
|
510
|
+
/** @return {boolean} */
|
|
511
|
+
isEnded() {}
|
|
512
|
+
};
|
package/ui/play_button.js
CHANGED
|
@@ -16,6 +16,7 @@ goog.requireType('shaka.ui.Controls');
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @extends {shaka.ui.Element}
|
|
19
|
+
* @implements {shaka.extern.IUIPlayButton}
|
|
19
20
|
* @export
|
|
20
21
|
*/
|
|
21
22
|
shaka.ui.PlayButton = class extends shaka.ui.Element {
|
|
@@ -95,6 +96,7 @@ shaka.ui.PlayButton = class extends shaka.ui.Element {
|
|
|
95
96
|
/**
|
|
96
97
|
* @return {boolean}
|
|
97
98
|
* @protected
|
|
99
|
+
* @override
|
|
98
100
|
*/
|
|
99
101
|
isPaused() {
|
|
100
102
|
if (this.ad && this.ad.isLinear()) {
|
|
@@ -107,6 +109,7 @@ shaka.ui.PlayButton = class extends shaka.ui.Element {
|
|
|
107
109
|
/**
|
|
108
110
|
* @return {boolean}
|
|
109
111
|
* @protected
|
|
112
|
+
* @override
|
|
110
113
|
*/
|
|
111
114
|
isEnded() {
|
|
112
115
|
if (this.ad && this.ad.isLinear()) {
|