shaka-player 4.11.0 → 4.11.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.
Files changed (67) 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 +191 -53
  5. package/dist/shaka-player.compiled.debug.js +34 -32
  6. package/dist/shaka-player.compiled.debug.map +4 -4
  7. package/dist/shaka-player.compiled.js +245 -242
  8. package/dist/shaka-player.compiled.map +4 -4
  9. package/dist/shaka-player.ui.debug.js +115 -99
  10. package/dist/shaka-player.ui.debug.map +4 -4
  11. package/dist/shaka-player.ui.js +495 -479
  12. package/dist/shaka-player.ui.map +4 -4
  13. package/externs/ima.js +22 -2
  14. package/lib/dash/dash_parser.js +7 -2
  15. package/lib/media/segment_index.js +14 -2
  16. package/lib/media/streaming_engine.js +6 -0
  17. package/lib/player.js +1 -1
  18. package/lib/text/simple_text_displayer.js +1 -1
  19. package/lib/text/text_utils.js +12 -3
  20. package/lib/text/ttml_text_parser.js +25 -4
  21. package/lib/util/periods.js +4 -1
  22. package/package.json +1 -1
  23. package/ui/less/overflow_menu.less +1 -0
  24. package/ui/less/tooltip.less +1 -1
  25. package/ui/locales/ar-XB.json +11 -0
  26. package/ui/locales/ar.json +11 -0
  27. package/ui/locales/bg.json +11 -0
  28. package/ui/locales/ca.json +11 -0
  29. package/ui/locales/cs.json +11 -0
  30. package/ui/locales/da.json +11 -0
  31. package/ui/locales/de.json +13 -2
  32. package/ui/locales/el.json +11 -0
  33. package/ui/locales/en-GB.json +10 -1
  34. package/ui/locales/en-XA.json +12 -1
  35. package/ui/locales/es-419.json +5 -0
  36. package/ui/locales/es.json +1 -0
  37. package/ui/locales/fa.json +15 -4
  38. package/ui/locales/fi.json +11 -0
  39. package/ui/locales/fil.json +11 -0
  40. package/ui/locales/fr.json +3 -3
  41. package/ui/locales/hi.json +11 -0
  42. package/ui/locales/hr.json +11 -0
  43. package/ui/locales/hu.json +12 -1
  44. package/ui/locales/id.json +11 -0
  45. package/ui/locales/it.json +11 -0
  46. package/ui/locales/iw.json +13 -2
  47. package/ui/locales/ja.json +11 -0
  48. package/ui/locales/ko.json +11 -0
  49. package/ui/locales/lt.json +11 -0
  50. package/ui/locales/lv.json +12 -1
  51. package/ui/locales/nl.json +13 -2
  52. package/ui/locales/no.json +11 -0
  53. package/ui/locales/pl.json +8 -7
  54. package/ui/locales/pt-BR.json +1 -0
  55. package/ui/locales/pt-PT.json +1 -0
  56. package/ui/locales/ro.json +11 -0
  57. package/ui/locales/ru.json +11 -0
  58. package/ui/locales/sk.json +11 -0
  59. package/ui/locales/sl.json +11 -0
  60. package/ui/locales/sr.json +11 -0
  61. package/ui/locales/sv.json +11 -0
  62. package/ui/locales/th.json +12 -1
  63. package/ui/locales/tr.json +11 -0
  64. package/ui/locales/uk.json +12 -1
  65. package/ui/locales/vi.json +13 -2
  66. package/ui/locales/zh-TW.json +11 -0
  67. package/ui/locales/zh.json +12 -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 {};
