shaka-player 4.4.1 → 4.4.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/.github/workflows/deflake.yaml +8 -5
- package/.github/workflows/release-please.yaml +47 -7
- package/.github/workflows/shaka-bot-commands/command-test.sh +1 -1
- package/CHANGELOG.md +20 -0
- package/CONTRIBUTORS +1 -0
- package/demo/custom.js +5 -5
- package/dist/demo.compiled.debug.js +3 -3
- package/dist/demo.compiled.debug.map +1 -1
- package/dist/demo.compiled.js +3 -3
- package/dist/demo.compiled.map +1 -1
- package/dist/deps.js +2 -2
- package/dist/locales.js +31 -31
- package/dist/shaka-player.compiled.d.ts +311 -295
- package/dist/shaka-player.compiled.debug.d.ts +311 -295
- package/dist/shaka-player.compiled.debug.externs.js +37 -0
- package/dist/shaka-player.compiled.debug.js +145 -135
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.externs.js +37 -0
- package/dist/shaka-player.compiled.js +887 -884
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +355 -339
- package/dist/shaka-player.ui.debug.d.ts +355 -339
- package/dist/shaka-player.ui.debug.externs.js +37 -0
- package/dist/shaka-player.ui.debug.js +161 -151
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.externs.js +37 -0
- package/dist/shaka-player.ui.js +968 -967
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/fairplay.md +8 -0
- package/docs/tutorials/faq.md +1 -1
- package/externs/shaka/text.js +7 -0
- package/lib/dash/segment_template.js +3 -0
- package/lib/hls/hls_parser.js +8 -4
- package/lib/media/media_source_engine.js +1 -1
- package/lib/player.js +8 -57
- package/lib/text/lrc_text_parser.js +8 -0
- package/lib/text/mp4_ttml_parser.js +8 -0
- package/lib/text/mp4_vtt_parser.js +8 -0
- package/lib/text/sbv_text_parser.js +8 -0
- package/lib/text/srt_text_parser.js +8 -0
- package/lib/text/ssa_text_parser.js +8 -0
- package/lib/text/text_engine.js +8 -1
- package/lib/text/ttml_text_parser.js +10 -1
- package/lib/text/ui_text_displayer.js +49 -3
- package/lib/text/vtt_text_parser.js +21 -5
- package/lib/transmuxer/ts_transmuxer.js +44 -43
- package/lib/util/error.js +16 -10
- package/lib/util/player_configuration.js +2 -2
- package/lib/util/stream_utils.js +13 -11
- package/lib/util/ts_parser.js +70 -13
- package/package.json +2 -2
- package/test/text/text_engine_unit.js +4 -2
- package/test/text/ttml_text_parser_unit.js +3 -4
- package/test/text/vtt_text_parser_unit.js +17 -2
- package/test/text/web_vtt_layout_integration.js +0 -1
- package/ui/language_utils.js +0 -15
|
@@ -232,3 +232,11 @@ player.getNetworkingEngine()
|
|
|
232
232
|
player.configure('drm.initDataTransform',
|
|
233
233
|
FairPlayUtils.expressplayInitDataTransform);
|
|
234
234
|
```
|
|
235
|
+
|
|
236
|
+
#### Nagra (legacy Apple Media Keys)
|
|
237
|
+
|
|
238
|
+
For integration with Nagra the following can be used:
|
|
239
|
+
|
|
240
|
+
```js
|
|
241
|
+
shaka.polyfill.PatchedMediaKeysApple.install();
|
|
242
|
+
```
|
package/docs/tutorials/faq.md
CHANGED
|
@@ -153,7 +153,7 @@ In other environments, for example Electron, it is appropriate.
|
|
|
153
153
|
In those cases, before Shaka Player loads a manifest, you can register the
|
|
154
154
|
existing http plugin for `file://` requests:
|
|
155
155
|
```js
|
|
156
|
-
shaka.net.NetworkingEngine.registerScheme('file', shaka.net.HttpXHRPlugin);
|
|
156
|
+
shaka.net.NetworkingEngine.registerScheme('file', shaka.net.HttpXHRPlugin.parse);
|
|
157
157
|
```
|
|
158
158
|
|
|
159
159
|
<hr>
|
package/externs/shaka/text.js
CHANGED
|
@@ -868,6 +868,9 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
868
868
|
.unscaledPresentationTimeOffset + range.unscaledStart;
|
|
869
869
|
|
|
870
870
|
const createUrisCb = () => {
|
|
871
|
+
if (!this.templateInfo_) {
|
|
872
|
+
return [];
|
|
873
|
+
}
|
|
871
874
|
return shaka.dash.TimelineSegmentIndex
|
|
872
875
|
.createUris_(
|
|
873
876
|
this.templateInfo_.mediaTemplate,
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -900,6 +900,7 @@ shaka.hls.HlsParser = class {
|
|
|
900
900
|
const uint8ArrayData = shaka.util.BufferUtils.toUint8(response.data);
|
|
901
901
|
const tsParser = new shaka.util.TsParser().parse(uint8ArrayData);
|
|
902
902
|
const tsCodecs = tsParser.getCodecs();
|
|
903
|
+
const videoInfo = tsParser.getVideoInfo();
|
|
903
904
|
const codecs = [];
|
|
904
905
|
let hasAudio = false;
|
|
905
906
|
let hasVideo = false;
|
|
@@ -923,7 +924,11 @@ shaka.hls.HlsParser = class {
|
|
|
923
924
|
}
|
|
924
925
|
switch (tsCodecs.video) {
|
|
925
926
|
case 'avc':
|
|
926
|
-
|
|
927
|
+
if (videoInfo.codec) {
|
|
928
|
+
codecs.push(videoInfo.codec);
|
|
929
|
+
} else {
|
|
930
|
+
codecs.push('avc1.42E01E');
|
|
931
|
+
}
|
|
927
932
|
hasVideo = true;
|
|
928
933
|
break;
|
|
929
934
|
case 'hvc':
|
|
@@ -935,14 +940,13 @@ shaka.hls.HlsParser = class {
|
|
|
935
940
|
return null;
|
|
936
941
|
}
|
|
937
942
|
const onlyAudio = hasAudio && !hasVideo;
|
|
938
|
-
const videoResolution = tsParser.getVideoResolution();
|
|
939
943
|
return {
|
|
940
944
|
type: onlyAudio ? 'audio' : 'video',
|
|
941
945
|
mimeType: 'video/mp2t',
|
|
942
946
|
codecs: codecs.join(', '),
|
|
943
947
|
language: null,
|
|
944
|
-
height:
|
|
945
|
-
width:
|
|
948
|
+
height: videoInfo.height,
|
|
949
|
+
width: videoInfo.width,
|
|
946
950
|
channelCount: null,
|
|
947
951
|
sampleRate: null,
|
|
948
952
|
};
|
|
@@ -492,7 +492,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
492
492
|
this.textEngine_ = new shaka.text.TextEngine(this.textDisplayer_);
|
|
493
493
|
}
|
|
494
494
|
this.textEngine_.initParser(mimeType, sequenceMode,
|
|
495
|
-
external || this.segmentRelativeVttTiming_);
|
|
495
|
+
external || this.segmentRelativeVttTiming_, this.manifestType_);
|
|
496
496
|
}
|
|
497
497
|
|
|
498
498
|
/**
|
package/lib/player.js
CHANGED
|
@@ -2663,16 +2663,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2663
2663
|
return;
|
|
2664
2664
|
}
|
|
2665
2665
|
|
|
2666
|
-
this.selectAudioLanguage(preferredAudioLanguage);
|
|
2667
|
-
|
|
2668
2666
|
const preferredVariantRole = this.config_.preferredVariantRole;
|
|
2669
|
-
|
|
2670
|
-
// If the user has not selected a role preference, the previous match is
|
|
2671
|
-
// selected.
|
|
2672
|
-
if (preferredVariantRole == '') {
|
|
2673
|
-
return;
|
|
2674
|
-
}
|
|
2675
|
-
|
|
2676
2667
|
this.selectAudioLanguage(preferredAudioLanguage, preferredVariantRole);
|
|
2677
2668
|
}
|
|
2678
2669
|
|
|
@@ -2683,7 +2674,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2683
2674
|
*/
|
|
2684
2675
|
setupPreferredTextOnSrc_() {
|
|
2685
2676
|
const preferredTextLanguage = this.config_.preferredTextLanguage;
|
|
2686
|
-
const preferForcedSubs = this.config_.preferForcedSubs;
|
|
2687
2677
|
|
|
2688
2678
|
// If the user has not selected a preference, the browser preference is
|
|
2689
2679
|
// left.
|
|
@@ -2691,16 +2681,9 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2691
2681
|
return;
|
|
2692
2682
|
}
|
|
2693
2683
|
|
|
2694
|
-
this.
|
|
2695
|
-
|
|
2684
|
+
const preferForcedSubs = this.config_.preferForcedSubs;
|
|
2696
2685
|
const preferredTextRole = this.config_.preferredTextRole;
|
|
2697
2686
|
|
|
2698
|
-
// If the user has not selected a role preference, the previous match is
|
|
2699
|
-
// selected.
|
|
2700
|
-
if (preferredTextRole == '') {
|
|
2701
|
-
return;
|
|
2702
|
-
}
|
|
2703
|
-
|
|
2704
2687
|
this.selectTextLanguage(preferredTextLanguage, preferredTextRole,
|
|
2705
2688
|
preferForcedSubs);
|
|
2706
2689
|
}
|
|
@@ -4199,8 +4182,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4199
4182
|
* @export
|
|
4200
4183
|
*/
|
|
4201
4184
|
selectAudioLanguage(language, role, channelsCount = 0, safeMargin = 0) {
|
|
4202
|
-
const LanguageUtils = shaka.util.LanguageUtils;
|
|
4203
|
-
|
|
4204
4185
|
if (this.manifest_ && this.playhead_) {
|
|
4205
4186
|
this.currentAdaptationSetCriteria_ =
|
|
4206
4187
|
new shaka.media.PreferenceBasedCriteria(language, role || '',
|
|
@@ -4238,33 +4219,10 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4238
4219
|
// If we haven't switched yet, just use ABR to find a new track.
|
|
4239
4220
|
this.chooseVariantAndSwitch_();
|
|
4240
4221
|
} else if (this.video_ && this.video_.audioTracks) {
|
|
4241
|
-
const
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
let languageAndRoleMatch = null;
|
|
4246
|
-
|
|
4247
|
-
for (const audioTrack of audioTracks) {
|
|
4248
|
-
const track = shaka.util.StreamUtils.html5AudioTrackToTrack(audioTrack);
|
|
4249
|
-
|
|
4250
|
-
if (LanguageUtils.normalize(track.language) == selectedLanguage) {
|
|
4251
|
-
languageMatch = audioTrack;
|
|
4252
|
-
|
|
4253
|
-
if (role) {
|
|
4254
|
-
if (track.roles.includes(role)) {
|
|
4255
|
-
languageAndRoleMatch = audioTrack;
|
|
4256
|
-
}
|
|
4257
|
-
} else { // no role
|
|
4258
|
-
if (track.roles.length == 0) {
|
|
4259
|
-
languageAndRoleMatch = audioTrack;
|
|
4260
|
-
}
|
|
4261
|
-
}
|
|
4262
|
-
}
|
|
4263
|
-
}
|
|
4264
|
-
if (languageAndRoleMatch) {
|
|
4265
|
-
this.switchHtml5Track_(languageAndRoleMatch);
|
|
4266
|
-
} else if (languageMatch) {
|
|
4267
|
-
this.switchHtml5Track_(languageMatch);
|
|
4222
|
+
const track = shaka.util.StreamUtils.filterStreamsByLanguageAndRole(
|
|
4223
|
+
this.getVariantTracks(), language, role || '', false)[0];
|
|
4224
|
+
if (track) {
|
|
4225
|
+
this.selectVariantTrack(track);
|
|
4268
4226
|
}
|
|
4269
4227
|
}
|
|
4270
4228
|
}
|
|
@@ -4280,8 +4238,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4280
4238
|
* @export
|
|
4281
4239
|
*/
|
|
4282
4240
|
selectTextLanguage(language, role, forced = false) {
|
|
4283
|
-
const LanguageUtils = shaka.util.LanguageUtils;
|
|
4284
|
-
|
|
4285
4241
|
if (this.manifest_ && this.playhead_) {
|
|
4286
4242
|
this.currentTextLanguage_ = language;
|
|
4287
4243
|
this.currentTextRole_ = role || '';
|
|
@@ -4302,13 +4258,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4302
4258
|
}
|
|
4303
4259
|
}
|
|
4304
4260
|
} else {
|
|
4305
|
-
const
|
|
4306
|
-
|
|
4307
|
-
const track = this.getTextTracks().find((t) => {
|
|
4308
|
-
return LanguageUtils.normalize(t.language) == selectedLanguage &&
|
|
4309
|
-
(!role || t.roles.includes(role)) && t.forced == forced;
|
|
4310
|
-
});
|
|
4311
|
-
|
|
4261
|
+
const track = shaka.util.StreamUtils.filterStreamsByLanguageAndRole(
|
|
4262
|
+
this.getTextTracks(), language, role || '', forced)[0];
|
|
4312
4263
|
if (track) {
|
|
4313
4264
|
this.selectTextTrack(track);
|
|
4314
4265
|
}
|
|
@@ -7224,7 +7175,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
7224
7175
|
* @define {string} A version number taken from git at compile time.
|
|
7225
7176
|
* @export
|
|
7226
7177
|
*/
|
|
7227
|
-
shaka.Player.version = 'v4.4.
|
|
7178
|
+
shaka.Player.version = 'v4.4.2-uncompiled';
|
|
7228
7179
|
|
|
7229
7180
|
// Initialize the deprecation system using the version string we just set
|
|
7230
7181
|
// on the player.
|
package/lib/text/text_engine.js
CHANGED
|
@@ -132,8 +132,9 @@ shaka.text.TextEngine = class {
|
|
|
132
132
|
* @param {string} mimeType
|
|
133
133
|
* @param {boolean} sequenceMode
|
|
134
134
|
* @param {boolean} segmentRelativeVttTiming
|
|
135
|
+
* @param {string} manifestType
|
|
135
136
|
*/
|
|
136
|
-
initParser(mimeType, sequenceMode, segmentRelativeVttTiming) {
|
|
137
|
+
initParser(mimeType, sequenceMode, segmentRelativeVttTiming, manifestType) {
|
|
137
138
|
// No parser for CEA, which is extracted from video and side-loaded
|
|
138
139
|
// into TextEngine and TextDisplayer.
|
|
139
140
|
if (mimeType == shaka.util.MimeUtils.CEA608_CLOSED_CAPTION_MIMETYPE ||
|
|
@@ -152,6 +153,12 @@ shaka.text.TextEngine = class {
|
|
|
152
153
|
shaka.log.alwaysWarn(
|
|
153
154
|
'Text parsers should have a "setSequenceMode" method!');
|
|
154
155
|
}
|
|
156
|
+
if (this.parser_.setManifestType) {
|
|
157
|
+
this.parser_.setManifestType(manifestType);
|
|
158
|
+
} else {
|
|
159
|
+
shaka.log.alwaysWarn(
|
|
160
|
+
'Text parsers should have a "setManifestType" method!');
|
|
161
|
+
}
|
|
155
162
|
this.segmentRelativeVttTiming_ = segmentRelativeVttTiming;
|
|
156
163
|
}
|
|
157
164
|
|
|
@@ -38,6 +38,14 @@ shaka.text.TtmlTextParser = class {
|
|
|
38
38
|
// Unused.
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* @override
|
|
43
|
+
* @export
|
|
44
|
+
*/
|
|
45
|
+
setManifestType(manifestType) {
|
|
46
|
+
// Unused.
|
|
47
|
+
}
|
|
48
|
+
|
|
41
49
|
/**
|
|
42
50
|
* @override
|
|
43
51
|
* @export
|
|
@@ -214,11 +222,12 @@ shaka.text.TtmlTextParser = class {
|
|
|
214
222
|
}
|
|
215
223
|
}
|
|
216
224
|
|
|
217
|
-
const parentIsContent = isContent;
|
|
218
225
|
if (cueNode.nodeName == 'p' || imageElement) {
|
|
219
226
|
isContent = true;
|
|
220
227
|
}
|
|
221
228
|
|
|
229
|
+
const parentIsContent = isContent;
|
|
230
|
+
|
|
222
231
|
const spaceStyle = cueElement.getAttribute('xml:space') ||
|
|
223
232
|
(whitespaceTrim ? 'default' : 'preserve');
|
|
224
233
|
|
|
@@ -481,6 +481,43 @@ shaka.text.UITextDisplayer = class {
|
|
|
481
481
|
this.currentCuesMap_.set(cue, {cueElement, wrapper, regionElement});
|
|
482
482
|
}
|
|
483
483
|
|
|
484
|
+
/**
|
|
485
|
+
* Compute cue position alignment
|
|
486
|
+
* See https://www.w3.org/TR/webvtt1/#webvtt-cue-position-alignment
|
|
487
|
+
*
|
|
488
|
+
* @param {!shaka.text.Cue} cue
|
|
489
|
+
* @private
|
|
490
|
+
*/
|
|
491
|
+
computeCuePositionAlignment_(cue) {
|
|
492
|
+
const Cue = shaka.text.Cue;
|
|
493
|
+
const {direction, positionAlign, textAlign} = cue;
|
|
494
|
+
|
|
495
|
+
if (positionAlign !== Cue.positionAlign.AUTO) {
|
|
496
|
+
// Position align is not AUTO: use it
|
|
497
|
+
return positionAlign;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// Position align is AUTO: use text align to compute its value
|
|
501
|
+
|
|
502
|
+
if (textAlign === Cue.textAlign.LEFT ||
|
|
503
|
+
(textAlign === Cue.textAlign.START &&
|
|
504
|
+
direction === Cue.direction.HORIZONTAL_LEFT_TO_RIGHT) ||
|
|
505
|
+
(textAlign === Cue.textAlign.END &&
|
|
506
|
+
direction === Cue.direction.HORIZONTAL_RIGHT_TO_LEFT)) {
|
|
507
|
+
return Cue.positionAlign.LEFT;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (textAlign === Cue.textAlign.RIGHT ||
|
|
511
|
+
(textAlign === Cue.textAlign.START &&
|
|
512
|
+
direction === Cue.direction.HORIZONTAL_RIGHT_TO_LEFT) ||
|
|
513
|
+
(textAlign === Cue.textAlign.END &&
|
|
514
|
+
direction === Cue.direction.HORIZONTAL_LEFT_TO_RIGHT)) {
|
|
515
|
+
return Cue.positionAlign.RIGHT;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
return Cue.positionAlign.CENTER;
|
|
519
|
+
}
|
|
520
|
+
|
|
484
521
|
/**
|
|
485
522
|
* @param {!HTMLElement} cueElement
|
|
486
523
|
* @param {!shaka.text.Cue} cue
|
|
@@ -617,7 +654,15 @@ shaka.text.UITextDisplayer = class {
|
|
|
617
654
|
// TODO: Implement line alignment with line number.
|
|
618
655
|
// TODO: Implement lineAlignment of 'CENTER'.
|
|
619
656
|
if (cue.line != null) {
|
|
620
|
-
|
|
657
|
+
let lineInterpretation = cue.lineInterpretation;
|
|
658
|
+
// HACK: the current implementation of UITextDisplayer only handled
|
|
659
|
+
// PERCENTAGE, as cue.line=0 is zero, we can interpret it as percentage
|
|
660
|
+
// safely.
|
|
661
|
+
if (cue.line == 0 &&
|
|
662
|
+
lineInterpretation == Cue.lineInterpretation.LINE_NUMBER) {
|
|
663
|
+
lineInterpretation = Cue.lineInterpretation.PERCENTAGE;
|
|
664
|
+
}
|
|
665
|
+
if (lineInterpretation == Cue.lineInterpretation.PERCENTAGE) {
|
|
621
666
|
style.position = 'absolute';
|
|
622
667
|
if (cue.writingMode == Cue.writingMode.HORIZONTAL_TOP_TO_BOTTOM) {
|
|
623
668
|
style.width = '100%';
|
|
@@ -658,9 +703,10 @@ shaka.text.UITextDisplayer = class {
|
|
|
658
703
|
|
|
659
704
|
// The positionAlign attribute is an alignment for the text container in
|
|
660
705
|
// the dimension of the writing direction.
|
|
661
|
-
|
|
706
|
+
const computedPositionAlign = this.computeCuePositionAlignment_(cue);
|
|
707
|
+
if (computedPositionAlign == Cue.positionAlign.LEFT) {
|
|
662
708
|
style.cssFloat = 'left';
|
|
663
|
-
} else if (
|
|
709
|
+
} else if (computedPositionAlign == Cue.positionAlign.RIGHT) {
|
|
664
710
|
style.cssFloat = 'right';
|
|
665
711
|
}
|
|
666
712
|
|
|
@@ -8,6 +8,7 @@ goog.provide('shaka.text.VttTextParser');
|
|
|
8
8
|
|
|
9
9
|
goog.require('goog.asserts');
|
|
10
10
|
goog.require('shaka.log');
|
|
11
|
+
goog.require('shaka.media.ManifestParser');
|
|
11
12
|
goog.require('shaka.text.Cue');
|
|
12
13
|
goog.require('shaka.text.CueRegion');
|
|
13
14
|
goog.require('shaka.text.TextEngine');
|
|
@@ -26,6 +27,9 @@ shaka.text.VttTextParser = class {
|
|
|
26
27
|
constructor() {
|
|
27
28
|
/** @private {boolean} */
|
|
28
29
|
this.sequenceMode_ = false;
|
|
30
|
+
|
|
31
|
+
/** @private {string} */
|
|
32
|
+
this.manifestType_ = shaka.media.ManifestParser.UNKNOWN;
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
/**
|
|
@@ -44,6 +48,14 @@ shaka.text.VttTextParser = class {
|
|
|
44
48
|
this.sequenceMode_ = sequenceMode;
|
|
45
49
|
}
|
|
46
50
|
|
|
51
|
+
/**
|
|
52
|
+
* @override
|
|
53
|
+
* @export
|
|
54
|
+
*/
|
|
55
|
+
setManifestType(manifestType) {
|
|
56
|
+
this.manifestType_ = manifestType;
|
|
57
|
+
}
|
|
58
|
+
|
|
47
59
|
/**
|
|
48
60
|
* @override
|
|
49
61
|
* @export
|
|
@@ -72,10 +84,9 @@ shaka.text.VttTextParser = class {
|
|
|
72
84
|
// HLS content, which should use X-TIMESTAMP-MAP and periodStart instead.
|
|
73
85
|
let offset = time.vttOffset;
|
|
74
86
|
|
|
75
|
-
// Only use 'X-TIMESTAMP-MAP' in sequence mode
|
|
76
|
-
//
|
|
87
|
+
// Only use 'X-TIMESTAMP-MAP' in sequence mode.
|
|
88
|
+
// Note that an offset based on the first video
|
|
77
89
|
// timestamp has already been extracted, and appears in periodStart.
|
|
78
|
-
// The relative offset from X-TIMESTAMP-MAP will be added to that for HLS.
|
|
79
90
|
if (blocks[0].includes('X-TIMESTAMP-MAP') && this.sequenceMode_) {
|
|
80
91
|
// https://bit.ly/2K92l7y
|
|
81
92
|
// The 'X-TIMESTAMP-MAP' header is used in HLS to align text with
|
|
@@ -113,6 +124,11 @@ shaka.text.VttTextParser = class {
|
|
|
113
124
|
|
|
114
125
|
offset = time.periodStart + mpegTime / mpegTimescale - cueTime;
|
|
115
126
|
}
|
|
127
|
+
} else if (blocks[0].includes('X-TIMESTAMP-MAP') &&
|
|
128
|
+
this.manifestType_ == shaka.media.ManifestParser.HLS) {
|
|
129
|
+
// In we use HLS segments mode, with the presence of this tag we need
|
|
130
|
+
// calculate the offset from the segment startTime.
|
|
131
|
+
offset = time.segmentStart;
|
|
116
132
|
}
|
|
117
133
|
|
|
118
134
|
// Parse VTT regions.
|
|
@@ -401,8 +417,6 @@ shaka.text.VttTextParser = class {
|
|
|
401
417
|
cue = new shaka.text.Cue(start, end, '');
|
|
402
418
|
}
|
|
403
419
|
|
|
404
|
-
VttTextParser.parseCueStyles(payload, cue, styles);
|
|
405
|
-
|
|
406
420
|
// Parse optional settings.
|
|
407
421
|
parser.skipWhitespace();
|
|
408
422
|
let word = parser.readWord();
|
|
@@ -416,6 +430,8 @@ shaka.text.VttTextParser = class {
|
|
|
416
430
|
word = parser.readWord();
|
|
417
431
|
}
|
|
418
432
|
|
|
433
|
+
VttTextParser.parseCueStyles(payload, cue, styles);
|
|
434
|
+
|
|
419
435
|
if (id != null) {
|
|
420
436
|
cue.id = id;
|
|
421
437
|
}
|