shaka-player 3.1.3 → 3.1.4

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 (94) hide show
  1. package/AUTHORS +3 -0
  2. package/CHANGELOG.md +56 -0
  3. package/CONTRIBUTORS +3 -0
  4. package/build/generateExterns.js +1 -1
  5. package/demo/common/assets.js +1 -1
  6. package/dist/controls.css +2 -2
  7. package/dist/controls.css.map +1 -1
  8. package/dist/demo.compiled.debug.js +1 -1
  9. package/dist/demo.compiled.js +1 -1
  10. package/dist/deps.js +1 -1
  11. package/dist/locales.js +35 -35
  12. package/dist/receiver.compiled.debug.js +1 -1
  13. package/dist/receiver.compiled.js +1 -1
  14. package/dist/shaka-player.compiled.d.ts +1 -1
  15. package/dist/shaka-player.compiled.debug.d.ts +1 -1
  16. package/dist/shaka-player.compiled.debug.externs.js +1 -1
  17. package/dist/shaka-player.compiled.debug.js +187 -183
  18. package/dist/shaka-player.compiled.debug.map +3 -3
  19. package/dist/shaka-player.compiled.externs.js +1 -1
  20. package/dist/shaka-player.compiled.js +799 -799
  21. package/dist/shaka-player.compiled.map +2 -2
  22. package/dist/shaka-player.ui.d.ts +1 -1
  23. package/dist/shaka-player.ui.debug.d.ts +1 -1
  24. package/dist/shaka-player.ui.debug.externs.js +3 -3
  25. package/dist/shaka-player.ui.debug.js +264 -260
  26. package/dist/shaka-player.ui.debug.map +4 -4
  27. package/dist/shaka-player.ui.externs.js +3 -3
  28. package/dist/shaka-player.ui.js +896 -895
  29. package/dist/shaka-player.ui.map +4 -4
  30. package/docs/tutorials/fairplay.md +1 -1
  31. package/karma.conf.js +1 -0
  32. package/lib/ads/client_side_ad_manager.js +46 -86
  33. package/lib/ads/server_side_ad_manager.js +7 -10
  34. package/lib/cast/cast_proxy.js +3 -2
  35. package/lib/cast/cast_receiver.js +2 -1
  36. package/lib/cast/cast_sender.js +2 -2
  37. package/lib/dash/dash_parser.js +93 -2
  38. package/lib/dash/segment_list.js +1 -1
  39. package/lib/dash/segment_template.js +1 -1
  40. package/lib/hls/hls_parser.js +30 -17
  41. package/lib/media/drm_engine.js +7 -0
  42. package/lib/media/gap_jumping_controller.js +4 -2
  43. package/lib/media/media_source_engine.js +1 -2
  44. package/lib/media/streaming_engine.js +2 -1
  45. package/lib/net/networking_engine.js +2 -1
  46. package/lib/player.js +22 -22
  47. package/lib/polyfill/media_capabilities.js +7 -1
  48. package/lib/polyfill/mediasource.js +6 -0
  49. package/lib/polyfill/orientation.js +1 -1
  50. package/lib/polyfill/patchedmediakeys_apple.js +4 -4
  51. package/lib/polyfill/patchedmediakeys_ms.js +4 -4
  52. package/lib/polyfill/patchedmediakeys_webkit.js +4 -4
  53. package/lib/text/mp4_ttml_parser.js +3 -0
  54. package/lib/text/text_engine.js +14 -2
  55. package/lib/text/ttml_text_parser.js +5 -0
  56. package/lib/text/ui_text_displayer.js +85 -37
  57. package/lib/util/fake_event.js +53 -7
  58. package/lib/util/periods.js +4 -1
  59. package/lib/util/platform.js +13 -1
  60. package/lib/util/stream_utils.js +13 -0
  61. package/package.json +1 -1
  62. package/test/cast/cast_proxy_unit.js +12 -6
  63. package/test/cast/cast_utils_unit.js +1 -1
  64. package/test/dash/dash_parser_manifest_unit.js +187 -1
  65. package/test/hls/hls_parser_unit.js +5 -1
  66. package/test/media/closed_caption_parser_unit.js +6 -1
  67. package/test/media/drm_engine_unit.js +43 -0
  68. package/test/player_integration.js +38 -0
  69. package/test/test/assets/3675/chunk-stream0-00001.m4s +0 -0
  70. package/test/test/assets/3675/chunk-stream0-00002.m4s +0 -0
  71. package/test/test/assets/3675/chunk-stream0-00003.m4s +0 -0
  72. package/test/test/assets/3675/chunk-stream0-00004.m4s +0 -0
  73. package/test/test/assets/3675/chunk-stream0-00005.m4s +0 -0
  74. package/test/test/assets/3675/chunk-stream0-00006.m4s +0 -0
  75. package/test/test/assets/3675/chunk-stream0-00007.m4s +0 -0
  76. package/test/test/assets/3675/dash_0.mpd +30 -0
  77. package/test/test/assets/3675/dash_1.mpd +30 -0
  78. package/test/test/assets/3675/dash_2.mpd +30 -0
  79. package/test/test/assets/3675/dash_3.mpd +30 -0
  80. package/test/test/assets/3675/dash_4.mpd +30 -0
  81. package/test/test/assets/3675/dash_5.mpd +26 -0
  82. package/test/test/assets/3675/init-stream0.m4s +0 -0
  83. package/test/test/util/fake_ad_manager.js +1 -1
  84. package/test/text/ttml_text_parser_unit.js +9 -0
  85. package/test/text/ui_text_displayer_unit.js +29 -17
  86. package/test/ui/localization_unit.js +15 -14
  87. package/test/ui/text_displayer_layout_unit.js +13 -1
  88. package/test/util/stream_utils_unit.js +35 -0
  89. package/ui/cast_button.js +2 -3
  90. package/ui/controls.js +4 -6
  91. package/ui/less/containers.less +3 -7
  92. package/ui/locales/ru.json +6 -6
  93. package/ui/localization.js +28 -51
  94. package/ui/pip_button.js +2 -3
