shaka-player 4.6.0 → 4.6.1
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/CHANGELOG.md +11 -0
- package/dist/locales.js +33 -33
- package/dist/shaka-player.compiled.debug.js +254 -253
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.js +788 -787
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.debug.js +271 -271
- package/dist/shaka-player.ui.debug.map +2 -2
- package/dist/shaka-player.ui.js +870 -869
- package/dist/shaka-player.ui.map +3 -3
- package/lib/dash/dash_parser.js +12 -11
- package/lib/dash/segment_template.js +9 -3
- package/lib/hls/hls_parser.js +9 -3
- package/lib/media/streaming_engine.js +35 -27
- package/lib/player.js +6 -2
- package/package.json +1 -1
- package/test/hls/hls_parser_unit.js +40 -0
package/lib/dash/dash_parser.js
CHANGED
|
@@ -285,7 +285,8 @@ shaka.dash.DashParser = class {
|
|
|
285
285
|
|
|
286
286
|
// For redirections add the response uri to the first entry in the
|
|
287
287
|
// Manifest Uris array.
|
|
288
|
-
if (response.uri &&
|
|
288
|
+
if (response.uri && response.uri != response.originalUri &&
|
|
289
|
+
!this.manifestUris_.includes(response.uri)) {
|
|
289
290
|
this.manifestUris_.unshift(response.uri);
|
|
290
291
|
}
|
|
291
292
|
|
|
@@ -373,19 +374,16 @@ shaka.dash.DashParser = class {
|
|
|
373
374
|
|
|
374
375
|
const contentSteering = XmlUtils.findChild(mpd, 'ContentSteering');
|
|
375
376
|
if (contentSteering && this.playerInterface_) {
|
|
376
|
-
const
|
|
377
|
+
const defaultPathwayId =
|
|
378
|
+
contentSteering.getAttribute('defaultServiceLocation');
|
|
377
379
|
if (!this.contentSteeringManager_) {
|
|
378
380
|
this.contentSteeringManager_ =
|
|
379
381
|
new shaka.util.ContentSteeringManager(this.playerInterface_);
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
const defaultPathwayId =
|
|
386
|
-
contentSteering.getAttribute('defaultServiceLocation');
|
|
387
|
-
this.contentSteeringManager_.setDefaultPathwayId(defaultPathwayId);
|
|
388
|
-
if (!hasPrevContentSteeringManager) {
|
|
382
|
+
this.contentSteeringManager_.configure(this.config_);
|
|
383
|
+
this.contentSteeringManager_.setManifestType(
|
|
384
|
+
shaka.media.ManifestParser.DASH);
|
|
385
|
+
this.contentSteeringManager_.setBaseUris(manifestBaseUris);
|
|
386
|
+
this.contentSteeringManager_.setDefaultPathwayId(defaultPathwayId);
|
|
389
387
|
const uri = XmlUtils.getContents(contentSteering);
|
|
390
388
|
if (uri) {
|
|
391
389
|
const queryBeforeStart =
|
|
@@ -398,6 +396,9 @@ shaka.dash.DashParser = class {
|
|
|
398
396
|
this.contentSteeringManager_.requestInfo(uri);
|
|
399
397
|
}
|
|
400
398
|
}
|
|
399
|
+
} else {
|
|
400
|
+
this.contentSteeringManager_.setBaseUris(manifestBaseUris);
|
|
401
|
+
this.contentSteeringManager_.setDefaultPathwayId(defaultPathwayId);
|
|
401
402
|
}
|
|
402
403
|
}
|
|
403
404
|
|
|
@@ -141,7 +141,8 @@ shaka.dash.SegmentTemplate = class {
|
|
|
141
141
|
);
|
|
142
142
|
} else {
|
|
143
143
|
const tsi = /** @type {!TimelineSegmentIndex} */(segmentIndex);
|
|
144
|
-
tsi.appendTemplateInfo(
|
|
144
|
+
tsi.appendTemplateInfo(
|
|
145
|
+
info, periodStart, periodEnd, shouldFit, initSegmentReference);
|
|
145
146
|
|
|
146
147
|
const availabilityStart =
|
|
147
148
|
context.presentationTimeline.getSegmentAvailabilityStart();
|
|
@@ -167,7 +168,7 @@ shaka.dash.SegmentTemplate = class {
|
|
|
167
168
|
if (segmentIndex instanceof shaka.dash.TimelineSegmentIndex &&
|
|
168
169
|
segmentIndex.isEmpty()) {
|
|
169
170
|
segmentIndex.appendTemplateInfo(info, periodStart,
|
|
170
|
-
periodEnd, shouldFit);
|
|
171
|
+
periodEnd, shouldFit, initSegmentReference);
|
|
171
172
|
}
|
|
172
173
|
return Promise.resolve(segmentIndex);
|
|
173
174
|
},
|
|
@@ -684,8 +685,11 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
684
685
|
* @param {number} periodStart
|
|
685
686
|
* @param {number} periodEnd
|
|
686
687
|
* @param {boolean} shouldFit
|
|
688
|
+
* @param {shaka.media.InitSegmentReference} initSegmentReference
|
|
687
689
|
*/
|
|
688
|
-
appendTemplateInfo(info, periodStart, periodEnd, shouldFit
|
|
690
|
+
appendTemplateInfo(info, periodStart, periodEnd, shouldFit,
|
|
691
|
+
initSegmentReference) {
|
|
692
|
+
this.initSegmentReference_ = initSegmentReference;
|
|
689
693
|
if (!this.templateInfo_) {
|
|
690
694
|
this.templateInfo_ = info;
|
|
691
695
|
this.periodStart_ = periodStart;
|
|
@@ -693,6 +697,8 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
693
697
|
} else {
|
|
694
698
|
const currentTimeline = this.templateInfo_.timeline;
|
|
695
699
|
|
|
700
|
+
this.templateInfo_.mediaTemplate = info.mediaTemplate;
|
|
701
|
+
|
|
696
702
|
// Append timeline
|
|
697
703
|
const lastCurrentEntry = currentTimeline[currentTimeline.length - 1];
|
|
698
704
|
const newEntries = info.timeline.filter((entry) => {
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -1672,9 +1672,15 @@ shaka.hls.HlsParser = class {
|
|
|
1672
1672
|
// the value NONE. If the value is a quoted-string, it MUST match the
|
|
1673
1673
|
// value of the GROUP-ID attribute of an EXT-X-MEDIA tag elsewhere in the
|
|
1674
1674
|
// Playlist whose TYPE attribute is CLOSED-CAPTIONS.
|
|
1675
|
-
if (type == ContentType.VIDEO
|
|
1676
|
-
|
|
1677
|
-
|
|
1675
|
+
if (type == ContentType.VIDEO) {
|
|
1676
|
+
if (closedCaptionsAttr && closedCaptionsAttr != 'NONE') {
|
|
1677
|
+
return this.groupIdToClosedCaptionsMap_.get(closedCaptionsAttr);
|
|
1678
|
+
} else if (!closedCaptionsAttr &&
|
|
1679
|
+
this.groupIdToClosedCaptionsMap_.size) {
|
|
1680
|
+
for (const key of this.groupIdToClosedCaptionsMap_.keys()) {
|
|
1681
|
+
return this.groupIdToClosedCaptionsMap_.get(key);
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1678
1684
|
}
|
|
1679
1685
|
return null;
|
|
1680
1686
|
}
|
|
@@ -1351,6 +1351,7 @@ shaka.media.StreamingEngine = class {
|
|
|
1351
1351
|
let remaining = new Uint8Array(0);
|
|
1352
1352
|
let processingResult = false;
|
|
1353
1353
|
let callbackCalled = false;
|
|
1354
|
+
let streamDataCallbackError;
|
|
1354
1355
|
const streamDataCallback = async (data) => {
|
|
1355
1356
|
if (processingResult) {
|
|
1356
1357
|
// If the fallback result processing was triggered, don't also
|
|
@@ -1363,40 +1364,47 @@ shaka.media.StreamingEngine = class {
|
|
|
1363
1364
|
if (this.fatalError_) {
|
|
1364
1365
|
return;
|
|
1365
1366
|
}
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1367
|
+
try {
|
|
1368
|
+
// Append the data with complete boxes.
|
|
1369
|
+
// Every time streamDataCallback gets called, append the new data
|
|
1370
|
+
// to the remaining data.
|
|
1371
|
+
// Find the last fully completed Mdat box, and slice the data into
|
|
1372
|
+
// two parts: the first part with completed Mdat boxes, and the
|
|
1373
|
+
// second part with an incomplete box.
|
|
1374
|
+
// Append the first part, and save the second part as remaining
|
|
1375
|
+
// data, and handle it with the next streamDataCallback call.
|
|
1376
|
+
remaining = this.concatArray_(remaining, data);
|
|
1377
|
+
let sawMDAT = false;
|
|
1378
|
+
let offset = 0;
|
|
1379
|
+
new shaka.util.Mp4Parser()
|
|
1380
|
+
.box('mdat', (box) => {
|
|
1381
|
+
offset = box.size + box.start;
|
|
1382
|
+
sawMDAT = true;
|
|
1383
|
+
})
|
|
1384
|
+
.parse(remaining, /* partialOkay= */ false,
|
|
1385
|
+
/* isChunkedData= */ true);
|
|
1386
|
+
if (sawMDAT) {
|
|
1387
|
+
const dataToAppend = remaining.subarray(0, offset);
|
|
1388
|
+
remaining = remaining.subarray(offset);
|
|
1389
|
+
await this.append_(
|
|
1390
|
+
mediaState, presentationTime, stream, reference, dataToAppend,
|
|
1383
1391
|
/* isChunkedData= */ true);
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
/* isChunkedData= */ true);
|
|
1390
|
-
|
|
1391
|
-
if (mediaState.segmentPrefetch && mediaState.segmentIterator) {
|
|
1392
|
-
mediaState.segmentPrefetch.prefetchSegments(
|
|
1393
|
-
reference, /* skipFirst= */ true);
|
|
1392
|
+
|
|
1393
|
+
if (mediaState.segmentPrefetch && mediaState.segmentIterator) {
|
|
1394
|
+
mediaState.segmentPrefetch.prefetchSegments(
|
|
1395
|
+
reference, /* skipFirst= */ true);
|
|
1396
|
+
}
|
|
1394
1397
|
}
|
|
1398
|
+
} catch (error) {
|
|
1399
|
+
streamDataCallbackError = error;
|
|
1395
1400
|
}
|
|
1396
1401
|
};
|
|
1397
1402
|
|
|
1398
1403
|
const result =
|
|
1399
1404
|
await this.fetch_(mediaState, reference, streamDataCallback);
|
|
1405
|
+
if (streamDataCallbackError) {
|
|
1406
|
+
throw streamDataCallbackError;
|
|
1407
|
+
}
|
|
1400
1408
|
if (!callbackCalled) {
|
|
1401
1409
|
// In some environments, we might be forced to use network plugins
|
|
1402
1410
|
// that don't support streamDataCallback. In those cases, as a
|
package/lib/player.js
CHANGED
|
@@ -4595,9 +4595,13 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4595
4595
|
}
|
|
4596
4596
|
await this.addSrcTrackElement_(uri, language, kind, mimeType, label || '',
|
|
4597
4597
|
adCuePoints);
|
|
4598
|
+
|
|
4599
|
+
const LanguageUtils = shaka.util.LanguageUtils;
|
|
4600
|
+
const languageNormalized = LanguageUtils.normalize(language);
|
|
4601
|
+
|
|
4598
4602
|
const textTracks = this.getTextTracks();
|
|
4599
4603
|
const srcTrack = textTracks.find((t) => {
|
|
4600
|
-
return t.language ==
|
|
4604
|
+
return LanguageUtils.normalize(t.language) == languageNormalized &&
|
|
4601
4605
|
t.label == (label || '') &&
|
|
4602
4606
|
t.kind == kind;
|
|
4603
4607
|
});
|
|
@@ -6777,7 +6781,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
6777
6781
|
* @export
|
|
6778
6782
|
*/
|
|
6779
6783
|
// eslint-disable-next-line no-useless-concat
|
|
6780
|
-
shaka.Player.version = 'v4.6.
|
|
6784
|
+
shaka.Player.version = 'v4.6.1' + '-uncompiled'; // x-release-please-version
|
|
6781
6785
|
|
|
6782
6786
|
// Initialize the deprecation system using the version string we just set
|
|
6783
6787
|
// on the player.
|
package/package.json
CHANGED
|
@@ -750,6 +750,46 @@ describe('HlsParser', () => {
|
|
|
750
750
|
await testHlsParser(master, media, manifest);
|
|
751
751
|
});
|
|
752
752
|
|
|
753
|
+
it('parses audio+video variant with global closed captions', async () => {
|
|
754
|
+
const master = [
|
|
755
|
+
'#EXTM3U\n',
|
|
756
|
+
'#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aud1",LANGUAGE="eng",CHANNELS="2",',
|
|
757
|
+
'URI="audio"\n',
|
|
758
|
+
'#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS,GROUP-ID="cap1",LANGUAGE="eng",',
|
|
759
|
+
'INSTREAM-ID="CC1"\n',
|
|
760
|
+
'#EXT-X-STREAM-INF:BANDWIDTH=200,CODECS="avc1,mp4a",',
|
|
761
|
+
'RESOLUTION=960x540,FRAME-RATE=60,AUDIO="aud1"\n',
|
|
762
|
+
'video\n',
|
|
763
|
+
].join('');
|
|
764
|
+
|
|
765
|
+
const media = [
|
|
766
|
+
'#EXTM3U\n',
|
|
767
|
+
'#EXT-X-PLAYLIST-TYPE:VOD\n',
|
|
768
|
+
'#EXT-X-MAP:URI="init.mp4",BYTERANGE="616@0"\n',
|
|
769
|
+
'#EXTINF:5,\n',
|
|
770
|
+
'#EXT-X-BYTERANGE:121090@616\n',
|
|
771
|
+
'main.mp4',
|
|
772
|
+
].join('');
|
|
773
|
+
|
|
774
|
+
const closedCaptions = new Map([['CC1', 'en']]);
|
|
775
|
+
const manifest = shaka.test.ManifestGenerator.generate((manifest) => {
|
|
776
|
+
manifest.anyTimeline();
|
|
777
|
+
manifest.addPartialVariant((variant) => {
|
|
778
|
+
variant.addPartialStream(ContentType.VIDEO, (stream) => {
|
|
779
|
+
stream.closedCaptions = closedCaptions;
|
|
780
|
+
stream.mime('video/mp4', 'avc1');
|
|
781
|
+
});
|
|
782
|
+
variant.addPartialStream(ContentType.AUDIO, (stream) => {
|
|
783
|
+
stream.mime('audio/mp4', 'mp4a');
|
|
784
|
+
});
|
|
785
|
+
});
|
|
786
|
+
manifest.sequenceMode = sequenceMode;
|
|
787
|
+
manifest.type = shaka.media.ManifestParser.HLS;
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
await testHlsParser(master, media, manifest);
|
|
791
|
+
});
|
|
792
|
+
|
|
753
793
|
it('parses audio+video variant with no closed captions', async () => {
|
|
754
794
|
const master = [
|
|
755
795
|
'#EXTM3U\n',
|