shaka-player 4.3.11 → 4.3.12

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.
@@ -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/lib/player.js CHANGED
@@ -2651,16 +2651,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
2651
2651
  return;
2652
2652
  }
2653
2653
 
2654
- this.selectAudioLanguage(preferredAudioLanguage);
2655
-
2656
2654
  const preferredVariantRole = this.config_.preferredVariantRole;
2657
-
2658
- // If the user has not selected a role preference, the previous match is
2659
- // selected.
2660
- if (preferredVariantRole == '') {
2661
- return;
2662
- }
2663
-
2664
2655
  this.selectAudioLanguage(preferredAudioLanguage, preferredVariantRole);
2665
2656
  }
2666
2657
 
@@ -2671,7 +2662,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
2671
2662
  */
2672
2663
  setupPreferredTextOnSrc_() {
2673
2664
  const preferredTextLanguage = this.config_.preferredTextLanguage;
2674
- const preferForcedSubs = this.config_.preferForcedSubs;
2675
2665
 
2676
2666
  // If the user has not selected a preference, the browser preference is
2677
2667
  // left.
@@ -2679,16 +2669,9 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
2679
2669
  return;
2680
2670
  }
2681
2671
 
2682
- this.selectTextLanguage(preferredTextLanguage, '', preferForcedSubs);
2683
-
2672
+ const preferForcedSubs = this.config_.preferForcedSubs;
2684
2673
  const preferredTextRole = this.config_.preferredTextRole;
2685
2674
 
2686
- // If the user has not selected a role preference, the previous match is
2687
- // selected.
2688
- if (preferredTextRole == '') {
2689
- return;
2690
- }
2691
-
2692
2675
  this.selectTextLanguage(preferredTextLanguage, preferredTextRole,
2693
2676
  preferForcedSubs);
2694
2677
  }
@@ -4141,8 +4124,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
4141
4124
  * @export
4142
4125
  */