@@ -0,0 +1,26 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
+ xmlns="urn:mpeg:dash:schema:mpd:2011"
4
+ xmlns:xlink="http://www.w3.org/1999/xlink"
5
+ xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
6
+ profiles="urn:mpeg:dash:profile:isoff-live:2011"
7
+ type="static"
8
+ mediaPresentationDuration="PT14.0S"
9
+ maxSegmentDuration="PT2.0S"
10
+ minBufferTime="PT4.0S">
11
+ <ProgramInformation>
12
+ </ProgramInformation>
13
+ <ServiceDescription id="0">
14
+ </ServiceDescription>
15
+ <Period id="0" start="PT0.0S">
16
+ <AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
17
+ <Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
18
+ <SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="3">
19
+ <SegmentTimeline>
20
+ <S t="61440" d="30720" r="4" />
21
+ </SegmentTimeline>
22
+ </SegmentTemplate>
23
+ </Representation>
24
+ </AdaptationSet>
25
+ </Period>
26
+ </MPD>
@@ -78,7 +78,7 @@ shaka.test.FakeAdManager = class extends shaka.util.FakeEventTarget {
78
78
  */
79
79
  startAd(ad) {
80
80
  const event = new shaka.util.FakeEvent(shaka.ads.AdManager.AD_STARTED,
81
- {'ad': ad});
81
+ (new Map()).set('ad', ad));
82
82
 
83
83
  this.dispatchEvent(event);
84
84
  }
@@ -476,6 +476,15 @@ describe('TtmlTextParser', () => {
476
476
  {periodStart: 0, segmentStart: 0, segmentEnd: 0});
477
477
  });
478
478
 
