vidply 1.0.24 → 1.0.26

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 (56) hide show
  1. package/README.md +5 -0
  2. package/dist/dev/vidply.HLSRenderer-X46P47LY.js +261 -0
  3. package/dist/dev/vidply.HLSRenderer-X46P47LY.js.map +7 -0
  4. package/dist/dev/vidply.HTML5Renderer-LXQ3I45Q.js +12 -0
  5. package/dist/dev/vidply.HTML5Renderer-LXQ3I45Q.js.map +7 -0
  6. package/dist/dev/vidply.TranscriptManager-GZKY44ON.js +1744 -0
  7. package/dist/dev/vidply.TranscriptManager-GZKY44ON.js.map +7 -0
  8. package/dist/dev/vidply.VimeoRenderer-DCETT5IZ.js +213 -0
  9. package/dist/dev/vidply.VimeoRenderer-DCETT5IZ.js.map +7 -0
  10. package/dist/dev/vidply.YouTubeRenderer-QLMMD757.js +227 -0
  11. package/dist/dev/vidply.YouTubeRenderer-QLMMD757.js.map +7 -0
  12. package/dist/dev/vidply.chunk-UEIJOJH6.js +243 -0
  13. package/dist/dev/vidply.chunk-UEIJOJH6.js.map +7 -0
  14. package/dist/dev/vidply.chunk-UH5MTGKF.js +1630 -0
  15. package/dist/dev/vidply.chunk-UH5MTGKF.js.map +7 -0
  16. package/dist/dev/vidply.de-THBIMP4S.js +180 -0
  17. package/dist/dev/vidply.de-THBIMP4S.js.map +7 -0
  18. package/dist/dev/vidply.es-6VWDNNNL.js +180 -0
  19. package/dist/dev/vidply.es-6VWDNNNL.js.map +7 -0
  20. package/dist/{vidply.esm.js → dev/vidply.esm.js} +279 -5135
  21. package/dist/dev/vidply.esm.js.map +7 -0
  22. package/dist/dev/vidply.fr-WHTWCHWT.js +180 -0
  23. package/dist/dev/vidply.fr-WHTWCHWT.js.map +7 -0
  24. package/dist/dev/vidply.ja-BFQNPOFI.js +180 -0
  25. package/dist/dev/vidply.ja-BFQNPOFI.js.map +7 -0
  26. package/dist/{vidply.js → legacy/vidply.js} +7676 -7458
  27. package/dist/legacy/vidply.js.map +7 -0
  28. package/dist/legacy/vidply.min.js +6 -0
  29. package/dist/{vidply.min.meta.json → legacy/vidply.min.meta.json} +108 -87
  30. package/dist/prod/vidply.HLSRenderer-LDXSMWTI.min.js +6 -0
  31. package/dist/prod/vidply.HTML5Renderer-XJCSUETP.min.js +6 -0
  32. package/dist/prod/vidply.TranscriptManager-UZ6DUFB6.min.js +6 -0
  33. package/dist/prod/vidply.VimeoRenderer-P3PU27S7.min.js +6 -0
  34. package/dist/prod/vidply.YouTubeRenderer-DGKKWB5M.min.js +6 -0
  35. package/dist/prod/vidply.chunk-BQBGEJF7.min.js +6 -0
  36. package/dist/prod/vidply.chunk-MBUR3U5L.min.js +6 -0
  37. package/dist/prod/vidply.de-SWFW4HYT.min.js +6 -0
  38. package/dist/prod/vidply.es-7BJ2DJAY.min.js +6 -0
  39. package/dist/prod/vidply.esm.min.js +21 -0
  40. package/dist/prod/vidply.fr-DPVR5DFY.min.js +6 -0
  41. package/dist/prod/vidply.ja-PEBVWKVH.min.js +6 -0
  42. package/dist/vidply.css +1 -1
  43. package/dist/vidply.esm.min.meta.json +273 -96
  44. package/dist/vidply.min.css +1 -1
  45. package/package.json +3 -3
  46. package/src/controls/ControlBar.js +2 -4
  47. package/src/core/Player.js +64 -20
  48. package/src/features/PlaylistManager.js +5 -4
  49. package/src/i18n/i18n.js +51 -7
  50. package/src/i18n/translations.js +35 -18
  51. package/src/icons/Icons.js +2 -20
  52. package/src/renderers/HLSRenderer.js +7 -0
  53. package/dist/vidply.esm.js.map +0 -7
  54. package/dist/vidply.esm.min.js +0 -22
  55. package/dist/vidply.js.map +0 -7
  56. package/dist/vidply.min.js +0 -22