@@ -2978,6 +2978,8 @@ shaka.dash.DashParser = class {
2978
2978
  const schemeIdUri = elem.attributes['schemeIdUri'] || '';
2979
2979
  const value = elem.attributes['value'] || '';
2980
2980
  const timescale = TXml.parseAttr(elem, 'timescale', parseNumber) || 1;
2981
+ const presentationTimeOffset =
2982
+ TXml.parseAttr(elem, 'presentationTimeOffset', parseNumber) || 0;
2981
2983
 
2982
2984
  for (const eventNode of TXml.findChildren(elem, 'Event')) {
2983
2985
  const presentationTime =
@@ -2985,7 +2987,10 @@ shaka.dash.DashParser = class {
2985
2987
  const duration =
2986
2988
  TXml.parseAttr(eventNode, 'duration', parseNumber) || 0;
2987
2989
 
2988
- let startTime = presentationTime / timescale + periodStart;
2990
+ // Ensure start time won't be lower than period start.
2991
+ let startTime = Math.max(
2992
+ (presentationTime - presentationTimeOffset) / timescale + periodStart,
2993
+ periodStart);
2989
2994
  let endTime = startTime + (duration / timescale);
2990
2995
  if (periodDuration != null) {
2991
2996
  // An event should not go past the Period, even if the manifest says so.
@@ -3007,7 +3012,7 @@ shaka.dash.DashParser = class {
3007
3012
  endTime: endTime,
3008
3013
  id: eventNode.attributes['id'] || '',
3009
3014
  eventElement: TXml.txmlNodeToDomElement(eventNode),
3010
- eventNode: eventNode,
3015
+ eventNode: TXml.cloneNode(eventNode),
3011
3016
  };
3012
3017
 
3013
3018
  this.playerInterface_.onTimelineRegionAdded(region);
@@ -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_) {
@@ -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');
@@ -2502,6 +2503,11 @@ shaka.media.StreamingEngine = class {
2502
2503
  * @private
2503
2504
  */
2504
2505
  async evict_(mediaState, presentationTime) {
2506
+ const segmentIndex = mediaState.stream.segmentIndex;
2507
+ if (segmentIndex instanceof shaka.media.MetaSegmentIndex) {
2508
+ segmentIndex.evictEmpty();
2509
+ }
2510
+
2505
2511
  const logPrefix = shaka.media.StreamingEngine.logPrefix_(mediaState);
2506
2512
  shaka.log.v2(logPrefix, 'checking buffer length');
2507
2513
 
package/lib/player.js CHANGED
@@ -8063,7 +8063,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
8063
8063
  * @export
8064
8064
  */
8065
8065
  // eslint-disable-next-line no-useless-concat
8066
- shaka.Player.version = 'v4.11.0' + '-uncompiled'; // x-release-please-version
8066
+ shaka.Player.version = 'v4.11.2' + '-uncompiled'; // x-release-please-version
8067
8067
 
8068
8068
  // Initialize the deprecation system using the version string we just set
8069
8069
  // 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) {
@@ -32,6 +32,10 @@ shaka.text.Utils = class {
32
32
  }).join('');
33
33
  }
34
34
 
35
+ if (!cue.payload) {
36
+ return cue.payload;
37
+ }
38
+
35
39
  // Handle bold, italics and underline
36
40
  const openStyleTags = [];
37
41
  const bold = cue.fontWeight >= shaka.text.Cue.fontWeight.BOLD;
@@ -272,14 +276,19 @@ shaka.text.Utils = class {
272
276
  const cue = new shaka.text.Cue(vttCue.startTime, vttCue.endTime,
273
277
  vttCue.text);
274
278
  cue.line = typeof vttCue.line === 'number' ? vttCue.line : null;
275
- cue.lineAlign = /** @type {shaka.text.Cue.lineAlign} */ (vttCue.lineAlign);
279
+ if (vttCue.lineAlign) {
280
+ cue.lineAlign = /** @type {shaka.text.Cue.lineAlign} */
281
+ (vttCue.lineAlign);
282
+ }
276
283
  cue.lineInterpretation = vttCue.snapToLines ?
277
284
  shaka.text.Cue.lineInterpretation.LINE_NUMBER :
278
285
  shaka.text.Cue.lineInterpretation.PERCENTAGE;
279
286
  cue.position = typeof vttCue.position === 'number' ?
280
287
  vttCue.position : null;
281
- cue.positionAlign = /** @type {shaka.text.Cue.positionAlign} */
282
- (vttCue.positionAlign);
288
+ if (vttCue.positionAlign) {
289
+ cue.positionAlign = /** @type {shaka.text.Cue.positionAlign} */
290
+ (vttCue.positionAlign);
291
+ }
283
292
  cue.size = vttCue.size;
284
293
  cue.textAlign = /** @type {shaka.text.Cue.textAlign} */ (vttCue.align);
285
294
  if (vttCue.vertical === 'lr') {
@@ -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
 
@@ -518,6 +519,24 @@ shaka.text.TtmlTextParser = class {
518
519
  return region;
519
520
  }
520
521
 
522
+ /**
523
+ * Ensures any TTML RGBA's alpha range of 0-255 is converted to 0-1.
524
+ * @param {string} color
525
+ * @return {string}
526
+ * @private
527
+ */
528
+ static convertTTMLrgbaToHTMLrgba_(color) {
529
+ const rgba = color.match(/rgba\(([^)]+)\)/);
530
+ if (rgba) {
531
+ const values = rgba[1].split(',');
532
+ if (values.length == 4) {
533
+ values[3] = String(Number(values[3]) / 255);
534
+ return 'rgba(' + values.join(',') + ')';
535
+ }
536
+ }
537
+ return color;
538
+ }
539
+
521
540
  /**
522
541
  * Adds applicable style properties to a cue.
523
542
  *
@@ -596,7 +615,7 @@ shaka.text.TtmlTextParser = class {
596
615
  const color = TtmlTextParser.getStyleAttribute_(
597
616
  cueElement, region, styles, 'color', shouldInheritRegionStyles);
598
617
  if (color) {
599
- cue.color = color;
618
+ cue.color = TtmlTextParser.convertTTMLrgbaToHTMLrgba_(color);
600
619
  }
601
620
 
602
621
  // Background color should not be set on a container. If this is a nested
@@ -610,7 +629,8 @@ shaka.text.TtmlTextParser = class {
610
629
  cueElement, region, styles, 'backgroundColor',
611
630
  shouldInheritRegionStyles);
612
631
  if (backgroundColor) {
613
- cue.backgroundColor = backgroundColor;
632
+ cue.backgroundColor =
633
+ TtmlTextParser.convertTTMLrgbaToHTMLrgba_(backgroundColor);
614
634
  }
615
635
 
616
636
  const border = TtmlTextParser.getStyleAttribute_(
@@ -719,7 +739,8 @@ shaka.text.TtmlTextParser = class {
719
739
  // There is no defined color, so default to the text color.
720
740
  cue.textStrokeColor = cue.color;
721
741
  } else {
722
- cue.textStrokeColor = split[0];
742
+ cue.textStrokeColor =
743
+ TtmlTextParser.convertTTMLrgbaToHTMLrgba_(split[0]);
723
744
  split.shift();
724
745
  }
725
746
  if (split[0] && split[0].match(TtmlTextParser.unitValues_)) {
@@ -852,7 +852,10 @@ shaka.util.PeriodCombiner = class {
852
852
  if (output.originalId == null) {
853
853
  output.originalId = input.originalId;
854
854
  } else {
855
- output.originalId += ',' + (input.originalId || '');
855
+ const newOriginalId = (input.originalId || '');
856
+ if (newOriginalId && !output.originalId.endsWith(newOriginalId)) {
857
+ output.originalId += ',' + newOriginalId;
858
+ }
856
859
  }
857
860
 
858
861
  const commonDrmInfos = shaka.util.DrmUtils.getCommonDrmInfos(
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.11.0",
4
+ "version": "4.11.2",
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;
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "AD_DURATION": "‏‮Ad‬‏ ‏‮duration‬‏",
3
3
  "AD_PROGRESS": "‏‮Ad‬‏ [AD_ON] ‏‮of‬‏ [NUM_ADS]",
4
+ "AD_STATISTICS": "‏‮Ad‬‏ ‏‮statistics‬‏",
4
5
  "AD_TIME": "‏‮Ad‬‏: [AD_TIME]",
6
+ "AIRPLAY": "‏‮AirPlay‬‏",
5
7
  "AUTO_QUALITY": "‏‮Auto‬‏",
6
8
  "BACK": "‏‮Back‬‏",
7
9
  "CAPTIONS": "‏‮Captions‬‏",
8
10
  "CAST": "‏‮Cast‬‏...",
11
+ "CHAPTERS": "‏‮Chapters‬‏",
12
+ "DOWNLOAD_VIDEO_FRAME": "‏‮Save‬‏ ‏‮video‬‏ ‏‮frame‬‏",
9
13
  "ENTER_LOOP_MODE": "‏‮Loop‬‏ ‏‮the‬‏ ‏‮current‬‏ ‏‮video‬‏",
10
14
  "ENTER_PICTURE_IN_PICTURE": "‏‮Enter‬‏ ‏‮Picture‬‏-‏‮in‬‏-‏‮Picture‬‏",
11
15
  "EXIT_FULL_SCREEN": "‏‮Exit‬‏ ‏‮full‬‏ ‏‮screen‬‏",
@@ -26,11 +30,18 @@
26
30
  "PICTURE_IN_PICTURE": "‏‮Picture‬‏-‏‮in‬‏-‏‮Picture‬‏",
27
31
  "PLAY": "‏‮Play‬‏",
28
32
  "PLAYBACK_RATE": "‏‮Playback‬‏ ‏‮speed‬‏",
33
+ "QUALITY": "‏‮Quality‬‏",
34
+ "RECENTER_VR": "‏‮Recenter‬‏",
35
+ "REPLAY": "‏‮Replay‬‏",
29
36
  "RESOLUTION": "‏‮Resolution‬‏",
30
37
  "REWIND": "‏‮Rewind‬‏",
31
38
  "SEEK": "‏‮Seek‬‏",
32
39
  "SKIP_AD": "‏‮Skip‬‏ ‏‮Ad‬‏",
33
40
  "SKIP_TO_LIVE": "‏‮Skip‬‏ ‏‮ahead‬‏ ‏‮to‬‏ ‏‮live‬‏",
41
+ "STATISTICS": "‏‮Statistics‬‏",
42
+ "SUBTITLE_FORCED": "‏‮Forced‬‏",
43
+ "SURROUND": "‏‮Surround‬‏",
44
+ "TOGGLE_STEREOSCOPIC": "‏‮Toggle‬‏ ‏‮stereoscopic‬‏",
34
45
  "UNDETERMINED_LANGUAGE": "‏‮Undetermined‬‏",
35
46
  "UNMUTE": "‏‮Unmute‬‏",
36
47
  "UNRECOGNIZED_LANGUAGE": "‏‮Unrecognized‬‏",
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "AD_DURATION": "مدة الإعلان",
3
3
  "AD_PROGRESS": "الإعلان [AD_ON] من [NUM_ADS]",
4
+ "AD_STATISTICS": "إحصاءات الإعلانات",
4
5
  "AD_TIME": "الإعلان: [AD_TIME]",
6
+ "AIRPLAY": "AirPlay",
5
7
  "AUTO_QUALITY": "تلقائي",
6
8
  "BACK": "رجوع",
7
9
  "CAPTIONS": "الترجمة والشرح",
8
10
  "CAST": "إرسال...",
11
+ "CHAPTERS": "الفصول",
12
+ "DOWNLOAD_VIDEO_FRAME": "حفظ إطار الفيديو",
9
13
  "ENTER_LOOP_MODE": "تكرار الفيديو الحالي",
10
14
  "ENTER_PICTURE_IN_PICTURE": "الدخول في وضع \"نافذة ضمن نافذة\"",
11
15
  "EXIT_FULL_SCREEN": "إنهاء وضع ملء الشاشة",
@@ -26,11 +30,18 @@
26
30
  "PICTURE_IN_PICTURE": "نافذة ضمن النافذة",
27
31
  "PLAY": "التشغيل",
28
32
  "PLAYBACK_RATE": "سرعة التشغيل",
33
+ "QUALITY": "الجودة",
34
+ "RECENTER_VR": "إعادة التوسيط",
35
+ "REPLAY": "إعادة التشغيل",
29
36
  "RESOLUTION": "درجة الدقة",
30
37
  "REWIND": "ترجيع",
31
38
  "SEEK": "البحث بالتمرير",
32
39
  "SKIP_AD": "تخطّي الإعلان",
33
40
  "SKIP_TO_LIVE": "الانتقال إلى بث مباشر",
41
+ "STATISTICS": "الإحصاءات",
42
+ "SUBTITLE_FORCED": "عرض إجباري",
43
+ "SURROUND": "صوت محيطي",
44
+ "TOGGLE_STEREOSCOPIC": "إيقاف العرض المجسّم أو تفعيله",
34
45
  "UNDETERMINED_LANGUAGE": "غير محدد",
35
46
  "UNMUTE": "إعادة الصوت",
36
47
  "UNRECOGNIZED_LANGUAGE": "غير معروف",
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "AD_DURATION": "Времетраене на рекламата",
3
3
  "AD_PROGRESS": "Реклама [AD_ON] от [NUM_ADS]",
4
+ "AD_STATISTICS": "Статистически данни за рекламата",
4
5
  "AD_TIME": "Реклама: [AD_TIME]",
6
+ "AIRPLAY": "AirPlay",
5
7
  "AUTO_QUALITY": "Автоматично",
6
8
  "BACK": "Назад",
7
9
  "CAPTIONS": "Надписи",
8
10
  "CAST": "Предаване...",
11
+ "CHAPTERS": "Глави",
12
+ "DOWNLOAD_VIDEO_FRAME": "Запазване на кадъра от видеоклипа",
9
13
  "ENTER_LOOP_MODE": "Повтаряне на текущия видеоклип",
10
14
  "ENTER_PICTURE_IN_PICTURE": "Преминаване в режим „Картина в картината“",
11
15
  "EXIT_FULL_SCREEN": "Изход от цял екран",
@@ -26,11 +30,18 @@
26
30
  "PICTURE_IN_PICTURE": "Картина в картината",
27
31
  "PLAY": "Пускане",
28
32
  "PLAYBACK_RATE": "Скорост на възпроизвеждане",
33
+ "QUALITY": "Качество",
34
+ "RECENTER_VR": "Повторно центриране",
35
+ "REPLAY": "Повторно пускане",
29
36
  "RESOLUTION": "Разделителна способност",
30
37
  "REWIND": "Превъртане назад",
31
38
  "SEEK": "Търсене",
32
39
  "SKIP_AD": "Пропускане на рекламата",
33
40
  "SKIP_TO_LIVE": "Преминаване напред към предаването на живо",
41
+ "STATISTICS": "Статистически данни",
42
+ "SUBTITLE_FORCED": "Принудително",
43
+ "SURROUND": "Съраунд",
44
+ "TOGGLE_STEREOSCOPIC": "Превключване на стереоскопичния режим",
34
45
  "UNDETERMINED_LANGUAGE": "Неопределено",
35
46
  "UNMUTE": "Включване на звука",
36
47
  "UNRECOGNIZED_LANGUAGE": "Неразпознато",
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "AD_DURATION": "Durada de l'anunci",
3
3
  "AD_PROGRESS": "Anunci [AD_ON] de [NUM_ADS]",
4
+ "AD_STATISTICS": "Estadístiques dels anuncis",
4
5
  "AD_TIME": "Anunci: [AD_TIME]",
6
+ "AIRPLAY": "AirPlay",
5
7
  "AUTO_QUALITY": "Automàtic",
6
8
  "BACK": "Torna",
7
9
  "CAPTIONS": "Subtítols",
8
10
  "CAST": "Emet…",
11
+ "CHAPTERS": "Capítols",
12
+ "DOWNLOAD_VIDEO_FRAME": "Desa el fotograma del vídeo",
9
13
  "ENTER_LOOP_MODE": "Reprodueix en bucle el vídeo actual",
10
14
  "ENTER_PICTURE_IN_PICTURE": "Entra al mode de pantalla en pantalla",
11
15
  "EXIT_FULL_SCREEN": "Surt del mode de pantalla completa",
@@ -26,11 +30,18 @@
26
30
  "PICTURE_IN_PICTURE": "Pantalla en pantalla",
27
31
  "PLAY": "Reprodueix",
28
32
  "PLAYBACK_RATE": "Velocitat de reproducció",
33
+ "QUALITY": "Qualitat",
34
+ "RECENTER_VR": "Torna a centrar",
35
+ "REPLAY": "Torna a reproduir",
29
36
  "RESOLUTION": "Resolució",
30
37
  "REWIND": "Rebobina",
31
38
  "SEEK": "Cerca",
32
39
  "SKIP_AD": "Omet l'anunci",
33
40
  "SKIP_TO_LIVE": "Passa a l'emissió en directe",
41
+ "STATISTICS": "Estadístiques",
42
+ "SUBTITLE_FORCED": "Forçat",
43
+ "SURROUND": "So envoltant",
44
+ "TOGGLE_STEREOSCOPIC": "Commuta l'opció estereoscòpica",
34
45
  "UNDETERMINED_LANGUAGE": "Sense especificar",
35
46
  "UNMUTE": "Deixa de silenciar",
36
47
  "UNRECOGNIZED_LANGUAGE": "No reconegut",
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "AD_DURATION": "Délka reklamy",
3
3
  "AD_PROGRESS": "Reklama [AD_ON] z [NUM_ADS]",
4
+ "AD_STATISTICS": "Statistiky reklam",
4
5
  "AD_TIME": "Reklama: [AD_TIME]",
6
+ "AIRPLAY": "AirPlay",
5
7
  "AUTO_QUALITY": "Automaticky",
6
8
  "BACK": "Zpět",
7
9
  "CAPTIONS": "Titulky",
8
10
  "CAST": "Odeslat…",
11
+ "CHAPTERS": "Kapitoly",
12
+ "DOWNLOAD_VIDEO_FRAME": "Uložit snímek videa",
9
13
  "ENTER_LOOP_MODE": "Přehrávat toto video ve smyčce",
10
14
  "ENTER_PICTURE_IN_PICTURE": "Spustit režim obrazu v obraze",
11
15
  "EXIT_FULL_SCREEN": "Ukončit režim celé obrazovky",
@@ -26,11 +30,18 @@
26
30
  "PICTURE_IN_PICTURE": "Obraz v obraze",
27
31
  "PLAY": "Přehrát",
28
32
  "PLAYBACK_RATE": "Rychlost přehrávání",
33
+ "QUALITY": "Kvalita",
34
+ "RECENTER_VR": "Znovu vycentrovat",
35
+ "REPLAY": "Přehrát znovu",
29
36
  "RESOLUTION": "Rozlišení",
30
37
  "REWIND": "Přetočit zpět",
31
38
  "SEEK": "Posuvník přehrávání",
32
39
  "SKIP_AD": "Přeskočit reklamu",
33
40
  "SKIP_TO_LIVE": "Přeskočit na živé vysílání",
41
+ "STATISTICS": "Statistiky",
42
+ "SUBTITLE_FORCED": "Vynuceno",
43
+ "SURROUND": "Prostorový zvuk",
44
+ "TOGGLE_STEREOSCOPIC": "Přepnout stereoskopické zobrazení",
34
45
  "UNDETERMINED_LANGUAGE": "Neurčeno",
35
46
  "UNMUTE": "Zapnout zvuk",
36
47
  "UNRECOGNIZED_LANGUAGE": "Neznámé",
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "AD_DURATION": "Annoncevarighed",
3
3
  "AD_PROGRESS": "Annonce [AD_ON] af [NUM_ADS]",
4
+ "AD_STATISTICS": "Annoncestatistik",
4
5
  "AD_TIME": "Annonce: [AD_TIME]",
6
+ "AIRPLAY": "AirPlay",
5
7
  "AUTO_QUALITY": "Auto",
6
8
  "BACK": "Tilbage",
7
9
  "CAPTIONS": "Undertekster",
8
10
  "CAST": "Cast...",
11
+ "CHAPTERS": "Kapitler",
12
+ "DOWNLOAD_VIDEO_FRAME": "Gem videoramme",
9
13
  "ENTER_LOOP_MODE": "Gentag afspilning af aktuel video",
10
14
  "ENTER_PICTURE_IN_PICTURE": "Åbn integreret billede",
11
15
  "EXIT_FULL_SCREEN": "Afslut fuld skærm",
@@ -26,11 +30,18 @@
26
30
  "PICTURE_IN_PICTURE": "Integreret billede",
27
31
  "PLAY": "Afspil",
28
32
  "PLAYBACK_RATE": "Afspilningshastighed",
33
+ "QUALITY": "Kvalitet",
34
+ "RECENTER_VR": "Centrér igen",
35
+ "REPLAY": "Afspil igen",
29
36
  "RESOLUTION": "Opløsning",
30
37
  "REWIND": "Spol tilbage",
31
38
  "SEEK": "Hop",
32
39
  "SKIP_AD": "Spring annonce over",
33
40
  "SKIP_TO_LIVE": "Gå videre til liveudsendelse",
41
+ "STATISTICS": "Statistik",
42
+ "SUBTITLE_FORCED": "Gennemtvunget",
43
+ "SURROUND": "Surroundsound",
44
+ "TOGGLE_STEREOSCOPIC": "Slå stereoskopisk visning til/fra",
34
45
  "UNDETERMINED_LANGUAGE": "Ikke fastslået",
35
46
  "UNMUTE": "Slå lyden til",
36
47
  "UNRECOGNIZED_LANGUAGE": "Ikke genkendt",
@@ -1,16 +1,20 @@
1
1
  {
2
2
  "AD_DURATION": "Dauer der Werbeanzeige",
3
3
  "AD_PROGRESS": "Werbung [AD_ON] von [NUM_ADS]",
4
+ "AD_STATISTICS": "Anzeigenstatistiken",
4
5
  "AD_TIME": "Werbeanzeige: [AD_TIME]",
6
+ "AIRPLAY": "AirPlay",
5
7
  "AUTO_QUALITY": "Automatisch",
6
8
  "BACK": "Zurück",
7
9
  "CAPTIONS": "Untertitel",
8
10
  "CAST": "Streamen...",
11
+ "CHAPTERS": "Kapitel",
12
+ "DOWNLOAD_VIDEO_FRAME": "Videoframe speichern",
9
13
  "ENTER_LOOP_MODE": "In Endlosschleife spielen",
10
- "ENTER_PICTURE_IN_PICTURE": "Bild-im-Bild-Modus aktivieren",
14
+ "ENTER_PICTURE_IN_PICTURE": "Bild im Bild aktivieren",
11
15
  "EXIT_FULL_SCREEN": "Vollbildmodus beenden",
12
16
  "EXIT_LOOP_MODE": "Endlosschleife stoppen",
13
- "EXIT_PICTURE_IN_PICTURE": "Bild-im-Bild-Modus beenden",
17
+ "EXIT_PICTURE_IN_PICTURE": "Bild im Bild beenden",
14
18
  "FAST_FORWARD": "Vorspulen",
15
19
  "FULL_SCREEN": "Vollbildmodus",
16
20
  "LANGUAGE": "Sprache",
@@ -26,11 +30,18 @@
26
30
  "PICTURE_IN_PICTURE": "Bild im Bild",
27
31
  "PLAY": "Wiedergabe",
28
32
  "PLAYBACK_RATE": "Geschwindigkeit",
33
+ "QUALITY": "Qualität",
34
+ "RECENTER_VR": "Zentrieren",
35
+ "REPLAY": "Noch einmal wiedergeben",
29
36
  "RESOLUTION": "Auflösung",
30
37
  "REWIND": "Zurückspulen",
31
38
  "SEEK": "Suche",
32
39
  "SKIP_AD": "Überspringen",
33
40
  "SKIP_TO_LIVE": "Zum Live-Videostream wechseln",
41
+ "STATISTICS": "Statistiken",
42
+ "SUBTITLE_FORCED": "Erzwungen",
43
+ "SURROUND": "Surround",
44
+ "TOGGLE_STEREOSCOPIC": "Einstellung „stereoskopisch“ ein‑/ausschalten",
34
45
  "UNDETERMINED_LANGUAGE": "Unbestimmt",
35
46
  "UNMUTE": "Stummschaltung aufheben",
36
47
  "UNRECOGNIZED_LANGUAGE": "Unbekannt",
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "AD_DURATION": "Διάρκεια διαφήμισης",
3
3
  "AD_PROGRESS": "Διαφήμιση [AD_ON] από [NUM_ADS]",
4
+ "AD_STATISTICS": "Στατιστικά στοιχεία διαφήμισης",
4
5
  "AD_TIME": "Διαφήμιση: [AD_TIME]",
6
+ "AIRPLAY": "AirPlay",
5
7
  "AUTO_QUALITY": "Αυτόματα",
6
8
  "BACK": "Πίσω",
7
9
  "CAPTIONS": "Υπότιτλοι",
8
10
  "CAST": "Μετάδοση…",
11
+ "CHAPTERS": "Κεφάλαια",
12
+ "DOWNLOAD_VIDEO_FRAME": "Αποθήκευση καρέ βίντεο",
9
13
  "ENTER_LOOP_MODE": "Αναπαραγωγή τρέχοντος βίντεο σε επανάληψη",
10
14
  "ENTER_PICTURE_IN_PICTURE": "Είσοδος στη λειτουργία picture-in-picture",
11
15
  "EXIT_FULL_SCREEN": "Έξοδος από πλήρη οθόνη",
@@ -26,11 +30,18 @@
26
30
  "PICTURE_IN_PICTURE": "Picture-in-picture",
27
31
  "PLAY": "Αναπαραγωγή",
28
32
  "PLAYBACK_RATE": "Ταχύτητα αναπαραγωγής",
33
+ "QUALITY": "Ποιότητα",
34
+ "RECENTER_VR": "Εκ νέου κεντράρισμα",
35
+ "REPLAY": "Επανάληψη",
29
36
  "RESOLUTION": "Ανάλυση",
30
37
  "REWIND": "Επαναφορά",
31
38
  "SEEK": "Αναζήτηση",
32
39
  "SKIP_AD": "Παράβλεψη διαφήμισης",
33
40
  "SKIP_TO_LIVE": "Μετάβαση στη ζωντανή μετάδοση",
41
+ "STATISTICS": "Στατιστικά στοιχεία",
42
+ "SUBTITLE_FORCED": "Αναγκαστικό",
43
+ "SURROUND": "Surround",
44
+ "TOGGLE_STEREOSCOPIC": "Εναλλαγή στερεοσκοπικής",
34
45
  "UNDETERMINED_LANGUAGE": "Δεν έχει καθοριστεί",
35
46
  "UNMUTE": "Κατάργηση σίγασης",
36
47
  "UNRECOGNIZED_LANGUAGE": "Μη αναγνωρίσιμο",
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "AD_DURATION": "Ad duration",
3
3
  "AD_PROGRESS": "Ad [AD_ON] of [NUM_ADS]",
4
+ "AD_STATISTICS": "Ad statistics",
4
5
  "AD_TIME": "Ad: [AD_TIME]",
6
+ "AIRPLAY": "AirPlay",
5
7
  "AUTO_QUALITY": "Auto",
6
8
  "BACK": "Back",
7
9
  "CAPTIONS": "Captions",
8
10
  "CAST": "Cast...",
11
+ "CHAPTERS": "Chapters",
12
+ "DOWNLOAD_VIDEO_FRAME": "Save video frame",
9
13
  "ENTER_LOOP_MODE": "Loop the current video",
10
14
  "ENTER_PICTURE_IN_PICTURE": "Enter picture-in-picture",
11
15
  "EXIT_FULL_SCREEN": "Exit full screen",
@@ -26,12 +30,17 @@
26
30
  "PICTURE_IN_PICTURE": "Picture-in-picture",
27
31
  "PLAY": "Play",
28
32
  "PLAYBACK_RATE": "Playback speed",
29
- "RECENTER_VR": "Recenter",
33
+ "QUALITY": "Quality",
34
+ "RECENTER_VR": "Recentre",
35
+ "REPLAY": "Replay",
30
36
  "RESOLUTION": "Resolution",
31
37
  "REWIND": "Rewind",
32
38
  "SEEK": "Seek",
33
39
  "SKIP_AD": "Skip ad",
34
40
  "SKIP_TO_LIVE": "Skip ahead to live",
41
+ "STATISTICS": "Statistics",
42
+ "SUBTITLE_FORCED": "Forced",
43
+ "SURROUND": "Surround",
35
44
  "TOGGLE_STEREOSCOPIC": "Toggle stereoscopic",
36
45
  "UNDETERMINED_LANGUAGE": "Undetermined",
37
46
  "UNMUTE": "Unmute",