479
+ it('supports comments in the body', () => {
480
+ verifyHelper(
481
+ [],
482
+ '<tt><body><div>' +
483
+ '<!-- text-based TTML -->' +
484
+ '</div></body></tt>',
485
+ {periodStart: 0, segmentStart: 0, segmentEnd: 0});
486
+ });
487
+
479
488
  it('parses alignment from textAlign attribute of a region', () => {
480
489
  verifyHelper(
481
490
  [
@@ -84,20 +84,16 @@ describe('UITextDisplayer', () => {
84
84
  // Wait until updateCaptions_() gets called.
85
85
  await shaka.test.Util.delay(0.5);
86
86
 
87
- const textContainer =
88
- videoContainer.querySelector('.shaka-text-container');
89
- const captions =
90
- textContainer.querySelector('span:not(.shaka-text-wrapper)');
87
+ const textContainer = videoContainer.querySelector('.shaka-text-container');
88
+ const captions = textContainer.querySelector('div');
91
89
  const cssObj = parseCssText(captions.style.cssText);
92
90
 
93
91
  const expectCssObj = {
94
92
  'color': 'green',
95
- 'background-color': 'black',
96
93
  'direction': 'ltr',
97
94
  'font-size': '10px',
98
95
  'font-style': 'normal',
99
96
  'font-weight': 400,
100
- 'line-height': 2,
101
97
  'text-align': 'center',
102
98
  };
103
99
 
@@ -114,6 +110,8 @@ describe('UITextDisplayer', () => {
114
110
  }
115
111
 
116
112
  expect(cssObj).toEqual(jasmine.objectContaining(expectCssObj));
113
+ expect(parseCssText(textContainer.querySelector('span').style.cssText))
114
+ .toEqual(jasmine.objectContaining({'background-color': 'black'}));
117
115
  });
118
116
 
119
117
  it('correctly displays styles for nested cues', async () => {
@@ -137,15 +135,13 @@ describe('UITextDisplayer', () => {
137
135
  await shaka.test.Util.delay(0.5);
138
136
 
139
137
  // Verify styles applied to the nested cues.
140
- const textContainer =
141
- videoContainer.querySelector('.shaka-text-container');
138
+ const textContainer = videoContainer.querySelector('.shaka-text-container');
142
139
  const captions =
143
140
  textContainer.querySelector('span:not(.shaka-text-wrapper)');
144
141
  const cssObj = parseCssText(captions.style.cssText);
145
142
 
146
143
  const expectCssObj = {
147
144
  'color': 'green',
148
- 'background-color': 'black',
149
145
  'font-size': '10px',
150
146
  'font-style': 'normal',
151
147
  'font-weight': 400,
@@ -165,6 +161,8 @@ describe('UITextDisplayer', () => {
165
161
  }
166
162
 
167
163
  expect(cssObj).toEqual(jasmine.objectContaining(expectCssObj));
164
+ expect(parseCssText(captions.querySelector('span').style.cssText))
165
+ .toEqual(jasmine.objectContaining({'background-color': 'black'}));
168
166
  });
169
167
 
170
168
  it('correctly displays styles for cellResolution units', async () => {
@@ -191,10 +189,8 @@ describe('UITextDisplayer', () => {
191
189
  // style.
192
190
  const expectedLinePadding = '11.25px';
193
191
 
194
- const textContainer =
195
- videoContainer.querySelector('.shaka-text-container');
196
- const captions =
197
- textContainer.querySelector('span:not(.shaka-text-wrapper)');
192
+ const textContainer = videoContainer.querySelector('.shaka-text-container');
193
+ const captions = textContainer.querySelector('div');
198
194
  const cssObj = parseCssText(captions.style.cssText);
199
195
  expect(cssObj).toEqual(
200
196
  jasmine.objectContaining({
@@ -222,10 +218,8 @@ describe('UITextDisplayer', () => {
222
218
  // videoContainerHeight=450px and tts:fontSize="90%" on the default style.
223
219
  const expectedFontSize = '27px';
224
220
 
225
- const textContainer =
226
- videoContainer.querySelector('.shaka-text-container');
227
- const captions =
228
- textContainer.querySelector('span:not(.shaka-text-wrapper)');
221
+ const textContainer = videoContainer.querySelector('.shaka-text-container');
222
+ const captions = textContainer.querySelector('div');
229
223
  const cssObj = parseCssText(captions.style.cssText);
230
224
  expect(cssObj).toEqual(
231
225
  jasmine.objectContaining({'font-size': expectedFontSize}));
@@ -319,6 +313,24 @@ describe('UITextDisplayer', () => {
319
313
  expect(captions.length).toBe(3);
320
314
  });
321
315
 
316
+ it('hides currently displayed cue when removed', async () => {
317
+ const cue = new shaka.text.Cue(0, 50, 'One');
318
+ textDisplayer.setTextVisibility(true);
319
+ textDisplayer.append([cue]);
320
+ video.currentTime = 10;
321
+ await shaka.test.Util.delay(0.5);
322
+ const textContainer = videoContainer.querySelector('.shaka-text-container');
323
+
324
+ let cueElements = textContainer.querySelectorAll('div');
325
+ expect(cueElements.length).toBe(1);
326
+ expect(cueElements[0].textContent).toBe('One');
327
+
328
+ textDisplayer.remove(0, 100);
329
+
330
+ cueElements = textContainer.querySelectorAll('div');
331
+ expect(cueElements.length).toBe(0);
332
+ });
333
+
322
334
  it('hides and shows nested cues at appropriate times', async () => {
323
335
  const parentCue1 = new shaka.text.Cue(0, 100, '');
324
336
  const cue1 = new shaka.text.Cue(0, 50, 'One');
@@ -198,7 +198,7 @@ describe('Localization', () => {
198
198
  localization.changeLocale([ELVISH_WOODLAND]);
199
199
 
200
200
  expect(events.length).toBe(1);
201
- expect(events[0].locales).toEqual([ELVISH_WOODLAND]);
201
+ expect(events[0]['locales']).toEqual([ELVISH_WOODLAND]);
202
202
  });
203
203
 
204
204
 
@@ -214,23 +214,23 @@ describe('Localization', () => {
214
214
  localization.changeLocale([ELVISH_WOODLAND, DWARFISH_NORTH]);
215
215
 
216
216
  expect(events.length).toBe(1);
217
- expect(events[0].locales).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]);
217
+ expect(events[0]['locales']).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]);
218
218
 
219
219
  // We should see an event telling us that dwarfish is still missing.
220
220
  localization.insert(ELVISH_WOODLAND, new Map());
221
221
  localization.changeLocale([ELVISH_WOODLAND, DWARFISH_NORTH]);
222
222
 
223
223
  expect(events.length).toBe(2);
224
- expect(events[0].locales).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]);
225
- expect(events[1].locales).toEqual([DWARFISH_NORTH]);
224
+ expect(events[0]['locales']).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]);
225
+ expect(events[1]['locales']).toEqual([DWARFISH_NORTH]);
226
226
 
227
227
  // There should be no more events now that we added the last language.
228
228
  localization.insert(DWARFISH_NORTH, new Map());
229
229
  localization.changeLocale([ELVISH_WOODLAND, DWARFISH_NORTH]);
230
230
 
231
231
  expect(events.length).toBe(2);
232
- expect(events[0].locales).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]);
233
- expect(events[1].locales).toEqual([DWARFISH_NORTH]);
232
+ expect(events[0]['locales']).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]);
233
+ expect(events[1]['locales']).toEqual([DWARFISH_NORTH]);
234
234
  });
235
235
  });
236
236
 
@@ -373,8 +373,8 @@ describe('Localization', () => {
373
373
  // it was in the fallback (HALFLING) but not our preferred language
374
374
  // (EVLISH).
375
375
  expect(events.length).toBe(1);
376
- expect(events[0].locales).toEqual([ELVISH_WOODLAND]);
377
- expect(events[0].missing).toEqual(['hello']);
376
+ expect(events[0]['locales']).toEqual([ELVISH_WOODLAND]);
377
+ expect(events[0]['missing']).toEqual(['hello']);
378
378
  });
379
379
 
380
380
  it('fires when key/value is missing from preferred but found in base',
@@ -400,8 +400,8 @@ describe('Localization', () => {
400
400
  // because it was in the base (ELVISH) but not our preferred language
401
401
  // (EVLISH_WOODLAND).
402
402
  expect(events.length).toBe(1);
403
- expect(events[0].locales).toEqual([ELVISH_WOODLAND]);
404
- expect(events[0].missing).toEqual(['Best Wishes']);
403
+ expect(events[0]['locales']).toEqual([ELVISH_WOODLAND]);
404
+ expect(events[0]['missing']).toEqual(['Best Wishes']);
405
405
  });
406
406
 
407
407
  it('fires when key/value is missing from preferred but found in sibling',
@@ -427,8 +427,8 @@ describe('Localization', () => {
427
427
  // understand" because it was in a sibling locale (HALFLING_SHIRE)
428
428
  // but not our preferred language (HALFLING_COMMON).
429
429
  expect(events.length).toBe(1);
430
- expect(events[0].locales).toEqual([HALFLING_COMMON]);
431
- expect(events[0].missing).toEqual(['Do you understand']);
430
+ expect(events[0]['locales']).toEqual([HALFLING_COMMON]);
431
+ expect(events[0]['missing']).toEqual(['Do you understand']);
432
432
  });
433
433
 
434
434
  it('fires when key/value is missing from some preferred languages',
@@ -454,8 +454,9 @@ describe('Localization', () => {
454
454
 
455
455
  // There should have no missing localization events.
456
456
  expect(events.length).toBe(1);
457
- expect(events[0].locales).toEqual([ELVISH_WOODLAND, DWARFISH_NORTH]);
458
- expect(events[0].missing).toEqual(['may your forge burn bright']);
457
+ expect(events[0]['locales']).toEqual(
458
+ [ELVISH_WOODLAND, DWARFISH_NORTH]);
459
+ expect(events[0]['missing']).toEqual(['may your forge burn bright']);
459
460
  });
460
461
  });
461
462
 
@@ -141,7 +141,9 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
141
141
  cue.region.id = '1';
142
142
  // Position the cue *explicitly* at the bottom of the screen.
143
143
  cue.region.viewportAnchorX = 0; // %
144
- cue.region.viewportAnchorY = 100; // %
144
+ cue.region.viewportAnchorY = 90; // %
145
+ cue.region.width = 100; // %
146
+ cue.region.height = 10; // %
145
147
  textDisplayer.append([cue]);
146
148
 
147
149
  await checkScreenshot('ui', 'cue-with-controls');
@@ -314,6 +316,16 @@ filterDescribe('TextDisplayer layout', supportsScreenshots, () => {
314
316
  await checkScreenshot(prefix, 'nested-cues-with-linebreak');
315
317
  });
316
318
 
319
+ // Regression test for #3600
320
+ it('cue positioning', async () => {
321
+ const cue = new shaka.text.Cue(0, 1, 'Text');
322
+ cue.line = 10;
323
+ cue.lineInterpretation = shaka.text.Cue.lineInterpretation.PERCENTAGE;
324
+ textDisplayer.append([cue]);
325
+
326
+ await checkScreenshot(prefix, 'cue-position');
327
+ });
328
+
317
329
  // Regression test for #2157 and #2584
318
330
  it('region positioning', async () => {
319
331
  const nestedCue = new shaka.text.Cue(
@@ -537,6 +537,41 @@ describe('StreamUtils', () => {
537
537
  expect(manifest.variants.length).toBe(1);
538
538
  expect(manifest.variants[0].decodingInfos.length).toBe(0);
539
539
  });
540
+
541
+ it('includes transferFunction in config when hdr', async () => {
542
+ window.shakaMediaCapabilities.decodingInfo =
543
+ shaka.test.Util.spyFunc(decodingInfoSpy);
544
+
545
+ manifest = shaka.test.ManifestGenerator.generate((manifest) => {
546
+ manifest.addVariant(0, (variant) => {
547
+ variant.addVideo(0, (stream) => {
548
+ stream.mime('video/mp4', 'avc1.640028');
549
+ stream.hdr = 'SDR';
550
+ });
551
+ });
552
+ manifest.addVariant(1, (variant) => {
553
+ variant.addVideo(1, (stream) => {
554
+ stream.mime('video/mp4', 'hvc1.2.4.L150.90');
555
+ stream.hdr = 'PQ';
556
+ });
557
+ });
558
+ manifest.addVariant(2, (variant) => {
559
+ variant.addVideo(2, (stream) => {
560
+ stream.mime('video/mp4', 'hvc1.2.4.L153.B0');
561
+ stream.hdr = 'HLG';
562
+ });
563
+ });
564
+ });
565
+
566
+ await StreamUtils.getDecodingInfosForVariants(manifest.variants,
567
+ /* usePersistentLicenses= */ false, /* srcEquals= */ false);
568
+ expect(decodingInfoSpy.calls.argsFor(0)[0].video.transferFunction)
569
+ .toBe('srgb');
570
+ expect(decodingInfoSpy.calls.argsFor(1)[0].video.transferFunction)
571
+ .toBe('pq');
572
+ expect(decodingInfoSpy.calls.argsFor(2)[0].video.transferFunction)
573
+ .toBe('hlg');
574
+ });
540
575
  });
541
576
 
542
577
  describe('filterManifest', () => {
package/ui/cast_button.js CHANGED
@@ -102,9 +102,8 @@ shaka.ui.CastButton = class extends shaka.ui.Element {
102
102
  } catch (error) {
103
103
  this.castButton_.disabled = false;
104
104
  if (error.code != shaka.util.Error.Code.CAST_CANCELED_BY_USER) {
105
- this.controls.dispatchEvent(new shaka.util.FakeEvent('error', {
106
- detail: error,
107
- }));
105
+ this.controls.dispatchEvent(new shaka.util.FakeEvent(
106
+ 'error', (new Map()).set('detail', error)));
108
107
  }
109
108
  }
110
109
  }
package/ui/controls.js CHANGED
@@ -573,9 +573,8 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
573
573
  }
574
574
  }
575
575
  } catch (error) {
576
- this.dispatchEvent(new shaka.util.FakeEvent('error', {
577
- detail: error,
578
- }));
576
+ this.dispatchEvent(new shaka.util.FakeEvent(
577
+ 'error', (new Map()).set('detail', error)));
579
578
  }
580
579
  }
581
580
  }
@@ -1162,9 +1161,8 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
1162
1161
  /** @private */
1163
1162
  onCastStatusChange_() {
1164
1163
  const isCasting = this.castProxy_.isCasting();
1165
- this.dispatchEvent(new shaka.util.FakeEvent('caststatuschanged', {
1166
- newStatus: isCasting,
1167
- }));
1164
+ this.dispatchEvent(new shaka.util.FakeEvent(
1165
+ 'caststatuschanged', (new Map()).set('newStatus', isCasting)));
1168
1166
 
1169
1167
  if (isCasting) {
1170
1168
  this.controlsContainer_.setAttribute('casting', 'true');
@@ -229,13 +229,9 @@
229
229
  transition-delay: 500ms;
230
230
 
231
231
  /* These are defaults which are overridden by JS or cue styles. */
232
- span:not(.shaka-text-wrapper) {
233
- display: inline;
234
- font-size: 20px;
235
- line-height: 1.4; // relative to font size.
236
- background-color: rgba(0, 0, 0, 0.8);
237
- color: rgb(255, 255, 255);
238
- }
232
+ font-size: 20px;
233
+ line-height: 1.4; // relative to font size.
234
+ color: rgb(255, 255, 255);
239
235
 
240
236
  span.shaka-text-wrapper {
241
237
  display: inline;
@@ -1,10 +1,10 @@
1
1
  {
2
- "AD_DURATION": "Продолжительность объявления",
3
- "AD_PROGRESS": "Объявление [AD_ON] из [NUM_ADS]",
4
- "AD_TIME": "Объявление: [AD_TIME]",
2
+ "AD_DURATION": "Продолжительность рекламы",
3
+ "AD_PROGRESS": "Реклама [AD_ON] из [NUM_ADS]",
4
+ "AD_TIME": "Реклама: [AD_TIME]",
5
5
  "AUTO_QUALITY": "Авто",
6
6
  "BACK": "Назад",
7
- "CAPTIONS": "Титры",
7
+ "CAPTIONS": "Субтитры",
8
8
  "CAST": "Транслировать...",
9
9
  "ENTER_LOOP_MODE": "Зациклить текущее видео",
10
10
  "ENTER_PICTURE_IN_PICTURE": "Перейти в режим \"Картинка в картинке\"",
@@ -20,8 +20,8 @@
20
20
  "MULTIPLE_LANGUAGES": "Несколько языков",
21
21
  "MUTE": "Отключить звук",
22
22
  "NOT_APPLICABLE": "Неприменимо",
23
- "OFF": "Включить",
24
- "ON": "Отключить",
23
+ "OFF": "Выкл.",
24
+ "ON": "Вкл.",
25
25
  "PAUSE": "Пауза",
26
26
  "PICTURE_IN_PICTURE": "Картинка в картинке",
27
27
  "PLAY": "Воспроизвести",
@@ -130,28 +130,20 @@ shaka.ui.Localization = class {
130
130
  (locale) => !this.localizations_.has(locale));
131
131
 
132
132
  if (missing.length) {
133
- /** @type {shaka.ui.Localization.UnknownLocalesEvent} */
134
- const eMissing = {
135
- 'locales': missing,
136
- };
137
-
138
133
  this.events_.dispatchEvent(new shaka.util.FakeEvent(
139
134
  Class.UNKNOWN_LOCALES,
140
- eMissing));
135
+ (new Map()).set('locales', missing)));
141
136
  }
142
137
 
143
138
  const found = shaka.util.Iterables.filter(
144
139
  this.currentLocales_,
145
140
  (locale) => this.localizations_.has(locale));
146
141
 
147
- /** @type {shaka.ui.Localization.LocaleChangedEvent} */
148
- const eFound = {
149
- 'locales': found.length ? found : [this.fallbackLocale_],
150
- };
151
-
142
+ const data = (new Map()).set(
143
+ 'locales', found.length ? found : [this.fallbackLocale_]);
152
144
  this.events_.dispatchEvent(new shaka.util.FakeEvent(
153
145
  Class.LOCALE_CHANGED,
154
- eFound));
146
+ data));
155
147
  }
156
148
 
157
149
  /**
@@ -253,14 +245,11 @@ shaka.ui.Localization = class {
253
245
  // number of locales. Since we don't know which ones we actually checked,
254
246
  // just tell them the preferred locale.
255
247
 
256
- /** @type {shaka.ui.Localization.UnknownLocalizationEvent} */
257
- const e = {
258
- // Make a copy to avoid leaking references.
259
- 'locales': Array.from(this.currentLocales_),
260
- 'missing': id,
261
- };
262
-
263
- this.events_.dispatchEvent(new FakeEvent(Class.UNKNOWN_LOCALIZATION, e));
248
+ const data = new Map()
249
+ // Make a copy to avoid leaking references.
250
+ .set('locales', Array.from(this.currentLocales_))
251
+ .set('missing', id);
252
+ this.events_.dispatchEvent(new FakeEvent(Class.UNKNOWN_LOCALIZATION, data));
264
253
 
265
254
  return '';
266
255
  }
@@ -381,18 +370,16 @@ shaka.ui.Localization = class {
381
370
  }
382
371
 
383
372
  if (missing.size > 0) {
384
- /** @type {shaka.ui.Localization.MissingLocalizationsEvent} */
385
- const e = {
386
- // Make a copy of the preferred locales to avoid leaking references.
387
- 'locales': Array.from(preferredLocales),
388
- // Because most people like arrays more than sets, convert the set to
389
- // an array.
390
- 'missing': Array.from(missing),
391
- };
373
+ const data = new Map()
374
+ // Make a copy of the preferred locales to avoid leaking references.
375
+ .set('locales', Array.from(preferredLocales))
376
+ // Because more people like arrays more than sets, convert the set to
377
+ // an array.
378
+ .set('missing', Array.from(missing));
392
379
 
393
380
  this.events_.dispatchEvent(new shaka.util.FakeEvent(
394
381
  shaka.ui.Localization.MISSING_LOCALIZATIONS,
395
- e));
382
+ data));
396
383
  }