@@ -8,11 +8,7 @@ import {DOMUtils} from '../utils/DOMUtils.js';
8
8
  import {ControlBar} from '../controls/ControlBar.js';
9
9
  import {CaptionManager} from '../controls/CaptionManager.js';
10
10
  import {KeyboardManager} from '../controls/KeyboardManager.js';
11
- import {TranscriptManager} from '../controls/TranscriptManager.js';
12
11
  import {HTML5Renderer} from '../renderers/HTML5Renderer.js';
13
- import {YouTubeRenderer} from '../renderers/YouTubeRenderer.js';
14
- import {VimeoRenderer} from '../renderers/VimeoRenderer.js';
15
- import {HLSRenderer} from '../renderers/HLSRenderer.js';
16
12
  import {createPlayOverlay, createIconElement} from '../icons/Icons.js';
17
13
  import {i18n} from '../i18n/i18n.js';
18
14
  import {StorageManager} from '../utils/StorageManager.js';
@@ -293,6 +289,9 @@ export class Player extends EventEmitter {
293
289
  this.options.language = 'en';
294
290
  }
295
291
 
292
+ // Ensure requested language is available (loads built-ins on demand)
293
+ await i18n.ensureLanguage(this.options.language);
294
+
296
295
  // Set language
297
296
  i18n.setLanguage(this.options.language);
298
297
 
@@ -318,9 +317,9 @@ export class Player extends EventEmitter {
318
317
  this.captionManager = new CaptionManager(this);
319
318
  }
320
319
 
321
- // Initialize transcript
322
- if (this.options.transcript || this.options.transcriptButton) {
323
- this.transcriptManager = new TranscriptManager(this);
320
+ // Initialize transcript lazily unless explicitly requested
321
+ if (this.options.transcript) {
322
+ await this.ensureTranscriptManager();
324
323
  }
325
324
 
326
325
  // Always set up metadata track handling (independent of transcript)
@@ -376,9 +375,46 @@ export class Player extends EventEmitter {
376
375
  }
377
376
  }
378
377
 
378
+ /**
379
+ * Ensure the transcript manager is available, creating it on demand.
380
+ * This keeps initial load fast when transcripts are not needed.
381
+ */
382
+ async ensureTranscriptManager() {
383
+ if (this.transcriptManager) {
384
+ return this.transcriptManager;
385
+ }
386
+
387
+ if (!this.options.transcript && !this.options.transcriptButton) {
388
+ return null;
389
+ }
390
+
391
+ const module = await import('../controls/TranscriptManager.js');
392
+ const Manager = module.TranscriptManager || module.default;
393
+
394
+ if (!Manager) {
395
+ return null;
396
+ }
397
+
398
+ this.transcriptManager = new Manager(this);
399
+ return this.transcriptManager;
400
+ }
401
+
402
+ /**
403
+ * Toggle transcript visibility, lazily creating the manager if necessary.
404
+ */
405
+ async toggleTranscript() {
406
+ const manager = await this.ensureTranscriptManager();
407
+ if (!manager) return;
408
+
409
+ manager.toggleTranscript();
410
+ if (this.controlBar) {
411
+ this.controlBar.updateTranscriptButton();
412
+ }
413
+ }
414
+
379
415
  /**
380
416
  * Detect language from HTML lang attribute
381
- * @returns {string|null} Language code if available in translations, null otherwise
417
+ * @returns {string|null} Language code if available in translations or as built-in, null otherwise
382
418
  */
