shaka-player 4.6.0 → 4.6.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/CHANGELOG.md +23 -0
- package/demo/config.js +5 -0
- package/dist/demo.compiled.debug.js +26 -25
- package/dist/demo.compiled.debug.map +2 -2
- package/dist/demo.compiled.js +26 -25
- package/dist/demo.compiled.map +2 -2
- package/dist/locales.js +30 -30
- package/dist/shaka-player.compiled.d.ts +1 -0
- package/dist/shaka-player.compiled.debug.d.ts +1 -0
- package/dist/shaka-player.compiled.debug.externs.js +1 -0
- package/dist/shaka-player.compiled.debug.js +275 -273
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.externs.js +1 -0
- package/dist/shaka-player.compiled.js +1034 -1033
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.d.ts +1 -0
- package/dist/shaka-player.ui.debug.d.ts +1 -0
- package/dist/shaka-player.ui.debug.externs.js +1 -0
- package/dist/shaka-player.ui.debug.js +295 -293
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.externs.js +1 -0
- package/dist/shaka-player.ui.js +1172 -1171
- package/dist/shaka-player.ui.map +3 -3
- package/docs/tutorials/lcevc.md +2 -2
- package/lib/cea/cea608_memory.js +13 -2
- 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/segment_reference.js +2 -1
- package/lib/media/streaming_engine.js +36 -28
- package/lib/player.js +6 -2
- package/lib/transmuxer/ts_transmuxer.js +15 -0
- package/lib/util/error.js +6 -0
- package/package.json +2 -2
- package/test/cea/cea608_memory_unit.js +8 -8
- package/test/cea/cea_decoder_unit.js +11 -11
- package/test/demo/demo_unit.js +0 -3
- package/test/hls/hls_parser_unit.js +40 -0
- package/ui/presentation_time.js +5 -5
package/docs/tutorials/lcevc.md
CHANGED
|
@@ -24,7 +24,7 @@ LCEVC Decoder library needs to be included in the HTML page:
|
|
|
24
24
|
```
|
|
25
25
|
- Or use `unpkg.com` for latest LCEVC Decoder libraries.
|
|
26
26
|
```html
|
|
27
|
-
<script src="https://unpkg.com/lcevc_dec.js@1.0.
|
|
27
|
+
<script src="https://unpkg.com/lcevc_dec.js@1.0.1/dist/lcevc_dec.min.js"></script>
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
Configuration to enable LCEVC enhancement:
|
|
@@ -45,7 +45,7 @@ Sample setup using the Shaka Player UI library:
|
|
|
45
45
|
<link rel="stylesheet" href="dist/controls.css" />
|
|
46
46
|
|
|
47
47
|
<!-- LCEVC decoder compiled library -->
|
|
48
|
-
<script src="https://unpkg.com/lcevc_dec.js@1.0.
|
|
48
|
+
<script src="https://unpkg.com/lcevc_dec.js@1.0.1/dist/lcevc_dec.min.js"></script>
|
|
49
49
|
|
|
50
50
|
<!-- Application source: -->
|
|
51
51
|
<script src="app.js"></script>
|
package/lib/cea/cea608_memory.js
CHANGED
|
@@ -84,8 +84,10 @@ shaka.cea.Cea608Memory = class {
|
|
|
84
84
|
startTime, endTime, /* payload= */ '');
|
|
85
85
|
topLevelCue.lineInterpretation =
|
|
86
86
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
87
|
-
const
|
|
88
|
-
|
|
87
|
+
const line = shaka.cea.Cea608Memory.ROW_TO_LINE_CONVERSION_.get(this.row_);
|
|
88
|
+
if (line) {
|
|
89
|
+
topLevelCue.line = line;
|
|
90
|
+
}
|
|
89
91
|
return shaka.cea.CeaUtils.getParsedCaption(
|
|
90
92
|
topLevelCue, stream, this.rows_, startTime, endTime);
|
|
91
93
|
}
|
|
@@ -320,3 +322,12 @@ shaka.cea.Cea608Memory.CharSet.ExtendedPortugueseGerman = new Map([
|
|
|
320
322
|
[0x38, 'Å'], [0x39, 'å'], [0x3a, 'Ø'], [0x3b, 'ø'], [0x3c, '┌'], [0x3d, '┐'],
|
|
321
323
|
[0x3e, '└'], [0x3f, '┘'],
|
|
322
324
|
]);
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* @private @const {!Map<number, number>}
|
|
328
|
+
*/
|
|
329
|
+
shaka.cea.Cea608Memory.ROW_TO_LINE_CONVERSION_ = new Map([
|
|
330
|
+
[1, 10], [2, 15.33], [3, 20.66], [4, 26], [5, 31.33], [6, 36.66], [7, 42],
|
|
331
|
+
[8, 47.33], [9, 52.66], [10, 58], [11, 63.33], [12, 68.66], [13, 74],
|
|
332
|
+
[14, 79.33], [15, 84.66],
|
|
333
|
+
]);
|
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
|
}
|
|
@@ -128,7 +128,8 @@ shaka.media.InitSegmentReference = class {
|
|
|
128
128
|
} else {
|
|
129
129
|
return reference1.getStartByte() == reference2.getStartByte() &&
|
|
130
130
|
reference1.getEndByte() == reference2.getEndByte() &&
|
|
131
|
-
ArrayUtils.equal(
|
|
131
|
+
ArrayUtils.equal(
|
|
132
|
+
reference1.getUris().sort(), reference2.getUris().sort()) &&
|
|
132
133
|
BufferUtils.equal(reference1.getSegmentData(),
|
|
133
134
|
reference2.getSegmentData());
|
|
134
135
|
}
|
|
@@ -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
|
|
@@ -1784,7 +1792,7 @@ shaka.media.StreamingEngine = class {
|
|
|
1784
1792
|
reference.initSegmentReference, mediaState.lastInitSegmentReference)) {
|
|
1785
1793
|
mediaState.lastInitSegmentReference = reference.initSegmentReference;
|
|
1786
1794
|
|
|
1787
|
-
if (reference.initSegmentReference) {
|
|
1795
|
+
if (reference.isIndependent() && reference.initSegmentReference) {
|
|
1788
1796
|
shaka.log.v1(logPrefix, 'fetching init segment');
|
|
1789
1797
|
|
|
1790
1798
|
const fetchInit =
|
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.2' + '-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.
|
|
@@ -242,6 +242,9 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
} catch (e) {
|
|
245
|
+
if (e && e.code == shaka.util.Error.Code.TRANSMUXING_NO_VIDEO_DATA) {
|
|
246
|
+
return Promise.resolve(new Uint8Array([]));
|
|
247
|
+
}
|
|
245
248
|
return Promise.reject(e);
|
|
246
249
|
}
|
|
247
250
|
|
|
@@ -704,6 +707,12 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
704
707
|
|
|
705
708
|
let nalus = [];
|
|
706
709
|
const videoData = tsParser.getVideoData();
|
|
710
|
+
if (!videoData.length) {
|
|
711
|
+
throw new shaka.util.Error(
|
|
712
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
713
|
+
shaka.util.Error.Category.MEDIA,
|
|
714
|
+
shaka.util.Error.Code.TRANSMUXING_NO_VIDEO_DATA);
|
|
715
|
+
}
|
|
707
716
|
for (let i = 0; i < videoData.length; i++) {
|
|
708
717
|
const pes = videoData[i];
|
|
709
718
|
const dataNalus = pes.nalus;
|
|
@@ -790,6 +799,12 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
790
799
|
|
|
791
800
|
let nalus = [];
|
|
792
801
|
const videoData = tsParser.getVideoData();
|
|
802
|
+
if (!videoData.length) {
|
|
803
|
+
throw new shaka.util.Error(
|
|
804
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
805
|
+
shaka.util.Error.Category.MEDIA,
|
|
806
|
+
shaka.util.Error.Code.TRANSMUXING_NO_VIDEO_DATA);
|
|
807
|
+
}
|
|
793
808
|
for (let i = 0; i < videoData.length; i++) {
|
|
794
809
|
const pes = videoData[i];
|
|
795
810
|
const dataNalus = pes.nalus;
|
package/lib/util/error.js
CHANGED
|
@@ -511,6 +511,12 @@ shaka.util.Error.Code = {
|
|
|
511
511
|
*/
|
|
512
512
|
'MSS_TRANSMUXING_FAILED': 3022,
|
|
513
513
|
|
|
514
|
+
/**
|
|
515
|
+
* An internal error which indicates that transmuxing operation has no video
|
|
516
|
+
* data. This should not be seen by applications.
|
|
517
|
+
*/
|
|
518
|
+
'TRANSMUXING_NO_VIDEO_DATA': 3023,
|
|
519
|
+
|
|
514
520
|
|
|
515
521
|
/**
|
|
516
522
|
* The Player was unable to guess the manifest type based on file extension
|
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.6.
|
|
4
|
+
"version": "4.6.2",
|
|
5
5
|
"homepage": "https://github.com/shaka-project/shaka-player",
|
|
6
6
|
"author": "Google",
|
|
7
7
|
"maintainers": [
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"karma-sourcemap-loader": "^0.3.8",
|
|
49
49
|
"karma-spec-reporter": "^0.0.34",
|
|
50
50
|
"karma-webdriver-launcher": "^1.0.8",
|
|
51
|
-
"lcevc_dec.js": "^1.0.
|
|
51
|
+
"lcevc_dec.js": "^1.0.1",
|
|
52
52
|
"less": "https://gitpkg.now.sh/joeyparrish/less.js/packages/less?28c63a43",
|
|
53
53
|
"less-plugin-clean-css": "github:austingardner/less-plugin-clean-css#4e9e77bf",
|
|
54
54
|
"material-design-lite": "^1.3.0",
|
|
@@ -31,7 +31,7 @@ describe('Cea608Memory', () => {
|
|
|
31
31
|
const caption = memory.forceEmit(startTime, endTime);
|
|
32
32
|
|
|
33
33
|
const topLevelCue = new shaka.text.Cue(startTime, endTime, '');
|
|
34
|
-
topLevelCue.line =
|
|
34
|
+
topLevelCue.line = 10;
|
|
35
35
|
topLevelCue.lineInterpretation =
|
|
36
36
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
37
37
|
topLevelCue.nestedCues = [
|
|
@@ -82,7 +82,7 @@ describe('Cea608Memory', () => {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
const topLevelCue = new shaka.text.Cue(startTime, endTime, '');
|
|
85
|
-
topLevelCue.line =
|
|
85
|
+
topLevelCue.line = 10;
|
|
86
86
|
topLevelCue.lineInterpretation =
|
|
87
87
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
88
88
|
topLevelCue.nestedCues = [
|
|
@@ -119,7 +119,7 @@ describe('Cea608Memory', () => {
|
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
const topLevelCue = new shaka.text.Cue(startTime, endTime, '');
|
|
122
|
-
topLevelCue.line =
|
|
122
|
+
topLevelCue.line = 10;
|
|
123
123
|
topLevelCue.lineInterpretation =
|
|
124
124
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
125
125
|
topLevelCue.nestedCues = [
|
|
@@ -173,7 +173,7 @@ describe('Cea608Memory', () => {
|
|
|
173
173
|
// ...
|
|
174
174
|
// So we expect that test\n\ntest is emitted
|
|
175
175
|
const topLevelCue = new shaka.text.Cue(startTime, endTime, '');
|
|
176
|
-
topLevelCue.line =
|
|
176
|
+
topLevelCue.line = 36.66;
|
|
177
177
|
topLevelCue.lineInterpretation =
|
|
178
178
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
179
179
|
topLevelCue.nestedCues = [
|
|
@@ -217,7 +217,7 @@ describe('Cea608Memory', () => {
|
|
|
217
217
|
memory.eraseChar(); // Erase the last 't' from 'testt'
|
|
218
218
|
|
|
219
219
|
const topLevelCue = new shaka.text.Cue(startTime, endTime, '');
|
|
220
|
-
topLevelCue.line =
|
|
220
|
+
topLevelCue.line = 10;
|
|
221
221
|
topLevelCue.lineInterpretation =
|
|
222
222
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
223
223
|
topLevelCue.nestedCues = [
|
|
@@ -291,7 +291,7 @@ describe('Cea608Memory', () => {
|
|
|
291
291
|
|
|
292
292
|
// Expected text is 's\nt\nt\ne'
|
|
293
293
|
const topLevelCue = new shaka.text.Cue(startTime, endTime, '');
|
|
294
|
-
topLevelCue.line = 31.
|
|
294
|
+
topLevelCue.line = 31.33;
|
|
295
295
|
topLevelCue.lineInterpretation =
|
|
296
296
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
297
297
|
topLevelCue.nestedCues = [
|
|
@@ -338,7 +338,7 @@ describe('Cea608Memory', () => {
|
|
|
338
338
|
|
|
339
339
|
// Expected text is 't\ne\ns\nt'
|
|
340
340
|
const topLevelCue = new shaka.text.Cue(startTime, endTime, '');
|
|
341
|
-
topLevelCue.line = 31.
|
|
341
|
+
topLevelCue.line = 31.33;
|
|
342
342
|
topLevelCue.lineInterpretation =
|
|
343
343
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
344
344
|
topLevelCue.nestedCues = [
|
|
@@ -385,7 +385,7 @@ describe('Cea608Memory', () => {
|
|
|
385
385
|
|
|
386
386
|
// Expected text is 't\ne\ns\nt'
|
|
387
387
|
const topLevelCue = new shaka.text.Cue(startTime, endTime, '');
|
|
388
|
-
topLevelCue.line = 31.
|
|
388
|
+
topLevelCue.line = 31.33;
|
|
389
389
|
topLevelCue.lineInterpretation =
|
|
390
390
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
391
391
|
topLevelCue.nestedCues = [
|
|
@@ -65,7 +65,7 @@ describe('CeaDecoder', () => {
|
|
|
65
65
|
|
|
66
66
|
const topLevelCue = new shaka.text.Cue(
|
|
67
67
|
startTimeCaption1, startTimeCaption2, '');
|
|
68
|
-
topLevelCue.line =
|
|
68
|
+
topLevelCue.line = 74;
|
|
69
69
|
topLevelCue.lineInterpretation =
|
|
70
70
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
71
71
|
topLevelCue.nestedCues = [
|
|
@@ -113,7 +113,7 @@ describe('CeaDecoder', () => {
|
|
|
113
113
|
// Since there are three style changes, there should be three nested cues.
|
|
114
114
|
const topLevelCue = new shaka.text.Cue(
|
|
115
115
|
startTimeCaption1, startTimeCaption2, '');
|
|
116
|
-
topLevelCue.line =
|
|
116
|
+
topLevelCue.line = 10;
|
|
117
117
|
topLevelCue.lineInterpretation =
|
|
118
118
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
119
119
|
|
|
@@ -166,7 +166,7 @@ describe('CeaDecoder', () => {
|
|
|
166
166
|
// A single nested cue containing yellow, italicized text.
|
|
167
167
|
const topLevelCue = new shaka.text.Cue(startTimeCaption1,
|
|
168
168
|
startTimeCaption2, '');
|
|
169
|
-
topLevelCue.line =
|
|
169
|
+
topLevelCue.line = 15.33;
|
|
170
170
|
topLevelCue.lineInterpretation =
|
|
171
171
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
172
172
|
topLevelCue.nestedCues = [
|
|
@@ -208,7 +208,7 @@ describe('CeaDecoder', () => {
|
|
|
208
208
|
|
|
209
209
|
const topLevelCue = new shaka.text.Cue(startTimeCaption1,
|
|
210
210
|
startTimeCaption2, '');
|
|
211
|
-
topLevelCue.line =
|
|
211
|
+
topLevelCue.line = 10;
|
|
212
212
|
topLevelCue.lineInterpretation =
|
|
213
213
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
214
214
|
topLevelCue.nestedCues = [
|
|
@@ -243,7 +243,7 @@ describe('CeaDecoder', () => {
|
|
|
243
243
|
|
|
244
244
|
const topLevelCue = new shaka.text.Cue(startTimeCaption1,
|
|
245
245
|
startTimeCaption2, '');
|
|
246
|
-
topLevelCue.line =
|
|
246
|
+
topLevelCue.line = 10;
|
|
247
247
|
topLevelCue.lineInterpretation =
|
|
248
248
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
249
249
|
topLevelCue.nestedCues = [
|
|
@@ -315,7 +315,7 @@ describe('CeaDecoder', () => {
|
|
|
315
315
|
// Top level cue corresponding to the first closed caption.
|
|
316
316
|
const topLevelCue1 = new shaka.text.Cue(
|
|
317
317
|
/* startTime= */ time1, /* endTime= */ time2, '');
|
|
318
|
-
topLevelCue1.line =
|
|
318
|
+
topLevelCue1.line = 84.66;
|
|
319
319
|
topLevelCue1.lineInterpretation =
|
|
320
320
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
321
321
|
topLevelCue1.nestedCues = [
|
|
@@ -326,7 +326,7 @@ describe('CeaDecoder', () => {
|
|
|
326
326
|
// Top level cue corresponding to the second closed caption.
|
|
327
327
|
const topLevelCue2 = new shaka.text.Cue(
|
|
328
328
|
/* startTime= */ time2, /* endTime= */ time3, '');
|
|
329
|
-
topLevelCue2.line =
|
|
329
|
+
topLevelCue2.line = 84.66;
|
|
330
330
|
topLevelCue2.lineInterpretation =
|
|
331
331
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
332
332
|
topLevelCue2.nestedCues = [
|
|
@@ -343,7 +343,7 @@ describe('CeaDecoder', () => {
|
|
|
343
343
|
// Top level cue corresponding to the third closed caption.
|
|
344
344
|
const topLevelCue3 = new shaka.text.Cue(
|
|
345
345
|
/* startTime= */ time3, /* endTime= */ time4, '');
|
|
346
|
-
topLevelCue3.line =
|
|
346
|
+
topLevelCue3.line = 84.66;
|
|
347
347
|
topLevelCue3.lineInterpretation =
|
|
348
348
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
349
349
|
topLevelCue3.nestedCues = [
|
|
@@ -360,7 +360,7 @@ describe('CeaDecoder', () => {
|
|
|
360
360
|
// Top level cue corresponding to the fourth closed caption.
|
|
361
361
|
const topLevelCue4 = new shaka.text.Cue(
|
|
362
362
|
/* startTime= */ time4, /* endTime= */ time5, '');
|
|
363
|
-
topLevelCue4.line =
|
|
363
|
+
topLevelCue4.line = 84.66;
|
|
364
364
|
topLevelCue4.lineInterpretation =
|
|
365
365
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
366
366
|
topLevelCue4.nestedCues = [
|
|
@@ -433,7 +433,7 @@ describe('CeaDecoder', () => {
|
|
|
433
433
|
// Top level cue corresponding to the first closed caption.
|
|
434
434
|
const topLevelCue1 = new shaka.text.Cue(/* startTime= */ 1,
|
|
435
435
|
/* endTime= */ 2, '');
|
|
436
|
-
topLevelCue1.line =
|
|
436
|
+
topLevelCue1.line = 84.66;
|
|
437
437
|
topLevelCue1.lineInterpretation =
|
|
438
438
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
439
439
|
topLevelCue1.nestedCues = [
|
|
@@ -444,7 +444,7 @@ describe('CeaDecoder', () => {
|
|
|
444
444
|
// Top level cue corresponding to the second closed caption.
|
|
445
445
|
const topLevelCue2 = new shaka.text.Cue(/* startTime= */ 2,
|
|
446
446
|
/* endTime= */ 3, '');
|
|
447
|
-
topLevelCue2.line =
|
|
447
|
+
topLevelCue2.line = 26;
|
|
448
448
|
topLevelCue2.lineInterpretation =
|
|
449
449
|
shaka.text.Cue.lineInterpretation.PERCENTAGE;
|
|
450
450
|
topLevelCue2.nestedCues = [
|
package/test/demo/demo_unit.js
CHANGED
|
@@ -74,14 +74,11 @@ describe('Demo', () => {
|
|
|
74
74
|
function checkConfig(checkValueNameFn) {
|
|
75
75
|
const configPrimitives = new Set(['number', 'string', 'boolean']);
|
|
76
76
|
const exceptions = new Set()
|
|
77
|
-
.add('preferredVariantRole')
|
|
78
77
|
.add('playRangeStart')
|
|
79
78
|
.add('playRangeEnd')
|
|
80
79
|
.add('manifest.dash.keySystemsByURI')
|
|
81
|
-
.add('manifest.hls.mediaPlaylistFullMimeType')
|
|
82
80
|
.add('manifest.mss.keySystemsBySystemId')
|
|
83
81
|
.add('drm.keySystemsMapping')
|
|
84
|
-
.add('streaming.parsePrftBox')
|
|
85
82
|
.add('manifest.raiseFatalErrorOnManifestUpdateRequestFailure')
|
|
86
83
|
.add('drm.persistentSessionOnlinePlayback')
|
|
87
84
|
.add('drm.persistentSessionsMetadata');
|
|
@@ -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',
|
package/ui/presentation_time.js
CHANGED
|
@@ -64,7 +64,6 @@ shaka.ui.PresentationTimeTracker = class extends shaka.ui.Element {
|
|
|
64
64
|
updateTime_() {
|
|
65
65
|
const isSeeking = this.controls.isSeeking();
|
|
66
66
|
let displayTime = this.controls.getDisplayTime();
|
|
67
|
-
const duration = this.video.duration;
|
|
68
67
|
const seekRange = this.player.seekRange();
|
|
69
68
|
const seekRangeSize = seekRange.end - seekRange.start;
|
|
70
69
|
const Utils = shaka.ui.Utils;
|
|
@@ -89,11 +88,12 @@ shaka.ui.PresentationTimeTracker = class extends shaka.ui.Element {
|
|
|
89
88
|
this.currentTime_.disabled = true;
|
|
90
89
|
}
|
|
91
90
|
} else {
|
|
92
|
-
const showHour =
|
|
91
|
+
const showHour = seekRangeSize >= 3600;
|
|
93
92
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
const currentTime = Math.max(0, displayTime - seekRange.start);
|
|
94
|
+
let value = Utils.buildTimeString(currentTime, showHour);
|
|
95
|
+
if (seekRangeSize) {
|
|
96
|
+
value += ' / ' + Utils.buildTimeString(seekRangeSize, showHour);
|
|
97
97
|
}
|
|
98
98
|
this.setValue_(value);
|
|
99
99
|
this.currentTime_.disabled = true;
|