397
384
  }
398
385
 
@@ -478,52 +465,42 @@ shaka.ui.Localization.LOCALE_CHANGED = 'locale-changed';
478
465
  shaka.ui.Localization.LOCALE_UPDATED = 'locale-updated';
479
466
 
480
467
  /**
481
- * @typedef {{
482
- * 'locales': !Array.<string>
483
- * }}
484
- *
468
+ * @event shaka.ui.Localization.UnknownLocalesEvent
469
+ * @property {string} type
470
+ * 'unknown-locales'
485
471
  * @property {!Array.<string>} locales
486
472
  * The locales that the user wanted but could not be found.
487
473
  * @exportDoc
488
474
  */
489
- shaka.ui.Localization.UnknownLocalesEvent;
490
475
 
491
476
  /**
492
- * @typedef {{
493
- * 'locales': !Array.<string>,
494
- * 'missing': string
495
- * }}
496
- *
477
+ * @event shaka.ui.Localization.MissingLocalizationsEvent
478
+ * @property {string} type
479
+ * 'unknown-localization'
497
480
  * @property {!Array.<string>} locales
498
481
  * The locales that the user wanted.
499
482
  * @property {string} missing
500
483
  * The id of the unknown entry.
501
484
  * @exportDoc
502
485
  */
503
- shaka.ui.Localization.UnknownLocalizationEvent;
504
486
 