4143
4126
  selectAudioLanguage(language, role, channelsCount = 0) {
4144
- const LanguageUtils = shaka.util.LanguageUtils;
4145
-
4146
4127
  if (this.manifest_ && this.playhead_) {
4147
4128
  this.currentAdaptationSetCriteria_ =
4148
4129
  new shaka.media.PreferenceBasedCriteria(language, role || '',
@@ -4180,33 +4161,10 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
4180
4161
  // If we haven't switched yet, just use ABR to find a new track.
4181
4162
  this.chooseVariantAndSwitch_();
4182
4163
  } else if (this.video_ && this.video_.audioTracks) {
4183
- const audioTracks = Array.from(this.video_.audioTracks);
4184
- const selectedLanguage = LanguageUtils.normalize(language);
4185
-
4186
- let languageMatch = null;
4187
- let languageAndRoleMatch = null;
4188
-
4189
- for (const audioTrack of audioTracks) {
4190
- const track = shaka.util.StreamUtils.html5AudioTrackToTrack(audioTrack);
4191
-
4192
- if (LanguageUtils.normalize(track.language) == selectedLanguage) {
4193
- languageMatch = audioTrack;
4194
-
4195
- if (role) {
4196
- if (track.roles.includes(role)) {
4197
- languageAndRoleMatch = audioTrack;
4198
- }
4199
- } else { // no role
4200
- if (track.roles.length == 0) {
4201
- languageAndRoleMatch = audioTrack;
4202
- }
4203
- }
4204
- }
4205
- }
4206
- if (languageAndRoleMatch) {
4207
- this.switchHtml5Track_(languageAndRoleMatch);
4208
- } else if (languageMatch) {
4209
- this.switchHtml5Track_(languageMatch);
4164
+ const track = shaka.util.StreamUtils.filterStreamsByLanguageAndRole(
4165
+ this.getVariantTracks(), language, role || '', false)[0];
4166
+ if (track) {
4167
+ this.selectVariantTrack(track);
4210
4168
  }
4211
4169
  }
4212
4170
  }
@@ -4222,8 +4180,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
4222
4180
  * @export
4223
4181
  */
4224
4182
  selectTextLanguage(language, role, forced = false) {
4225
- const LanguageUtils = shaka.util.LanguageUtils;
4226
-
4227
4183
  if (this.manifest_ && this.playhead_) {
4228
4184
  this.currentTextLanguage_ = language;
4229
4185
  this.currentTextRole_ = role || '';
@@ -4244,13 +4200,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
4244
4200
  }
4245
4201
  }
4246
4202
  } else {
4247
- const selectedLanguage = LanguageUtils.normalize(language);
4248
-
4249
- const track = this.getTextTracks().find((t) => {
4250
- return LanguageUtils.normalize(t.language) == selectedLanguage &&
4251
- (!role || t.roles.includes(role)) && t.forced == forced;
4252
- });
4253
-
4203
+ const track = shaka.util.StreamUtils.filterStreamsByLanguageAndRole(
4204
+ this.getTextTracks(), language, role || '', forced)[0];
4254
4205
  if (track) {
4255
4206
  this.selectTextTrack(track);
4256
4207
  }
@@ -7020,7 +6971,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
7020
6971
  * @define {string} A version number taken from git at compile time.
7021
6972
  * @export
7022
6973
  */
7023
- shaka.Player.version = 'v4.3.11-uncompiled';
6974
+ shaka.Player.version = 'v4.3.12-uncompiled';
7024
6975
 
7025
6976
  // Initialize the deprecation system using the version string we just set
7026
6977
  // on the player.
@@ -214,11 +214,12 @@ shaka.text.TtmlTextParser = class {
214
214
  }
215
215
  }
216
216
 
217
- const parentIsContent = isContent;
218
217
  if (cueNode.nodeName == 'p' || imageElement) {
219
218
  isContent = true;
220
219
  }
221
220
 
221
+ const parentIsContent = isContent;
222
+
222
223
  const spaceStyle = cueElement.getAttribute('xml:space') ||
223
224
  (whitespaceTrim ? 'default' : 'preserve');
224
225
 
@@ -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.extern.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.extern.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
- if (cue.lineInterpretation == Cue.lineInterpretation.PERCENTAGE) {
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
- if (cue.positionAlign == Cue.positionAlign.LEFT) {
706
+ const computedPositionAlign = this.computeCuePositionAlignment_(cue);
707
+ if (computedPositionAlign == Cue.positionAlign.LEFT) {
662
708
  style.cssFloat = 'left';
663
- } else if (cue.positionAlign == Cue.positionAlign.RIGHT) {
709
+ } else if (computedPositionAlign == Cue.positionAlign.RIGHT) {
664
710
  style.cssFloat = 'right';
665
711
  }
666
712
 
@@ -403,8 +403,6 @@ shaka.text.VttTextParser = class {
403
403
  cue = new shaka.text.Cue(start, end, '');
404
404
  }
405
405
 
406
- VttTextParser.parseCueStyles(payload, cue, styles);
407
-
408
406
  // Parse optional settings.
409
407
  parser.skipWhitespace();
410
408
  let word = parser.readWord();
@@ -418,6 +416,8 @@ shaka.text.VttTextParser = class {
418
416
  word = parser.readWord();
419
417
  }
420
418
 
419
+ VttTextParser.parseCueStyles(payload, cue, styles);
420
+
421
421
  if (id != null) {
422
422
  cue.id = id;
423
423
  }
@@ -69,8 +69,8 @@ shaka.util.PlayerConfiguration = class {
69
69
  advanced: {}, // key is arbitrary key system ID, value is a record type
70
70
  delayLicenseRequestUntilPlayed: false,
71
71
  initDataTransform: (initData, initDataType, drmInfo) => {
72
- const keySystem = drmInfo.keySystem;
73
- if (keySystem == 'com.apple.fps.1_0' && initDataType == 'skd') {
72
+ if (shaka.util.Platform.isMediaKeysPolyfilled() &&
73
+ initDataType == 'skd') {
74
74
  const cert = drmInfo.serverCertificate;
75
75
  const contentId =
76
76
  shaka.util.FairPlayUtils.defaultGetContentId(initData);
@@ -1442,22 +1442,23 @@ shaka.util.StreamUtils = class {
1442
1442
 
1443
1443
  /**
1444
1444
  * Chooses streams according to the given config.
1445
+ * Works both for Stream and Track types due to their similarities.
1445
1446
  *
1446
- * @param {!Array.<shaka.extern.Stream>} streams
1447
+ * @param {!Array<!shaka.extern.Stream>|!Array<!shaka.extern.Track>} streams
1447
1448
  * @param {string} preferredLanguage
1448
1449
  * @param {string} preferredRole
1449
1450
  * @param {boolean} preferredForced
1450
- * @return {!Array.<!shaka.extern.Stream>}
1451
+ * @return {!Array<!shaka.extern.Stream>|!Array<!shaka.extern.Track>}
1451
1452
  */
1452
1453
  static filterStreamsByLanguageAndRole(
1453
1454
  streams, preferredLanguage, preferredRole, preferredForced) {
1454
1455
  const LanguageUtils = shaka.util.LanguageUtils;
1455
1456
 
1456
- /** @type {!Array.<!shaka.extern.Stream>} */
1457
+ /** @type {!Array<!shaka.extern.Stream>|!Array<!shaka.extern.Track>} */
1457
1458
  let chosen = streams;
1458
1459
 
1459
1460
  // Start with the set of primary streams.
1460
- /** @type {!Array.<!shaka.extern.Stream>} */
1461
+ /** @type {!Array<!shaka.extern.Stream>|!Array<!shaka.extern.Track>} */
1461
1462
  const primary = streams.filter((stream) => {
1462
1463
  return stream.primary;
1463
1464
  });
@@ -1497,7 +1498,7 @@ shaka.util.StreamUtils = class {
1497
1498
 
1498
1499
  // Now refine the choice based on role preference.
1499
1500
  if (preferredRole) {
1500
- const roleMatches = shaka.util.StreamUtils.filterTextStreamsByRole_(
1501
+ const roleMatches = shaka.util.StreamUtils.filterStreamsByRole_(
1501
1502
  chosen, preferredRole);
1502
1503
  if (roleMatches.length) {
1503
1504
  return roleMatches;
@@ -1525,20 +1526,21 @@ shaka.util.StreamUtils = class {
1525
1526
  if (!allRoles.length) {
1526
1527
  return chosen;
1527
1528
  }
1528
- return shaka.util.StreamUtils.filterTextStreamsByRole_(chosen, allRoles[0]);
1529
+ return shaka.util.StreamUtils.filterStreamsByRole_(chosen, allRoles[0]);
1529
1530
  }
1530
1531
 
1531
1532
 
1532
1533
  /**
1533
- * Filter text Streams by role.
1534
+ * Filter Streams by role.
1535
+ * Works both for Stream and Track types due to their similarities.
1534
1536
  *
1535
- * @param {!Array.<shaka.extern.Stream>} textStreams
1537
+ * @param {!Array<!shaka.extern.Stream>|!Array<!shaka.extern.Track>} streams
1536
1538
  * @param {string} preferredRole
1537
- * @return {!Array.<shaka.extern.Stream>}
1539
+ * @return {!Array<!shaka.extern.Stream>|!Array<!shaka.extern.Track>}
1538
1540
  * @private
1539
1541
  */
1540
- static filterTextStreamsByRole_(textStreams, preferredRole) {
1541
- return textStreams.filter((stream) => {
1542
+ static filterStreamsByRole_(streams, preferredRole) {
1543
+ return streams.filter((stream) => {
1542
1544
  return stream.roles.includes(preferredRole);
1543
1545
  });
1544
1546
  }
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.3.11",
4
+ "version": "4.3.12",
5
5
  "homepage": "https://github.com/shaka-project/shaka-player",
6
6
  "author": "Google",
7
7
  "maintainers": [
@@ -42,7 +42,7 @@
42
42
  "karma-coverage": "^2.2.0",
43
43
  "karma-jasmine": "^4.0.1",
44
44
  "karma-jasmine-ajax": "^0.1.13",
45
- "karma-local-wd-launcher": "^1.6.4",
45
+ "karma-local-wd-launcher": "^1.6.6",
46
46
  "karma-opera-launcher": "^1.0.0",
47
47
  "karma-sourcemap-loader": "^0.3.8",
48
48
  "karma-spec-reporter": "^0.0.34",
@@ -1866,9 +1866,8 @@ describe('TtmlTextParser', () => {
1866
1866
  endTime: 60,
1867
1867
  payload: '',
1868
1868
  fontSize: '15px',
1869
- // Styles from regionStyle should apply only to the nested cue.
1870
- backgroundColor: '',
1871
- color: '',
1869
+ backgroundColor: 'transparent',
1870
+ color: 'blue',
1872
1871
  displayAlign: Cue.displayAlign.CENTER,
1873
1872
  textAlign: Cue.textAlign.CENTER,
1874
1873
 
@@ -1970,7 +1969,7 @@ describe('TtmlTextParser', () => {
1970
1969
  startTime: 0,
1971
1970
  endTime: 60,
1972
1971
  payload: '',
1973
- fontSize: '',
1972
+ fontSize: '16px',
1974
1973
  nestedCues: [
1975
1974
  {
1976
1975
  startTime: 0,
@@ -207,15 +207,30 @@ describe('VttTextParser', () => {
207
207
  {
208
208
  startTime: 40,
209
209
  endTime: 50,
210
- payload: 'Test2',
210
+ payload: '',
211
211
  writingMode: Cue.writingMode.VERTICAL_LEFT_TO_RIGHT,
212
+ nestedCues: [
213
+ {
214
+ startTime: 40,
215
+ endTime: 50,
216
+ payload: 'Test',
217
+ writingMode: Cue.writingMode.VERTICAL_LEFT_TO_RIGHT,
218
+ },
219
+ {
220
+ startTime: 40,
221
+ endTime: 50,
222
+ payload: '2',
223
+ fontWeight: Cue.fontWeight.BOLD,
224
+ writingMode: Cue.writingMode.VERTICAL_LEFT_TO_RIGHT,
225
+ },
226
+ ],
212
227
  },
213
228
  ],
214
229
  'WEBVTT\n\n' +
215
230
  '00:00:20.000 --> 00:00:40.000 vertical:rl\n' +
216
231
  'Test\n\n' +
217
232
  '00:00:40.000 --> 00:00:50.000 vertical:lr\n' +
218
- 'Test2',
233
+ 'Test<b>2</b>',
219
234
  {periodStart: 0, segmentStart: 0, segmentEnd: 0, vttOffset: 0});
220
235
  });
221
236
 
@@ -213,7 +213,6 @@ filterDescribe('WebVTT layout', shaka.test.TextLayoutTests.supported, () => {
213
213
  await helper.checkScreenshot('line-negative-2');
214
214
  });
215
215
 
216
- // FIXME: UI version is wrong: not positioned by line
217
216
  it('line 0', async () => {
218
217
  parseAndDisplay([
219
218
  'WEBVTT\n',