383
419
  detectHtmlLanguage() {
384
420
  // Try to get lang from html element
@@ -391,11 +427,16 @@ export class Player extends EventEmitter {
391
427
  // Normalize the language code (e.g., "en-US" -> "en", "de-DE" -> "de")
392
428
  const normalizedLang = htmlLang.toLowerCase().split('-')[0];
393
429
 
394
- // Check if this language is available in our translations (including dynamically loaded ones)
430
+ // Check if this language is available in our translations (already loaded)
395
431
  if (i18n.translations[normalizedLang]) {
396
432
  return normalizedLang;
397
433
  }
398
434
 
435
+ // Check if this language is available as a built-in that can be loaded on demand
436
+ if (i18n.builtInLanguageLoaders && i18n.builtInLanguageLoaders[normalizedLang]) {
437
+ return normalizedLang;
438
+ }
439
+
399
440
  // Language not available, will fallback to English
400
441
  this.log(`Language "${htmlLang}" not available, using English as fallback`);
401
442
  return null; // Return null instead of 'en' to let the default language handling work
@@ -674,21 +715,22 @@ export class Player extends EventEmitter {
674
715
  this.originalSrc = src;
675
716
  }
676
717
 
677
- // Detect media type
678
- let renderer;
718
+ // Detect media type and lazily load heavy renderers
719
+ let rendererClass = HTML5Renderer;
679
720
 
680
721
  if (src.includes('youtube.com') || src.includes('youtu.be')) {
681
- renderer = YouTubeRenderer;
722
+ const module = await import('../renderers/YouTubeRenderer.js');
723
+ rendererClass = module.YouTubeRenderer || module.default;
682
724
  } else if (src.includes('vimeo.com')) {
683
- renderer = VimeoRenderer;
725
+ const module = await import('../renderers/VimeoRenderer.js');
726
+ rendererClass = module.VimeoRenderer || module.default;
684
727
  } else if (src.includes('.m3u8')) {
685
- renderer = HLSRenderer;
686
- } else {
687
- renderer = HTML5Renderer;
728
+ const module = await import('../renderers/HLSRenderer.js');
729
+ rendererClass = module.HLSRenderer || module.default;
688
730
  }
689
731
 
690
- this.log(`Using ${renderer.name} renderer`);
691
- this.renderer = new renderer(this);
732
+ this.log(`Using ${rendererClass?.name || 'HTML5Renderer'} renderer`);
733
+ this.renderer = new rendererClass(this);
692
734
  await this.renderer.init();
693
735
 
694
736
  // Invalidate cache after renderer initialization (tracks may have changed)
@@ -970,11 +1012,13 @@ export class Player extends EventEmitter {
970
1012
  if (this.transcriptManager) {
971
1013
  const wasTranscriptVisible = this.transcriptManager.isVisible;
972
1014
  this.transcriptManager.destroy();
973
- this.transcriptManager = new TranscriptManager(this);
1015
+ this.transcriptManager = null;
1016
+
1017
+ await this.ensureTranscriptManager();
974
1018
 
975
1019
  // Only restore transcript visibility if new track has captions
976
1020
  if (wasTranscriptVisible && this.controlBar && this.controlBar.hasCaptionTracks()) {
977
- this.transcriptManager.showTranscript();
1021
+ this.transcriptManager?.showTranscript();
978
1022
  }
979
1023
  }
980
1024
 
@@ -15,6 +15,7 @@ export class PlaylistManager {
15
15
  constructor(player, options = {}) {
16
16
  this.player = player;
17
17
  this.tracks = [];
18
+ this.initialTracks = Array.isArray(options.tracks) ? options.tracks : [];
18
19
  this.currentIndex = -1;
19
20
 
20
21
  // Generate unique instance ID for this playlist
@@ -53,9 +54,9 @@ export class PlaylistManager {
53
54
  // Update controls to add playlist buttons
54
55
  this.updatePlayerControls();
55
56
 
56
- // Load tracks if provided in options
57
- if (options.tracks && Array.isArray(options.tracks)) {
58
- this.loadPlaylist(options.tracks);
57
+ // Load tracks if provided in options (after UI is ready)
58
+ if (this.initialTracks.length > 0) {
59
+ this.loadPlaylist(this.initialTracks);
59
60
  }
60
61
  }
61
62
 
@@ -81,7 +82,7 @@ export class PlaylistManager {
81
82
  }
82
83
 
83
84
  // Check for data-playlist attribute on player container (only if tracks weren't provided in options)
84
- if (this.tracks.length === 0) {
85
+ if (this.tracks.length === 0 && this.initialTracks.length === 0) {
85
86
  this.loadPlaylistFromAttribute();
86
87
  }
87
88
  }
package/src/i18n/i18n.js CHANGED
@@ -2,13 +2,14 @@
2
2
  * Internationalization system
3
3
  */
4
4
 
5
- import { loadBuiltInTranslations } from './translations.js';
5
+ import { getBaseTranslations, getBuiltInLanguageLoaders, loadBuiltInTranslation } from './translations.js';
6
6
 
7
7
  class I18n {
8
8
  constructor() {
9
9
  this.currentLanguage = 'en';
10
- this.translations = loadBuiltInTranslations();
10
+ this.translations = getBaseTranslations();
11
11
  this.loadingPromises = new Map(); // Cache for loading promises
12
+ this.builtInLanguageLoaders = getBuiltInLanguageLoaders();
12
13
  }
13
14
 
14
15
  setLanguage(lang) {
@@ -24,6 +25,47 @@ class I18n {
24
25
  return this.currentLanguage;
25
26
  }
26
27
 
28
+ /**
29
+ * Ensure a language is available, loading built-ins on demand.
30
+ * @param {string} lang Language code
31
+ * @returns {Promise<string|null>} Normalized language code if available
32
+ */
33
+ async ensureLanguage(lang) {
34
+ const normalizedLang = (lang || '').toLowerCase();
35
+ if (!normalizedLang) return this.currentLanguage;
36
+
37
+ if (this.translations[normalizedLang]) {
38
+ return normalizedLang;
39
+ }
40
+
41
+ if (this.loadingPromises.has(normalizedLang)) {
42
+ await this.loadingPromises.get(normalizedLang);
43
+ return this.translations[normalizedLang] ? normalizedLang : null;
44
+ }
45
+
46
+ if (!this.builtInLanguageLoaders[normalizedLang]) {
47
+ return null;
48
+ }
49
+
50
+ const loadPromise = (async () => {
51
+ try {
52
+ const loaded = await loadBuiltInTranslation(normalizedLang);
53
+ if (loaded) {
54
+ this.translations[normalizedLang] = loaded;
55
+ }
56
+ } catch (error) {
57
+ console.warn(`Language "${normalizedLang}" failed to load:`, error);
58
+ } finally {
59
+ this.loadingPromises.delete(normalizedLang);
60
+ }
61
+ })();
62
+
63
+ this.loadingPromises.set(normalizedLang, loadPromise);
64
+ await loadPromise;
65
+
66
+ return this.translations[normalizedLang] ? normalizedLang : null;
67
+ }
68
+
27
69
  t(key, replacements = {}) {
28
70
  const keys = key.split('.');
29
71
  let value = this.translations[this.currentLanguage];
@@ -84,20 +126,22 @@ class I18n {
84
126
  const contentType = response.headers.get('content-type') || '';
85
127
  let translations;
86
128
 
129
+ const buffer = await response.arrayBuffer();
130
+ const utf8Text = new TextDecoder('utf-8').decode(buffer);
131
+
87
132
  if (contentType.includes('application/json') || url.endsWith('.json')) {
88
- translations = await response.json();
133
+ translations = JSON.parse(utf8Text);
89
134
  } else if (contentType.includes('text/yaml') || contentType.includes('application/x-yaml') || url.endsWith('.yaml') || url.endsWith('.yml')) {
90
135
  // For YAML, we'll need to parse it
91
136
  // Note: This requires a YAML parser library in production
92
137
  // For now, we'll try to parse as JSON first, then show a warning
93
- const text = await response.text();
94
138
  try {
95
139
  // Try JSON first (in case server sends JSON with YAML content-type)
96
- translations = JSON.parse(text);
140
+ translations = JSON.parse(utf8Text);
97
141
  } catch (e) {
98
142
  // If JSON parsing fails, try to use a YAML parser if available
99
143
  if (typeof window !== 'undefined' && window.jsyaml) {
100
- translations = window.jsyaml.load(text);
144
+ translations = window.jsyaml.load(utf8Text);
101
145
  } else {
102
146
  console.warn('YAML parsing requires js-yaml library. Please include it or use JSON format.');
103
147
  throw new Error('YAML parsing not available. Please use JSON format or include js-yaml library.');
@@ -105,7 +149,7 @@ class I18n {
105
149
  }
106
150
  } else {
107
151
  // Try to parse as JSON by default
108
- translations = await response.json();
152
+ translations = JSON.parse(utf8Text);
109
153
  }
110
154
 
111
155
  this.addTranslation(langCode, translations);
@@ -1,31 +1,48 @@
1
1
  /**
2
2
  * Translation strings for VidPly
3
- * This file loads all built-in language files
3
+ * Lazily loads built-in language files to keep the base bundle small.
4
4
  */
5
5
 
6
6
  import { en } from './languages/en.js';
7
- import { de } from './languages/de.js';
8
- import { es } from './languages/es.js';
9
- import { fr } from './languages/fr.js';
10
- import { ja } from './languages/ja.js';
7
+
8
+ const builtInLanguageLoaders = {
9
+ de: () => import('./languages/de.js'),
10
+ es: () => import('./languages/es.js'),
11
+ fr: () => import('./languages/fr.js'),
12
+ ja: () => import('./languages/ja.js')
13
+ };
14
+
15
+ /**
16
+ * Returns the base translations that are always available in the bundle.
17
+ * Currently this is English-only to minimize bundle size.
18
+ */
19
+ export function getBaseTranslations() {
20
+ return { en };
21
+ }
11
22
 
12
23
  /**
13
- * Load all built-in translations
14
- * @returns {Object} Object containing all built-in language translations
24
+ * Expose built-in language loaders so they can be loaded on demand.
15
25
  */
16
- export function loadBuiltInTranslations() {
17
- return {
18
- en,
19
- de,
20
- es,
21
- fr,
22
- ja
23
- };
26
+ export function getBuiltInLanguageLoaders() {
27
+ return builtInLanguageLoaders;
28
+ }
29
+
30
+ /**
31
+ * Load a single built-in language asynchronously.
32
+ * @param {string} lang Language code to load
33
+ * @returns {Promise<Object|null>} Loaded translation object or null if unavailable
34
+ */
35
+ export async function loadBuiltInTranslation(lang) {
36
+ const loader = builtInLanguageLoaders[lang];
37
+ if (!loader) return null;
38
+
39
+ const module = await loader();
40
+ return module[lang] || module.default || null;
24
41
  }
25
42
 
26
43
  /**
27
- * Legacy export for backwards compatibility
28
- * @deprecated Use loadBuiltInTranslations() instead
44
+ * Legacy export for backwards compatibility (keeps API surface stable)
45
+ * Note: Only English is included by default; other languages are loaded on demand.
29
46
  */
30
- export const translations = loadBuiltInTranslations();
47
+ export const translations = getBaseTranslations();
31
48
 
@@ -47,26 +47,12 @@ const iconPaths = {
47
47
 
48
48
  check: `<path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>`,
49
49
 
50
- arrowUp: `<path d="M7 14l5-5 5 5z"/>`,
51
-
52
- arrowDown: `<path d="M7 10l5 5 5-5z"/>`,
53
-
54
- arrowLeft: `<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>`,
55
-
56
- arrowRight: `<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>`,
57
-
58
50
  loading: `<path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/>`,
59
51
 
60
52
  error: `<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>`,
61
53
 
62
- download: `<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>`,
63
-
64
- link: `<path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/>`,
65
-
66
54
  playlist: `<path d="M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z"/>`,
67
55
 
68
- language: `<path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z"/>`,
69
-
70
56
  hd: `<path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-8 12H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 .55-.45 1-1 1h-.75v1.5h-1.5V15H14c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v4zm-3.5-.5h2v-3h-2v3z"/>`,
71
57
 
72
58
  transcript: `<path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/>`,
@@ -81,18 +67,14 @@ const iconPaths = {
81
67
 
82
68
  signLanguageOn: `<g transform="scale(1.5)"><path d="M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z"/></g>`,
83
69
 
84
- speaker: `<path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/>`,
85
-
86
70
  music: `<path d="M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7zm-1.5 16c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/>`,
87
71
 
88
72
  moreVertical: `<path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/>`,
89
73
 
90
- moreHorizontal: `<path d="M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/>`,
91
-
92
74
  move: `<path d="M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z"/>`,
93
-
75
+
94
76
  resize: `<path d="M21.71 11.29l-9-9c-.39-.39-1.02-.39-1.41 0l-9 9c-.39.39-.39 1.02 0 1.41l9 9c.39.39 1.02.39 1.41 0l9-9c.39-.38.39-1.01 0-1.41zM14 14.5V12h-4v2.5L7 11l3-3.5V10h4V7.5l3 3.5-3 3.5z"/>`,
95
-
77
+
96
78
  clock: `<path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/><path d="M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"/>`
97
79
  };
98
80
 
@@ -309,6 +309,13 @@ export class HLSRenderer {
309
309
  return [];
310
310
  }
311
311
 
312
+ getCurrentQuality() {
313
+ if (this.hls) {
314
+ return this.hls.currentLevel;
315
+ }
316
+ return -1;
317
+ }
318
+
312
319
  destroy() {
313
320
  if (this.hls) {
314
321
  this.hls.destroy();