505
487
  /**
506
- * @typedef {{
507
- * 'locales': !Array.<string>,
508
- * 'missing': !Array.<string>
509
- * }}
510
- *
488
+ * @event shaka.ui.Localization.MissingLocalizationsEvent
489
+ * @property {string} type
490
+ * 'missing-localizations'
511
491
  * @property {string} locale
512
492
  * The locale that the user wanted.
513
493
  * @property {!Array.<string>} missing
514
494
  * The ids of the missing entries.
515
495
  * @exportDoc
516
496
  */
517
- shaka.ui.Localization.MissingLocalizationsEvent;
518
497
 
519
498
  /**
520
- * @typedef {{
521
- * 'locales': !Array.<string>
522
- * }}
523
- *
499
+ * @event shaka.ui.Localization.LocaleChangedEvent
500
+ * @property {string} type
501
+ * 'locale-changed'
524
502
  * @property {!Array.<string>} locales
525
503
  * The new set of locales that user wanted,
526
504
  * and that were successfully found.
527
505
  * @exportDoc
528
506
  */
529
- shaka.ui.Localization.LocaleChangedEvent;
package/ui/pip_button.js CHANGED
@@ -131,9 +131,8 @@ shaka.ui.PipButton = class extends shaka.ui.Element {
131
131
  await document.exitPictureInPicture();
132
132
  }
133
133
  } catch (error) {
134
- this.controls.dispatchEvent(new shaka.util.FakeEvent('error', {
135
- detail: error,
136
- }));
134
+ this.controls.dispatchEvent(new shaka.util.FakeEvent(
135
+ 'error', (new Map()).set('detail', error)));
137
136
  }
138
137
  }
139
138