shaka-player 4.9.26 → 4.9.27

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.
Files changed (78) hide show
  1. package/dist/controls.css +2 -2
  2. package/dist/controls.css.map +1 -1
  3. package/dist/deps.js +1 -1
  4. package/dist/locales.js +54 -54
  5. package/dist/shaka-player.compiled.d.ts +4 -0
  6. package/dist/shaka-player.compiled.debug.d.ts +4 -0
  7. package/dist/shaka-player.compiled.debug.externs.js +6 -0
  8. package/dist/shaka-player.compiled.debug.js +58 -50
  9. package/dist/shaka-player.compiled.debug.map +4 -4
  10. package/dist/shaka-player.compiled.externs.js +6 -0
  11. package/dist/shaka-player.compiled.js +738 -733
  12. package/dist/shaka-player.compiled.map +4 -4
  13. package/dist/shaka-player.ui.d.ts +4 -0
  14. package/dist/shaka-player.ui.debug.d.ts +4 -0
  15. package/dist/shaka-player.ui.debug.externs.js +6 -0
  16. package/dist/shaka-player.ui.debug.js +109 -100
  17. package/dist/shaka-player.ui.debug.map +4 -4
  18. package/dist/shaka-player.ui.externs.js +6 -0
  19. package/dist/shaka-player.ui.js +828 -822
  20. package/dist/shaka-player.ui.map +4 -4
  21. package/externs/ima.js +22 -2
  22. package/lib/dash/dash_parser.js +10 -5
  23. package/lib/dash/mpd_utils.js +0 -3
  24. package/lib/media/segment_index.js +18 -6
  25. package/lib/media/streaming_engine.js +7 -0
  26. package/lib/player.js +4 -2
  27. package/lib/text/simple_text_displayer.js +1 -1
  28. package/lib/text/text_utils.js +4 -0
  29. package/lib/text/ttml_text_parser.js +26 -5
  30. package/lib/util/periods.js +60 -4
  31. package/lib/util/tXml.js +17 -9
  32. package/package.json +1 -1
  33. package/ui/less/overflow_menu.less +1 -0
  34. package/ui/less/tooltip.less +1 -1
  35. package/ui/locales/ar-XB.json +1 -1
  36. package/ui/locales/ar.json +1 -1
  37. package/ui/locales/bg.json +1 -1
  38. package/ui/locales/ca.json +5 -5
  39. package/ui/locales/cs.json +1 -1
  40. package/ui/locales/da.json +1 -1
  41. package/ui/locales/de.json +1 -1
  42. package/ui/locales/el.json +1 -1
  43. package/ui/locales/en-GB.json +1 -1
  44. package/ui/locales/en-XA.json +1 -1
  45. package/ui/locales/es-419.json +4 -4
  46. package/ui/locales/es.json +3 -3
  47. package/ui/locales/fa.json +1 -1
  48. package/ui/locales/fi.json +1 -1
  49. package/ui/locales/fil.json +1 -1
  50. package/ui/locales/fr.json +6 -6
  51. package/ui/locales/hi.json +1 -1
  52. package/ui/locales/hr.json +1 -1
  53. package/ui/locales/hu.json +1 -1
  54. package/ui/locales/id.json +1 -1
  55. package/ui/locales/it.json +1 -1
  56. package/ui/locales/iw.json +1 -1
  57. package/ui/locales/ja.json +1 -1
  58. package/ui/locales/ko.json +1 -1
  59. package/ui/locales/lt.json +1 -1
  60. package/ui/locales/lv.json +1 -1
  61. package/ui/locales/nl.json +1 -1
  62. package/ui/locales/no.json +1 -1
  63. package/ui/locales/pl.json +6 -6
  64. package/ui/locales/pt-BR.json +6 -6
  65. package/ui/locales/pt-PT.json +7 -7
  66. package/ui/locales/ro.json +1 -1
  67. package/ui/locales/ru.json +1 -1
  68. package/ui/locales/sk.json +1 -1
  69. package/ui/locales/sl.json +1 -1
  70. package/ui/locales/sr.json +1 -1
  71. package/ui/locales/sv.json +1 -1
  72. package/ui/locales/th.json +1 -1
  73. package/ui/locales/tr.json +1 -1
  74. package/ui/locales/uk.json +1 -1
  75. package/ui/locales/vi.json +1 -1
  76. package/ui/locales/zh-HK.json +1 -1
  77. package/ui/locales/zh-TW.json +1 -1
  78. package/ui/locales/zh.json +1 -1
package/externs/ima.js CHANGED
@@ -269,7 +269,6 @@ google.ima.Ad = class {
269
269
  getMediaUrl() {}
270
270
  };
271
271
 
272
-
273
272
  /** @const */
274
273
  google.ima.AdPodInfo = class {
275
274
  /** @return {number} */
@@ -366,7 +365,7 @@ google.ima.AdEvent.Type = {
366
365
  * @description Request for the ad server
367
366
  * @property {string|undefined} adTagUrl
368
367
  * Specifies the ad tag url that is requested from the ad server.
369
- * This parameter is optional if adsReponse is given.
368
+ * This parameter is optional if adsResponse is given.
370
369
  * @property {string|undefined} adsResponse
371
370
  * Specifies a VAST 2.0 document to be used as the ads response instead of
372
371
  * making a request via an ad tag url. This can be useful for debugging
@@ -518,6 +517,9 @@ google.ima.dai.api.Ad = class {
518
517
 
519
518
  /** @return {string} */
520
519
  getCreativeAdId() {}
520
+
521
+ /** @return {!Array.<!google.ima.dai.api.CompanionAd>} */
522
+ getCompanionAds() {}
521
523
  };
522
524
 
523
525
 
@@ -536,6 +538,24 @@ google.ima.dai.api.AdPodInfo = class {
536
538
  getPodIndex() {}
537
539
  };
538
540
 
541
+ /** @const */
542
+ google.ima.dai.api.CompanionAd = class {
543
+ /** @return {?string} */
544
+ getAdSlotId() {}
545
+
546
+ /** @return {string} */
547
+ getContent() {}
548
+
549
+ /** @return {?string} */
550
+ getContentType() {}
551
+
552
+ /** @return {number} */
553
+ getHeight() {}
554
+
555
+ /** @return {?number} */
556
+ getWidth() {}
557
+ };
558
+
539
559
 
540
560
  /** @const */
541
561
  google.ima.dai.api.CuePoint = class {};
@@ -1430,14 +1430,14 @@ shaka.dash.DashParser = class {
1430
1430
  */
1431
1431
  cleanStreamMap_() {
1432
1432
  const oldPeriodIds = Object.keys(this.indexStreamMap_);
1433
- if (oldPeriodIds.length === this.lastManifestUpdatePeriodIds_.length) {
1434
- return;
1435
- }
1436
1433
  const diffPeriodsIDs = oldPeriodIds.filter((pId) => {
1437
1434
  return !this.lastManifestUpdatePeriodIds_.includes(pId);
1438
1435
  });
1439
1436
  for (const pId of diffPeriodsIDs) {
1440
1437
  for (const contextId of this.indexStreamMap_[pId]) {
1438
+ if (this.periodCombiner_) {
1439
+ this.periodCombiner_.deleteStream(this.streamMap_[contextId], pId);
1440
+ }
1441
1441
  delete this.streamMap_[contextId];
1442
1442
  }
1443
1443
  delete this.indexStreamMap_[pId];
@@ -2804,6 +2804,8 @@ shaka.dash.DashParser = class {
2804
2804
  const schemeIdUri = elem.attributes['schemeIdUri'] || '';
2805
2805
  const value = elem.attributes['value'] || '';
2806
2806
  const timescale = TXml.parseAttr(elem, 'timescale', parseNumber) || 1;
2807
+ const presentationTimeOffset =
2808
+ TXml.parseAttr(elem, 'presentationTimeOffset', parseNumber) || 0;
2807
2809
 
2808
2810
  for (const eventNode of TXml.findChildren(elem, 'Event')) {
2809
2811
  const presentationTime =
@@ -2811,7 +2813,10 @@ shaka.dash.DashParser = class {
2811
2813
  const duration =
2812
2814
  TXml.parseAttr(eventNode, 'duration', parseNumber) || 0;
2813
2815
 
2814
- let startTime = presentationTime / timescale + periodStart;
2816
+ // Ensure start time won't be lower than period start.
2817
+ let startTime = Math.max(
2818
+ (presentationTime - presentationTimeOffset) / timescale + periodStart,
2819
+ periodStart);
2815
2820
  let endTime = startTime + (duration / timescale);
2816
2821
  if (periodDuration != null) {
2817
2822
  // An event should not go past the Period, even if the manifest says so.
@@ -2833,7 +2838,7 @@ shaka.dash.DashParser = class {
2833
2838
  endTime: endTime,
2834
2839
  id: eventNode.attributes['id'] || '',
2835
2840
  eventElement: TXml.txmlNodeToDomElement(eventNode),
2836
- eventNode: eventNode,
2841
+ eventNode: TXml.cloneNode(eventNode),
2837
2842
  };
2838
2843
 
2839
2844
  this.playerInterface_.onTimelineRegionAdded(region);
@@ -481,9 +481,6 @@ shaka.dash.MpdUtils = class {
481
481
  // Move the children of the loaded xml into the current element.
482
482
  while (rootElem.children.length) {
483
483
  const child = rootElem.children.shift();
484
- if (TXml.isNode(child)) {
485
- child.parent = element;
486
- }
487
484
  element.children.push(child);
488
485
  }
489
486
 
@@ -700,6 +700,17 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
700
700
  this.indexes_ = [];
701
701
  }
702
702
 
703
+ /** Evicts all old SegmentIndexes in this MetaSegmentIndex that are empty. */
704
+ evictEmpty() {
705
+ while (this.indexes_.length > 1 && this.indexes_[0].isEmpty()) {
706
+ const index = this.indexes_.shift();
707
+ // In the case of this class, this.numEvicted_ represents the evicted
708
+ // segments that were in indexes that were entirely evicted.
709
+ this.numEvicted_ += index.getNumEvicted();
710
+ index.release();
711
+ }
712
+ }
713
+
703
714
  /**
704
715
  * Append a SegmentIndex to this MetaSegmentIndex. This effectively stitches
705
716
  * the underlying Stream onto the end of the multi-Period Stream represented
@@ -724,6 +735,7 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
724
735
  // Be careful to clone the Array. We don't want to share the reference with
725
736
  // our clone and affect each other accidentally.
726
737
  clone.indexes_ = this.indexes_.slice();
738
+ clone.numEvicted_ = this.numEvicted_;
727
739
  return clone;
728
740
  }
729
741
 
@@ -754,7 +766,7 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
754
766
  * @export
755
767
  */
756
768
  find(time) {
757
- let numPassedInEarlierIndexes = 0;
769
+ let numPassedInEarlierIndexes = this.numEvicted_;
758
770
 
759
771
  for (const index of this.indexes_) {
760
772
  const position = index.find(time);
@@ -775,7 +787,7 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
775
787
  * @export
776
788
  */
777
789
  get(position) {
778
- let numPassedInEarlierIndexes = 0;
790
+ let numPassedInEarlierIndexes = this.numEvicted_;
779
791
  let sawSegments = false;
780
792
 
781
793
  for (const index of this.indexes_) {
@@ -822,10 +834,10 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
822
834
  * @export
823
835
  */
824
836
  evict(time) {
825
- // evict() is only used internally by the DASH and HLS parser on
826
- // SegmentIndexes, but never on MetaSegmentIndex.
827
- goog.asserts.assert(
828
- false, 'evict() should not be used in MetaSegmentIndex!');
837
+ for (const index of this.indexes_) {
838
+ index.evict(time);
839
+ }
840
+ this.evictEmpty();
829
841
  }
830
842
 
831
843
  /**
@@ -15,6 +15,7 @@ goog.require('shaka.log');
15
15
  goog.require('shaka.media.InitSegmentReference');
16
16
  goog.require('shaka.media.ManifestParser');
17
17
  goog.require('shaka.media.MediaSourceEngine');
18
+ goog.require('shaka.media.MetaSegmentIndex');
18
19
  goog.require('shaka.media.SegmentIterator');
19
20
  goog.require('shaka.media.SegmentReference');
20
21
  goog.require('shaka.media.SegmentPrefetch');
@@ -2465,6 +2466,12 @@ shaka.media.StreamingEngine = class {
2465
2466
  * @private
2466
2467
  */
2467
2468
  async evict_(mediaState, presentationTime) {
2469
+ const segmentIndex = mediaState.stream.segmentIndex;
2470
+ if (segmentIndex instanceof shaka.media.MetaSegmentIndex) {
2471
+ segmentIndex.evict(
2472
+ this.manifest_.presentationTimeline.getSeekRangeStart());
2473
+ }
2474
+
2468
2475
  const logPrefix = shaka.media.StreamingEngine.logPrefix_(mediaState);
2469
2476
  shaka.log.v2(logPrefix, 'checking buffer length');
2470
2477
 
package/lib/player.js CHANGED
@@ -6740,11 +6740,13 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
6740
6740
  this.playhead_.notifyOfBufferingChange();
6741
6741
  // Skip the initial buffer gap
6742
6742
  const startTime = this.mediaSourceEngine_.bufferStart(contentType);
6743
+ const ContentType = shaka.util.ManifestParserUtils.ContentType;
6743
6744
  if (
6744
6745
  !this.isLive() &&
6745
6746
  // If not paused then GapJumpingController will handle this gap.
6746
6747
  this.video_.paused &&
6747
6748
  startTime != null &&
6749
+ contentType != ContentType.TEXT &&
6748
6750
  startTime > 0 &&
6749
6751
  this.playhead_.getTime() < startTime
6750
6752
  ) {
@@ -7517,8 +7519,8 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
7517
7519
  * @define {string} A version number taken from git at compile time.
7518
7520
  * @export
7519
7521
  */
7520
- // eslint-disable-next-line no-useless-concat
7521
- shaka.Player.version = 'v4.9.26' + '-uncompiled'; // x-release-please-version
7522
+ // eslint-disable-next-line no-useless-concat, max-len
7523
+ shaka.Player.version = 'v4.9.27' + '-uncompiled'; // x-release-please-version
7522
7524
 
7523
7525
  // Initialize the deprecation system using the version string we just set
7524
7526
  // on the player.
@@ -112,7 +112,7 @@ shaka.text.SimpleTextDisplayer = class {
112
112
  return false;
113
113
  });
114
114
 
115
- if (!containsCue) {
115
+ if (!containsCue && inCue.payload) {
116
116
  const cue =
117
117
  shaka.text.Utils.mapShakaCueToNativeCue(inCue);
118
118
  if (cue) {
@@ -31,6 +31,10 @@ shaka.text.Utils = class {
31
31
  }).join('');
32
32
  }
33
33
 
34
+ if (!cue.payload) {
35
+ return cue.payload;
36
+ }
37
+
34
38
  // Handle bold, italics and underline
35
39
  const openStyleTags = [];
36
40
  const bold = cue.fontWeight >= shaka.text.Cue.fontWeight.BOLD;
@@ -65,7 +65,7 @@ shaka.text.TtmlTextParser = class {
65
65
  return cues;
66
66
  }
67
67
 
68
- const tt = TXml.parseXmlString(str, 'tt');
68
+ const tt = TXml.parseXmlString(str, 'tt', /* includeParent= */ true);
69
69
  if (!tt) {
70
70
  throw new shaka.util.Error(
71
71
  shaka.util.Error.Severity.CRITICAL,
@@ -108,7 +108,8 @@ shaka.text.TtmlTextParser = class {
108
108
  TtmlTextParser.getCellResolution_(cellResolution);
109
109
 
110
110
  const metadata = TXml.getElementsByTagName(tt, 'metadata')[0];
111
- const metadataElements = metadata ? metadata.children : [];
111
+ const metadataElements =
112
+ (metadata ? metadata.children : []).filter((c) => c != '\n');
112
113
  const styles = TXml.getElementsByTagName(tt, 'style');
113
114
  const regionElements = TXml.getElementsByTagName(tt, 'region');
114
115
 
@@ -508,6 +509,24 @@ shaka.text.TtmlTextParser = class {
508
509
  return region;
509
510
  }
510
511
 
512
+ /**
513
+ * Ensures any TTML RGBA's alpha range of 0-255 is converted to 0-1.
514
+ * @param {string} color
515
+ * @return {string}
516
+ * @private
517
+ */
518
+ static convertTTMLrgbaToHTMLrgba_(color) {
519
+ const rgba = color.match(/rgba\(([^)]+)\)/);
520
+ if (rgba) {
521
+ const values = rgba[1].split(',');
522
+ if (values.length == 4) {
523
+ values[3] = String(Number(values[3]) / 255);
524
+ return 'rgba(' + values.join(',') + ')';
525
+ }
526
+ }
527
+ return color;
528
+ }
529
+
511
530
  /**
512
531
  * Adds applicable style properties to a cue.
513
532
  *
@@ -586,7 +605,7 @@ shaka.text.TtmlTextParser = class {
586
605
  const color = TtmlTextParser.getStyleAttribute_(
587
606
  cueElement, region, styles, 'color', shouldInheritRegionStyles);
588
607
  if (color) {
589
- cue.color = color;
608
+ cue.color = TtmlTextParser.convertTTMLrgbaToHTMLrgba_(color);
590
609
  }
591
610
 
592
611
  // Background color should not be set on a container. If this is a nested
@@ -600,7 +619,8 @@ shaka.text.TtmlTextParser = class {
600
619
  cueElement, region, styles, 'backgroundColor',
601
620
  shouldInheritRegionStyles);
602
621
  if (backgroundColor) {
603
- cue.backgroundColor = backgroundColor;
622
+ cue.backgroundColor =
623
+ TtmlTextParser.convertTTMLrgbaToHTMLrgba_(backgroundColor);
604
624
  }
605
625
 
606
626
  const border = TtmlTextParser.getStyleAttribute_(
@@ -709,7 +729,8 @@ shaka.text.TtmlTextParser = class {
709
729
  // There is no defined color, so default to the text color.
710
730
  cue.textStrokeColor = cue.color;
711
731
  } else {
712
- cue.textStrokeColor = split[0];
732
+ cue.textStrokeColor =
733
+ TtmlTextParser.convertTTMLrgbaToHTMLrgba_(split[0]);
713
734
  split.shift();
714
735
  }
715
736
  if (split[0] && split[0].match(TtmlTextParser.unitValues_)) {
@@ -107,6 +107,56 @@ shaka.util.PeriodCombiner = class {
107
107
  return this.imageStreams_;
108
108
  }
109
109
 
110
+ /**
111
+ * Deletes a stream from matchedStreams because it is no longer needed
112
+ *
113
+ * @param {?shaka.extern.Stream} stream
114
+ * @param {string} periodId
115
+ *
116
+ * @export
117
+ */
118
+ deleteStream(stream, periodId) {
119
+ if (!stream) {
120
+ return;
121
+ }
122
+ const ContentType = shaka.util.ManifestParserUtils.ContentType;
123
+ if (stream.type == ContentType.AUDIO) {
124
+ for (const audioStream of this.audioStreams_) {
125
+ audioStream.matchedStreams = audioStream.matchedStreams.filter((s) => {
126
+ return s !== stream;
127
+ });
128
+ }
129
+ } else if (stream.type == ContentType.VIDEO) {
130
+ for (const videoStream of this.videoStreams_) {
131
+ videoStream.matchedStreams = videoStream.matchedStreams.filter((s) => {
132
+ return s !== stream;
133
+ });
134
+ if (videoStream.trickModeVideo) {
135
+ videoStream.trickModeVideo.matchedStreams =
136
+ videoStream.trickModeVideo.matchedStreams.filter((s) => {
137
+ return s !== stream;
138
+ });
139
+ }
140
+ }
141
+ } else if (stream.type == ContentType.TEXT) {
142
+ for (const textStream of this.textStreams_) {
143
+ textStream.matchedStreams = textStream.matchedStreams.filter((s) => {
144
+ return s !== stream;
145
+ });
146
+ }
147
+ } else if (stream.type == ContentType.IMAGE) {
148
+ for (const imageStream of this.imageStreams_) {
149
+ imageStream.matchedStreams = imageStream.matchedStreams.filter((s) => {
150
+ return s !== stream;
151
+ });
152
+ }
153
+ }
154
+ if (stream.segmentIndex) {
155
+ stream.closeSegmentIndex();
156
+ }
157
+ this.usedPeriodIds_.delete(periodId);
158
+ }
159
+
110
160
  /**
111
161
  * Returns an object that contains arrays of streams by type
112
162
  * @param {!Array<shaka.extern.Period>} periods
@@ -600,7 +650,8 @@ shaka.util.PeriodCombiner = class {
600
650
  const streams = outputStream.matchedStreams;
601
651
  goog.asserts.assert(streams, 'matched streams should be valid');
602
652
 
603
- for (const stream of streams) {
653
+ for (let i = firstNewPeriodIndex; i < streams.length; i++) {
654
+ const stream = streams[i];
604
655
  operations.push(stream.createSegmentIndex());
605
656
  if (stream.trickModeVideo && !stream.trickModeVideo.segmentIndex) {
606
657
  operations.push(stream.trickModeVideo.createSegmentIndex());
@@ -783,7 +834,8 @@ shaka.util.PeriodCombiner = class {
783
834
  clone.segmentIndex = null;
784
835
  clone.emsgSchemeIdUris = [];
785
836
  clone.keyIds = new Set();
786
- clone.closedCaptions = null;
837
+ clone.closedCaptions = stream.closedCaptions ?
838
+ new Map(stream.closedCaptions) : null;
787
839
  clone.trickModeVideo = null;
788
840
 
789
841
  return clone;
@@ -808,7 +860,8 @@ shaka.util.PeriodCombiner = class {
808
860
  clone.keyIds = new Set();
809
861
  clone.segments = [];
810
862
  clone.variantIds = [];
811
- clone.closedCaptions = null;
863
+ clone.closedCaptions = streamDb.closedCaptions ?
864
+ new Map(streamDb.closedCaptions) : null;
812
865
 
813
866
  return clone;
814
867
  }
@@ -852,7 +905,10 @@ shaka.util.PeriodCombiner = class {
852
905
  if (output.originalId == null) {
853
906
  output.originalId = input.originalId;
854
907
  } else {
855
- output.originalId += ',' + (input.originalId || '');
908
+ const newOriginalId = (input.originalId || '');
909
+ if (newOriginalId && !output.originalId.endsWith(newOriginalId)) {
910
+ output.originalId += ',' + newOriginalId;
911
+ }
856
912
  }
857
913
 
858
914
  const commonDrmInfos = shaka.util.DrmUtils.getCommonDrmInfos(
package/lib/util/tXml.js CHANGED
@@ -44,11 +44,13 @@ shaka.util.TXml = class {
44
44
  * Parse some data
45
45
  * @param {BufferSource} data
46
46
  * @param {string=} expectedRootElemName
47
+ * @param {boolean=} includeParent
47
48
  * @return {shaka.extern.xml.Node | null}
48
49
  */
49
- static parseXml(data, expectedRootElemName) {
50
+ static parseXml(data, expectedRootElemName, includeParent = false) {
50
51
  const xmlString = shaka.util.StringUtils.fromBytesAutoDetect(data);
51
- return shaka.util.TXml.parseXmlString(xmlString, expectedRootElemName);
52
+ return shaka.util.TXml.parseXmlString(
53
+ xmlString, expectedRootElemName, includeParent);
52
54
  }
53
55
 
54
56
  /**
@@ -57,8 +59,9 @@ shaka.util.TXml = class {
57
59
  * @param {string=} expectedRootElemName
58
60
  * @return {shaka.extern.xml.Node | null}
59
61
  */
60
- static parseXmlString(xmlString, expectedRootElemName) {
61
- const result = shaka.util.TXml.parse(xmlString);
62
+ static parseXmlString(xmlString, expectedRootElemName,
63
+ includeParent = false) {
64
+ const result = shaka.util.TXml.parse(xmlString, includeParent);
62
65
  if (!expectedRootElemName && result.length) {
63
66
  return result[0];
64
67
  }
@@ -109,9 +112,10 @@ shaka.util.TXml = class {
109
112
  * parseXML / html into a DOM Object,
110
113
  * with no validation and some failure tolerance
111
114
  * @param {string} S your XML to parse
115
+ * @param {boolean} includeParent
112
116
  * @return {Array.<shaka.extern.xml.Node>}
113
117
  */
114
- static parse(S) {
118
+ static parse(S, includeParent) {
115
119
  let pos = 0;
116
120
 
117
121
  const openBracket = '<';
@@ -286,9 +290,11 @@ shaka.util.TXml = class {
286
290
  children,
287
291
  parent: null,
288
292
  };
289
- for (let i = 0; i < children.length; i++) {
290
- if (typeof children[i] !== 'string') {
291
- children[i].parent = node;
293
+ if (includeParent) {
294
+ for (let i = 0; i < children.length; i++) {
295
+ if (typeof children[i] !== 'string') {
296
+ children[i].parent = node;
297
+ }
292
298
  }
293
299
  }
294
300
  return node;
@@ -330,7 +336,9 @@ shaka.util.TXml = class {
330
336
  for (let i = 0; i < childrenLength; i++) {
331
337
  const childrenValue = children[i];
332
338
  if (typeof childrenValue !== 'string') {
333
- childrenValue.parent = node;
339
+ if (includeParent) {
340
+ childrenValue.parent = node;
341
+ }
334
342
  } else if (i == childrenLength - 1 && childrenValue == '\n') {
335
343
  children.pop();
336
344
  }
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.9.26",
4
+ "version": "4.9.27",
5
5
  "homepage": "https://github.com/shaka-project/shaka-player",
6
6
  "author": "Google",
7
7
  "maintainers": [
@@ -39,6 +39,7 @@
39
39
 
40
40
  /* The buttons inside the menu. */
41
41
  button {
42
+ font-family: Roboto, sans-serif, TengwarTelcontar;
42
43
  font-size: 14px;
43
44
  background: transparent;
44
45
  color: black;
@@ -47,7 +47,7 @@
47
47
  content: attr(aria-label);
48
48
 
49
49
  /* Override .material-icons-round text styling */
50
- font-family: Roboto, sans-serif;
50
+ font-family: Roboto, sans-serif, TengwarTelcontar;
51
51
  line-height: calc(@material-icons-width / 2);
52
52
  white-space: nowrap;
53
53
  font-size: 13px;
@@ -35,4 +35,4 @@
35
35
  "UNMUTE": "‏‮Unmute‬‏",
36
36
  "UNRECOGNIZED_LANGUAGE": "‏‮Unrecognized‬‏",
37
37
  "VOLUME": "‏‮Volume‬‏"
38
- }
38
+ }
@@ -35,4 +35,4 @@
35
35
  "UNMUTE": "إعادة الصوت",
36
36
  "UNRECOGNIZED_LANGUAGE": "غير معروف",
37
37
  "VOLUME": "مستوى الصوت"
38
- }
38
+ }
@@ -35,4 +35,4 @@
35
35
  "UNMUTE": "Включване на звука",
36
36
  "UNRECOGNIZED_LANGUAGE": "Неразпознато",
37
37
  "VOLUME": "Звук"
38
- }
38
+ }
@@ -7,10 +7,10 @@
7
7
  "CAPTIONS": "Subtítols",
8
8
  "CAST": "Emet…",
9
9
  "ENTER_LOOP_MODE": "Reprodueix en bucle el vídeo actual",
10
- "ENTER_PICTURE_IN_PICTURE": "Entra al mode de pantalla en pantalla",
10
+ "ENTER_PICTURE_IN_PICTURE": "Entra a imatge sobre imatge",
11
11
  "EXIT_FULL_SCREEN": "Surt del mode de pantalla completa",
12
12
  "EXIT_LOOP_MODE": "Deixa de reproduir en bucle el vídeo actual",
13
- "EXIT_PICTURE_IN_PICTURE": "Surt del mode de pantalla en pantalla",
13
+ "EXIT_PICTURE_IN_PICTURE": "Surt d'imatge sobre imatge",
14
14
  "FAST_FORWARD": "Avança ràpidament",
15
15
  "FULL_SCREEN": "Pantalla completa",
16
16
  "LANGUAGE": "Idioma",
@@ -22,8 +22,8 @@
22
22
  "NOT_APPLICABLE": "No aplicable",
23
23
  "OFF": "Desactivat",
24
24
  "ON": "Activat",
25
- "PAUSE": "Atura",
26
- "PICTURE_IN_PICTURE": "Pantalla en pantalla",
25
+ "PAUSE": "Posa en pausa",
26
+ "PICTURE_IN_PICTURE": "Imatge sobre imatge",
27
27
  "PLAY": "Reprodueix",
28
28
  "PLAYBACK_RATE": "Velocitat de reproducció",
29
29
  "RESOLUTION": "Resolució",
@@ -35,4 +35,4 @@
35
35
  "UNMUTE": "Deixa de silenciar",
36
36
  "UNRECOGNIZED_LANGUAGE": "No reconegut",
37
37
  "VOLUME": "Volum"
38
- }
38
+ }
@@ -35,4 +35,4 @@
35
35
  "UNMUTE": "Zapnout zvuk",
36
36
  "UNRECOGNIZED_LANGUAGE": "Neznámé",
37
37
  "VOLUME": "Hlasitost"
38
- }
38
+ }
@@ -35,4 +35,4 @@
35
35
  "UNMUTE": "Slå lyden til",
36
36
  "UNRECOGNIZED_LANGUAGE": "Ikke genkendt",
37
37
  "VOLUME": "Lydstyrke"
38
- }
38
+ }
@@ -35,4 +35,4 @@
35
35
  "UNMUTE": "Stummschaltung aufheben",
36
36
  "UNRECOGNIZED_LANGUAGE": "Unbekannt",
37
37
  "VOLUME": "Lautstärke"
38
- }
38
+ }
@@ -35,4 +35,4 @@
35
35
  "UNMUTE": "Κατάργηση σίγασης",
36
36
  "UNRECOGNIZED_LANGUAGE": "Μη αναγνωρίσιμο",
37
37
  "VOLUME": "Ένταση"
38
- }
38
+ }
@@ -37,4 +37,4 @@
37
37
  "UNMUTE": "Unmute",
38
38
  "UNRECOGNIZED_LANGUAGE": "Unrecognised",
39
39
  "VOLUME": "volume"
40
- }
40
+ }
@@ -35,4 +35,4 @@
35
35
  "UNMUTE": "[Ûñmûţé one]",
36
36
  "UNRECOGNIZED_LANGUAGE": "[Ûñŕéçöĝñîžéð one two]",
37
37
  "VOLUME": "[Vöļûmé one]"
38
- }
38
+ }
@@ -26,17 +26,17 @@
26
26
  "PICTURE_IN_PICTURE": "Pantalla en pantalla",
27
27
  "PLAY": "Reproducir",
28
28
  "PLAYBACK_RATE": "Velocidad de reproducción",
29
- "RECENTER_VR": "Recentrar",
29
+ "RECENTER_VR": "Volver a centrar",
30
30
  "RESOLUTION": "Resolución",
31
31
  "REWIND": "Retroceder",
32
32
  "SEEK": "Buscar",
33
33
  "SKIP_AD": "Omitir anuncio",
34
34
  "SKIP_TO_LIVE": "Adelantar hasta la transmisión en vivo",
35
35
  "SUBTITLE_FORCED": "Forzado",
36
- "SURROUND": "Envolvente",
37
- "TOGGLE_STEREOSCOPIC": "Alternar estereoscópico",
36
+ "SURROUND": "Sonido envolvente",
37
+ "TOGGLE_STEREOSCOPIC": "Activar o desactivar el modo estereoscópico",
38
38
  "UNDETERMINED_LANGUAGE": "Sin especificar",
39
39
  "UNMUTE": "Dejar de silenciar",
40
40
  "UNRECOGNIZED_LANGUAGE": "No reconocida",
41
41
  "VOLUME": "Volumen"
42
- }
42
+ }
@@ -28,7 +28,7 @@
28
28
  "PLAY": "Reproducir",
29
29
  "PLAYBACK_RATE": "Velocidad de reproducción",
30
30
  "QUALITY": "Calidad",
31
- "RECENTER_VR": "Recentrar",
31
+ "RECENTER_VR": "Volver a centrar",
32
32
  "RESOLUTION": "Resolución",
33
33
  "REWIND": "Rebobinar",
34
34
  "SEEK": "Buscar",
@@ -36,9 +36,9 @@
36
36
  "SKIP_TO_LIVE": "Ir al vídeo en directo",
37
37
  "SUBTITLE_FORCED": "Forzado",
38
38
  "SURROUND": "Envolvente",
39
- "TOGGLE_STEREOSCOPIC": "Alternar estereoscópico",
39
+ "TOGGLE_STEREOSCOPIC": "Activar/Desactivar estereoscópica",
40
40
  "UNDETERMINED_LANGUAGE": "Sin especificar",
41
41
  "UNMUTE": "Activar sonido",
42
42
  "UNRECOGNIZED_LANGUAGE": "No reconocida",
43
43
  "VOLUME": "Volumen"
44
- }
44
+ }
@@ -35,4 +35,4 @@
35
35
  "UNMUTE": "باصدا کردن",
36
36
  "UNRECOGNIZED_LANGUAGE": "ناشناس",
37
37
  "VOLUME": "میزان صدا"
38
- }
38
+ }
@@ -35,4 +35,4 @@
35
35
  "UNMUTE": "Poista mykistys",
36
36
  "UNRECOGNIZED_LANGUAGE": "Tunnistamaton",
37
37
  "VOLUME": "Äänenvoimakkuus"
38
- }
38
+ }
@@ -35,4 +35,4 @@
35
35
  "UNMUTE": "I-unmute",
36
36
  "UNRECOGNIZED_LANGUAGE": "Hindi nakikilala",
37
37
  "VOLUME": "Volume"
38
- }
38
+ }