@frameset/plex-player 1.0.3 → 1.0.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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @frameset/plex-player v1.0.3
2
+ * @frameset/plex-player v1.0.4
3
3
  * Professional video player with VAST ads, Chromecast, PiP, subtitles, playlists and more. Built by FRAMESET Studio.
4
4
  * (c) 2026 FRAMESET Studio
5
5
  * Released under the MIT License
@@ -2,8 +2,9 @@
2
2
  PLEX Video Player - Main Styles
3
3
  ===================================================== */
4
4
 
5
- /* CSS Variables */
6
- :root {
5
+ /* CSS Variables - scoped to player */
6
+ .plex-player,
7
+ .plex-player-container {
7
8
  --plex-primary: #e5a00d;
8
9
  --plex-primary-hover: #f5b82e;
9
10
  --plex-bg-dark: #1a1a1a;
@@ -29,20 +30,24 @@
29
30
  --plex-z-toast: 50;
30
31
  }
31
32
 
32
- /* Reset & Base */
33
- *, *::before, *::after {
33
+ /* Scoped Reset - only inside player */
34
+ .plex-player *,
35
+ .plex-player *::before,
36
+ .plex-player *::after {
34
37
  box-sizing: border-box;
35
38
  margin: 0;
36
39
  padding: 0;
37
40
  }
38
41
 
39
- html, body {
42
+ /* Player Container Wrapper */
43
+ .plex-player-container {
44
+ position: relative;
40
45
  width: 100%;
41
- height: 100%;
46
+ aspect-ratio: 16 / 9;
42
47
  background: var(--plex-bg-darker);
43
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
44
- color: var(--plex-text-primary);
48
+ border-radius: var(--plex-radius-md);
45
49
  overflow: hidden;
50
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
46
51
  -webkit-font-smoothing: antialiased;
47
52
  -moz-osx-font-smoothing: grayscale;
48
53
  }
@@ -57,6 +62,8 @@ html, body {
57
62
  user-select: none;
58
63
  -webkit-user-select: none;
59
64
  -webkit-tap-highlight-color: transparent;
65
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
66
+ color: var(--plex-text-primary);
60
67
  }
61
68
 
62
69
  .plex-player.fullscreen {
@@ -1 +1 @@
1
- {"version":3,"sources":["main.css","controls.css","playlist.css","settings.css"],"names":[],"mappings":"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","file":"plex-player.css","sourcesContent":["/* =====================================================\r\n PLEX Video Player - Main Styles\r\n ===================================================== */\r\n\r\n/* CSS Variables */\r\n:root {\r\n --plex-primary: #e5a00d;\r\n --plex-primary-hover: #f5b82e;\r\n --plex-bg-dark: #1a1a1a;\r\n --plex-bg-darker: #0d0d0d;\r\n --plex-bg-overlay: rgba(0, 0, 0, 0.85);\r\n --plex-text-primary: #ffffff;\r\n --plex-text-secondary: #a0a0a0;\r\n --plex-border: rgba(255, 255, 255, 0.1);\r\n --plex-gradient: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, transparent 100%);\r\n --plex-gradient-top: linear-gradient(to bottom, rgba(0, 0, 0, 0.7) 0%, transparent 100%);\r\n --plex-transition-fast: 0.15s ease;\r\n --plex-transition-normal: 0.25s ease;\r\n --plex-transition-slow: 0.4s ease;\r\n --plex-radius-sm: 4px;\r\n --plex-radius-md: 8px;\r\n --plex-radius-lg: 12px;\r\n --plex-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);\r\n --plex-z-video: 1;\r\n --plex-z-overlay: 10;\r\n --plex-z-controls: 20;\r\n --plex-z-panel: 30;\r\n --plex-z-modal: 40;\r\n --plex-z-toast: 50;\r\n}\r\n\r\n/* Reset & Base */\r\n*, *::before, *::after {\r\n box-sizing: border-box;\r\n margin: 0;\r\n padding: 0;\r\n}\r\n\r\nhtml, body {\r\n width: 100%;\r\n height: 100%;\r\n background: var(--plex-bg-darker);\r\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n color: var(--plex-text-primary);\r\n overflow: hidden;\r\n -webkit-font-smoothing: antialiased;\r\n -moz-osx-font-smoothing: grayscale;\r\n}\r\n\r\n/* Player Container */\r\n.plex-player {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\r\n background: var(--plex-bg-darker);\r\n overflow: hidden;\r\n user-select: none;\r\n -webkit-user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n}\r\n\r\n.plex-player.fullscreen {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100vw;\r\n height: 100vh;\r\n z-index: 9999;\r\n}\r\n\r\n/* Video Container */\r\n.video-container {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n background: #000;\r\n z-index: var(--plex-z-video);\r\n}\r\n\r\n.video-container video {\r\n width: 100%;\r\n height: 100%;\r\n max-width: 100%;\r\n max-height: 100%;\r\n object-fit: contain;\r\n background: #000;\r\n}\r\n\r\n/* Controls Visibility */\r\n.plex-player.controls-visible .top-controls,\r\n.plex-player.controls-visible .bottom-controls {\r\n opacity: 1;\r\n visibility: visible;\r\n transform: translateY(0);\r\n}\r\n\r\n.plex-player:not(.controls-visible) .top-controls,\r\n.plex-player:not(.controls-visible) .bottom-controls {\r\n opacity: 0;\r\n visibility: hidden;\r\n}\r\n\r\n.plex-player:not(.controls-visible) .top-controls {\r\n transform: translateY(-100%);\r\n}\r\n\r\n.plex-player:not(.controls-visible) .bottom-controls {\r\n transform: translateY(100%);\r\n}\r\n\r\n/* Cursor hiding */\r\n.plex-player.hide-cursor {\r\n cursor: none;\r\n}\r\n\r\n.plex-player.hide-cursor video {\r\n cursor: none;\r\n}\r\n\r\n/* Loading Spinner */\r\n.loading-spinner {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n z-index: var(--plex-z-overlay);\r\n}\r\n\r\n.loading-spinner .spinner {\r\n width: 60px;\r\n height: 60px;\r\n border: 4px solid rgba(255, 255, 255, 0.2);\r\n border-top-color: var(--plex-primary);\r\n border-radius: 50%;\r\n animation: spin 1s linear infinite;\r\n}\r\n\r\n@keyframes spin {\r\n to {\r\n transform: rotate(360deg);\r\n }\r\n}\r\n\r\n/* Big Play Button */\r\n.big-play-btn {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%) scale(1);\r\n width: 80px;\r\n height: 80px;\r\n background: var(--plex-primary);\r\n border-radius: 50%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n z-index: var(--plex-z-overlay);\r\n transition: all var(--plex-transition-normal);\r\n box-shadow: 0 4px 30px rgba(229, 160, 13, 0.4);\r\n}\r\n\r\n.big-play-btn:hover {\r\n transform: translate(-50%, -50%) scale(1.1);\r\n background: var(--plex-primary-hover);\r\n}\r\n\r\n.big-play-btn .material-icons {\r\n font-size: 48px;\r\n color: #000;\r\n margin-left: 4px;\r\n}\r\n\r\n.big-play-btn.hidden {\r\n opacity: 0;\r\n visibility: hidden;\r\n transform: translate(-50%, -50%) scale(0.8);\r\n}\r\n\r\n/* Gesture Overlay */\r\n.gesture-overlay {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n display: flex;\r\n z-index: var(--plex-z-overlay);\r\n pointer-events: none;\r\n}\r\n\r\n.gesture-left,\r\n.gesture-right {\r\n flex: 1;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n.gesture-center {\r\n flex: 1;\r\n}\r\n\r\n.gesture-indicator {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 20px;\r\n background: rgba(0, 0, 0, 0.7);\r\n border-radius: var(--plex-radius-lg);\r\n opacity: 0;\r\n transform: scale(0.8);\r\n transition: all var(--plex-transition-fast);\r\n}\r\n\r\n.gesture-indicator.active {\r\n opacity: 1;\r\n transform: scale(1);\r\n}\r\n\r\n.gesture-indicator .material-icons {\r\n font-size: 48px;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.gesture-indicator .gesture-text {\r\n font-size: 14px;\r\n font-weight: 600;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n/* Volume/Brightness Indicators */\r\n.volume-indicator,\r\n.brightness-indicator {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 24px;\r\n background: rgba(0, 0, 0, 0.8);\r\n border-radius: var(--plex-radius-lg);\r\n z-index: var(--plex-z-overlay);\r\n transition: opacity var(--plex-transition-fast);\r\n}\r\n\r\n.volume-indicator .material-icons,\r\n.brightness-indicator .material-icons {\r\n font-size: 36px;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.volume-indicator-bar,\r\n.brightness-indicator-bar {\r\n width: 120px;\r\n height: 4px;\r\n background: rgba(255, 255, 255, 0.2);\r\n border-radius: 2px;\r\n overflow: hidden;\r\n}\r\n\r\n.volume-indicator-fill,\r\n.brightness-indicator-fill {\r\n height: 100%;\r\n background: var(--plex-primary);\r\n border-radius: 2px;\r\n transition: width var(--plex-transition-fast);\r\n}\r\n\r\n/* Subtitles Container */\r\n.subtitles-container {\r\n position: absolute;\r\n bottom: 80px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n width: 80%;\r\n max-width: 800px;\r\n text-align: center;\r\n z-index: var(--plex-z-overlay);\r\n pointer-events: none;\r\n}\r\n\r\n.subtitle-line {\r\n display: inline-block;\r\n padding: 8px 16px;\r\n margin: 4px 0;\r\n background: rgba(0, 0, 0, 0.75);\r\n border-radius: var(--plex-radius-sm);\r\n font-size: 24px;\r\n line-height: 1.4;\r\n color: #fff;\r\n text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8);\r\n}\r\n\r\n/* Cast Overlay */\r\n.cast-overlay {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background: var(--plex-bg-darker);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: var(--plex-z-overlay);\r\n}\r\n\r\n.cast-overlay.hidden {\r\n display: none;\r\n}\r\n\r\n.cast-overlay-content {\r\n text-align: center;\r\n animation: castPulse 2s ease-in-out infinite;\r\n}\r\n\r\n.cast-overlay .cast-icon {\r\n font-size: 80px;\r\n color: var(--plex-primary);\r\n margin-bottom: 24px;\r\n}\r\n\r\n.cast-overlay .cast-title {\r\n font-size: 18px;\r\n color: var(--plex-text-secondary);\r\n margin-bottom: 8px;\r\n}\r\n\r\n.cast-overlay .cast-device {\r\n font-size: 28px;\r\n font-weight: 600;\r\n color: var(--plex-text-primary);\r\n margin-bottom: 16px;\r\n}\r\n\r\n.cast-overlay .cast-video {\r\n font-size: 16px;\r\n color: var(--plex-text-secondary);\r\n max-width: 300px;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n}\r\n\r\n@keyframes castPulse {\r\n 0%, 100% { opacity: 1; }\r\n 50% { opacity: 0.7; }\r\n}\r\n\r\n/* Utility Classes */\r\n.hidden {\r\n display: none !important;\r\n}\r\n\r\n.visually-hidden {\r\n opacity: 0;\r\n visibility: hidden;\r\n}\r\n\r\n/* Toast Notification */\r\n.toast {\r\n position: absolute;\r\n bottom: 100px;\r\n left: 50%;\r\n transform: translateX(-50%) translateY(20px);\r\n background: var(--plex-bg-overlay);\r\n padding: 12px 24px;\r\n border-radius: var(--plex-radius-md);\r\n z-index: var(--plex-z-toast);\r\n opacity: 0;\r\n visibility: hidden;\r\n transition: all var(--plex-transition-normal);\r\n}\r\n\r\n.toast.show {\r\n opacity: 1;\r\n visibility: visible;\r\n transform: translateX(-50%) translateY(0);\r\n}\r\n\r\n.toast-message {\r\n font-size: 14px;\r\n font-weight: 500;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n/* Context Menu */\r\n.context-menu {\r\n position: fixed;\r\n min-width: 200px;\r\n background: var(--plex-bg-dark);\r\n border: 1px solid var(--plex-border);\r\n border-radius: var(--plex-radius-md);\r\n box-shadow: var(--plex-shadow);\r\n z-index: var(--plex-z-modal);\r\n overflow: hidden;\r\n}\r\n\r\n.context-menu-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 12px 16px;\r\n cursor: pointer;\r\n transition: background var(--plex-transition-fast);\r\n}\r\n\r\n.context-menu-item:hover {\r\n background: rgba(255, 255, 255, 0.1);\r\n}\r\n\r\n.context-menu-item .material-icons {\r\n font-size: 20px;\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n.context-menu-item span:last-child {\r\n font-size: 14px;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.context-menu-divider {\r\n height: 1px;\r\n background: var(--plex-border);\r\n margin: 4px 0;\r\n}\r\n\r\n/* Stats Overlay */\r\n.stats-overlay {\r\n position: absolute;\r\n top: 80px;\r\n left: 20px;\r\n width: 280px;\r\n background: var(--plex-bg-overlay);\r\n border-radius: var(--plex-radius-md);\r\n z-index: var(--plex-z-panel);\r\n overflow: hidden;\r\n}\r\n\r\n.stats-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 12px 16px;\r\n background: rgba(255, 255, 255, 0.05);\r\n border-bottom: 1px solid var(--plex-border);\r\n font-size: 14px;\r\n font-weight: 600;\r\n}\r\n\r\n.stats-content {\r\n padding: 12px 16px;\r\n}\r\n\r\n.stat-item {\r\n display: flex;\r\n justify-content: space-between;\r\n padding: 8px 0;\r\n font-size: 13px;\r\n border-bottom: 1px solid var(--plex-border);\r\n}\r\n\r\n.stat-item:last-child {\r\n border-bottom: none;\r\n}\r\n\r\n.stat-label {\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n.stat-value {\r\n color: var(--plex-text-primary);\r\n font-weight: 500;\r\n}\r\n\r\n/* Responsive */\r\n@media (max-width: 768px) {\r\n .big-play-btn {\r\n width: 64px;\r\n height: 64px;\r\n }\r\n \r\n .big-play-btn .material-icons {\r\n font-size: 36px;\r\n }\r\n \r\n .subtitle-line {\r\n font-size: 18px;\r\n padding: 6px 12px;\r\n }\r\n \r\n .subtitles-container {\r\n width: 90%;\r\n bottom: 70px;\r\n }\r\n \r\n .gesture-indicator .material-icons {\r\n font-size: 36px;\r\n }\r\n \r\n .stats-overlay {\r\n top: 60px;\r\n left: 10px;\r\n width: 240px;\r\n }\r\n}\r\n\r\n@media (max-width: 480px) {\r\n .big-play-btn {\r\n width: 56px;\r\n height: 56px;\r\n }\r\n \r\n .big-play-btn .material-icons {\r\n font-size: 32px;\r\n }\r\n \r\n .subtitle-line {\r\n font-size: 16px;\r\n }\r\n}\r\n\r\n/* Touch Device Optimizations */\r\n@media (hover: none) and (pointer: coarse) {\r\n .control-btn {\r\n min-width: 44px;\r\n min-height: 44px;\r\n }\r\n \r\n .volume-slider-container {\r\n display: none;\r\n }\r\n}\r\n\r\n/* Animations */\r\n@keyframes fadeIn {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n@keyframes slideUp {\r\n from {\r\n opacity: 0;\r\n transform: translateY(20px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n}\r\n\r\n@keyframes pulse {\r\n 0%, 100% {\r\n transform: translate(-50%, -50%) scale(1);\r\n }\r\n 50% {\r\n transform: translate(-50%, -50%) scale(1.05);\r\n }\r\n}\r\n","/* =====================================================\r\n PLEX Video Player - Controls Styles\r\n ===================================================== */\r\n\r\n/* Top Controls Bar */\r\n.top-controls {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 16px 20px;\r\n background: var(--plex-gradient-top);\r\n z-index: var(--plex-z-controls);\r\n transition: all var(--plex-transition-normal);\r\n}\r\n\r\n.top-left,\r\n.top-right {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n}\r\n\r\n.video-title {\r\n font-size: 16px;\r\n font-weight: 600;\r\n color: var(--plex-text-primary);\r\n margin-left: 8px;\r\n max-width: 400px;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n}\r\n\r\n/* Bottom Controls */\r\n.bottom-controls {\r\n position: absolute;\r\n bottom: 0;\r\n left: 0;\r\n width: 100%;\r\n padding: 0 16px 16px;\r\n background: var(--plex-gradient);\r\n z-index: var(--plex-z-controls);\r\n transition: all var(--plex-transition-normal);\r\n}\r\n\r\n/* Progress Container */\r\n.progress-container {\r\n position: relative;\r\n width: 100%;\r\n height: 24px;\r\n display: flex;\r\n align-items: center;\r\n cursor: pointer;\r\n padding: 8px 0;\r\n}\r\n\r\n.progress-bar {\r\n position: relative;\r\n width: 100%;\r\n height: 4px;\r\n background: rgba(255, 255, 255, 0.2);\r\n border-radius: 2px;\r\n overflow: visible;\r\n transition: height var(--plex-transition-fast);\r\n}\r\n\r\n.progress-container:hover .progress-bar {\r\n height: 6px;\r\n}\r\n\r\n.progress-buffered {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n height: 100%;\r\n background: rgba(255, 255, 255, 0.35);\r\n border-radius: 2px;\r\n pointer-events: none;\r\n}\r\n\r\n.progress-played {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n height: 100%;\r\n background: var(--plex-primary);\r\n border-radius: 2px;\r\n pointer-events: none;\r\n}\r\n\r\n.progress-handle {\r\n position: absolute;\r\n top: 50%;\r\n left: 0;\r\n width: 14px;\r\n height: 14px;\r\n background: var(--plex-primary);\r\n border-radius: 50%;\r\n transform: translate(-50%, -50%) scale(0);\r\n transition: transform var(--plex-transition-fast);\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);\r\n pointer-events: none;\r\n}\r\n\r\n.progress-container:hover .progress-handle,\r\n.progress-container.dragging .progress-handle {\r\n transform: translate(-50%, -50%) scale(1);\r\n}\r\n\r\n.progress-container.dragging .progress-bar {\r\n height: 6px;\r\n}\r\n\r\n/* Progress Tooltip */\r\n.progress-tooltip {\r\n position: absolute;\r\n bottom: 100%;\r\n left: 0;\r\n padding: 6px 10px;\r\n background: var(--plex-bg-dark);\r\n border-radius: var(--plex-radius-sm);\r\n font-size: 13px;\r\n font-weight: 500;\r\n white-space: nowrap;\r\n opacity: 0;\r\n visibility: hidden;\r\n transform: translateX(-50%) translateY(4px);\r\n transition: all var(--plex-transition-fast);\r\n pointer-events: none;\r\n z-index: 50;\r\n}\r\n\r\n.progress-container:hover .progress-tooltip {\r\n opacity: 1;\r\n visibility: visible;\r\n transform: translateX(-50%) translateY(-4px);\r\n}\r\n\r\n/* Hide tooltip when preview is visible */\r\n.progress-container:hover .progress-preview[style*=\"display: flex\"] ~ .progress-tooltip,\r\n.progress-preview:not([style*=\"display: none\"]) + .progress-tooltip {\r\n opacity: 0;\r\n visibility: hidden;\r\n}\r\n\r\n/* Progress Preview (Thumbnail) */\r\n.progress-preview {\r\n position: absolute;\r\n bottom: calc(100% + 16px);\r\n left: 0;\r\n display: none;\r\n flex-direction: column;\r\n align-items: center;\r\n z-index: 100;\r\n pointer-events: none;\r\n background: rgba(0, 0, 0, 0.9);\r\n padding: 4px;\r\n border-radius: var(--plex-radius-sm);\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);\r\n}\r\n\r\n#preview-canvas {\r\n width: 160px;\r\n height: 90px;\r\n background: var(--plex-bg-dark);\r\n border: 2px solid var(--plex-primary);\r\n border-radius: var(--plex-radius-sm);\r\n object-fit: contain;\r\n}\r\n\r\n.preview-time {\r\n margin-top: 6px;\r\n padding: 4px 10px;\r\n background: var(--plex-primary);\r\n color: #000;\r\n border-radius: var(--plex-radius-sm);\r\n font-size: 12px;\r\n font-weight: 700;\r\n}\r\n\r\n/* Time Display */\r\n.time-display {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n padding: 8px 0;\r\n font-size: 13px;\r\n font-weight: 500;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.time-separator {\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n/* Main Controls Row */\r\n.main-controls {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n margin-top: 4px;\r\n}\r\n\r\n.controls-left,\r\n.controls-right {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n}\r\n\r\n/* Control Button */\r\n.control-btn {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 40px;\r\n height: 40px;\r\n background: transparent;\r\n border: none;\r\n border-radius: var(--plex-radius-sm);\r\n cursor: pointer;\r\n transition: all var(--plex-transition-fast);\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.control-btn:hover {\r\n background: rgba(255, 255, 255, 0.1);\r\n}\r\n\r\n.control-btn:active {\r\n transform: scale(0.95);\r\n}\r\n\r\n.control-btn .material-icons {\r\n font-size: 24px;\r\n}\r\n\r\n.control-btn.active {\r\n color: var(--plex-primary);\r\n}\r\n\r\n/* Cast Button */\r\n#cast-btn {\r\n transition: all var(--plex-transition-fast);\r\n}\r\n\r\n#cast-btn.active {\r\n color: var(--plex-primary);\r\n animation: pulse-cast 2s ease-in-out infinite;\r\n}\r\n\r\n#cast-btn.hidden {\r\n display: none;\r\n}\r\n\r\n@keyframes pulse-cast {\r\n 0%, 100% { opacity: 1; }\r\n 50% { opacity: 0.6; }\r\n}\r\n\r\n/* Play Button (Larger) */\r\n.play-btn {\r\n width: 48px;\r\n height: 48px;\r\n}\r\n\r\n.play-btn .material-icons {\r\n font-size: 32px;\r\n}\r\n\r\n/* Speed Text */\r\n.speed-text {\r\n font-size: 14px;\r\n font-weight: 600;\r\n min-width: 28px;\r\n}\r\n\r\n/* Volume Control */\r\n.volume-control {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n}\r\n\r\n.volume-slider-container {\r\n position: relative;\r\n width: 0;\r\n overflow: hidden;\r\n transition: width var(--plex-transition-normal);\r\n}\r\n\r\n.volume-control:hover .volume-slider-container {\r\n width: 80px;\r\n}\r\n\r\n.volume-slider {\r\n -webkit-appearance: none;\r\n appearance: none;\r\n width: 80px;\r\n height: 4px;\r\n background: rgba(255, 255, 255, 0.2);\r\n border-radius: 2px;\r\n outline: none;\r\n cursor: pointer;\r\n}\r\n\r\n.volume-slider::-webkit-slider-thumb {\r\n -webkit-appearance: none;\r\n appearance: none;\r\n width: 14px;\r\n height: 14px;\r\n background: var(--plex-primary);\r\n border-radius: 50%;\r\n cursor: pointer;\r\n transition: transform var(--plex-transition-fast);\r\n}\r\n\r\n.volume-slider::-webkit-slider-thumb:hover {\r\n transform: scale(1.2);\r\n}\r\n\r\n.volume-slider::-moz-range-thumb {\r\n width: 14px;\r\n height: 14px;\r\n background: var(--plex-primary);\r\n border: none;\r\n border-radius: 50%;\r\n cursor: pointer;\r\n}\r\n\r\n.volume-slider-fill {\r\n position: absolute;\r\n top: 50%;\r\n left: 0;\r\n height: 4px;\r\n background: var(--plex-primary);\r\n border-radius: 2px;\r\n transform: translateY(-50%);\r\n pointer-events: none;\r\n}\r\n\r\n/* Chapters Markers (on progress bar) */\r\n.chapter-marker {\r\n position: absolute;\r\n top: 0;\r\n width: 3px;\r\n height: 100%;\r\n background: rgba(255, 255, 255, 0.8);\r\n border-radius: 1px;\r\n transform: translateX(-50%);\r\n cursor: pointer;\r\n z-index: 2;\r\n}\r\n\r\n.chapter-marker:hover {\r\n background: var(--plex-primary);\r\n}\r\n\r\n/* Skip Intro Button */\r\n.skip-intro-btn {\r\n position: absolute;\r\n right: 20px;\r\n bottom: 100px;\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 12px 20px;\r\n background: rgba(255, 255, 255, 0.9);\r\n color: #000;\r\n border: none;\r\n border-radius: var(--plex-radius-md);\r\n font-size: 14px;\r\n font-weight: 600;\r\n cursor: pointer;\r\n z-index: var(--plex-z-controls);\r\n transition: all var(--plex-transition-normal);\r\n}\r\n\r\n.skip-intro-btn:hover {\r\n background: #fff;\r\n transform: scale(1.02);\r\n}\r\n\r\n.skip-intro-btn .material-icons {\r\n font-size: 20px;\r\n}\r\n\r\n/* Double Tap Ripple Effect */\r\n.tap-ripple {\r\n position: absolute;\r\n width: 100px;\r\n height: 100px;\r\n border-radius: 50%;\r\n background: rgba(255, 255, 255, 0.3);\r\n transform: translate(-50%, -50%) scale(0);\r\n animation: ripple 0.5s ease-out forwards;\r\n pointer-events: none;\r\n}\r\n\r\n@keyframes ripple {\r\n to {\r\n transform: translate(-50%, -50%) scale(2);\r\n opacity: 0;\r\n }\r\n}\r\n\r\n/* Responsive Controls */\r\n@media (max-width: 768px) {\r\n .top-controls {\r\n padding: 12px 16px;\r\n }\r\n \r\n .video-title {\r\n font-size: 14px;\r\n max-width: 200px;\r\n }\r\n \r\n .bottom-controls {\r\n padding: 0 12px 12px;\r\n }\r\n \r\n .control-btn {\r\n width: 36px;\r\n height: 36px;\r\n }\r\n \r\n .control-btn .material-icons {\r\n font-size: 22px;\r\n }\r\n \r\n .play-btn {\r\n width: 44px;\r\n height: 44px;\r\n }\r\n \r\n .play-btn .material-icons {\r\n font-size: 28px;\r\n }\r\n \r\n .time-display {\r\n font-size: 12px;\r\n }\r\n \r\n .speed-text {\r\n font-size: 12px;\r\n }\r\n \r\n #preview-canvas {\r\n width: 120px;\r\n height: 68px;\r\n }\r\n}\r\n\r\n@media (max-width: 480px) {\r\n .controls-left,\r\n .controls-right {\r\n gap: 0;\r\n }\r\n \r\n .control-btn {\r\n width: 32px;\r\n height: 32px;\r\n }\r\n \r\n .control-btn .material-icons {\r\n font-size: 20px;\r\n }\r\n \r\n .video-title {\r\n max-width: 140px;\r\n font-size: 13px;\r\n }\r\n \r\n /* Hide some buttons on very small screens */\r\n #cast-btn,\r\n #quality-btn {\r\n display: none;\r\n }\r\n}\r\n\r\n/* Hover/Focus States for Accessibility */\r\n.control-btn:focus-visible {\r\n outline: 2px solid var(--plex-primary);\r\n outline-offset: 2px;\r\n}\r\n\r\n.progress-container:focus-visible {\r\n outline: 2px solid var(--plex-primary);\r\n outline-offset: 2px;\r\n}\r\n\r\n/* Disabled State */\r\n.control-btn:disabled {\r\n opacity: 0.4;\r\n cursor: not-allowed;\r\n}\r\n\r\n.control-btn:disabled:hover {\r\n background: transparent;\r\n}\r\n","/* =====================================================\r\n PLEX Video Player - Playlist Styles\r\n ===================================================== */\r\n\r\n/* Playlist Panel */\r\n.playlist-panel {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n width: 360px;\r\n height: 100%;\r\n background: var(--plex-bg-dark);\r\n border-left: 1px solid var(--plex-border);\r\n z-index: var(--plex-z-panel);\r\n display: flex;\r\n flex-direction: column;\r\n transform: translateX(100%);\r\n transition: transform var(--plex-transition-normal);\r\n}\r\n\r\n.playlist-panel.visible {\r\n transform: translateX(0);\r\n}\r\n\r\n/* Playlist Header */\r\n.playlist-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 16px 20px;\r\n background: rgba(255, 255, 255, 0.03);\r\n border-bottom: 1px solid var(--plex-border);\r\n flex-shrink: 0;\r\n}\r\n\r\n.playlist-title {\r\n font-size: 16px;\r\n font-weight: 600;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.playlist-header-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n}\r\n\r\n/* Playlist Content */\r\n.playlist-content {\r\n flex: 1;\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n padding: 12px;\r\n}\r\n\r\n.playlist-content::-webkit-scrollbar {\r\n width: 6px;\r\n}\r\n\r\n.playlist-content::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n\r\n.playlist-content::-webkit-scrollbar-thumb {\r\n background: rgba(255, 255, 255, 0.2);\r\n border-radius: 3px;\r\n}\r\n\r\n.playlist-content::-webkit-scrollbar-thumb:hover {\r\n background: rgba(255, 255, 255, 0.3);\r\n}\r\n\r\n/* Playlist Empty State */\r\n.playlist-empty {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n height: 100%;\r\n padding: 40px;\r\n text-align: center;\r\n}\r\n\r\n.playlist-empty .material-icons {\r\n font-size: 64px;\r\n color: var(--plex-text-secondary);\r\n margin-bottom: 16px;\r\n opacity: 0.5;\r\n}\r\n\r\n.playlist-empty-title {\r\n font-size: 18px;\r\n font-weight: 600;\r\n color: var(--plex-text-primary);\r\n margin-bottom: 8px;\r\n}\r\n\r\n.playlist-empty-text {\r\n font-size: 14px;\r\n color: var(--plex-text-secondary);\r\n line-height: 1.5;\r\n}\r\n\r\n/* Playlist Item */\r\n.playlist-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 10px 12px;\r\n background: rgba(255, 255, 255, 0.02);\r\n border-radius: var(--plex-radius-md);\r\n cursor: pointer;\r\n transition: all var(--plex-transition-fast);\r\n margin-bottom: 8px;\r\n position: relative;\r\n}\r\n\r\n.playlist-item:hover {\r\n background: rgba(255, 255, 255, 0.08);\r\n}\r\n\r\n.playlist-item.active {\r\n background: rgba(229, 160, 13, 0.15);\r\n border: 1px solid rgba(229, 160, 13, 0.3);\r\n}\r\n\r\n.playlist-item.playing {\r\n background: rgba(229, 160, 13, 0.2);\r\n}\r\n\r\n.playlist-item.dragging {\r\n opacity: 0.5;\r\n transform: scale(0.98);\r\n}\r\n\r\n/* Playlist Item Thumbnail */\r\n.playlist-item-thumbnail {\r\n position: relative;\r\n width: 100px;\r\n height: 56px;\r\n background: var(--plex-bg-darker);\r\n border-radius: var(--plex-radius-sm);\r\n overflow: hidden;\r\n flex-shrink: 0;\r\n}\r\n\r\n.playlist-item-thumbnail img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n}\r\n\r\n.playlist-item-thumbnail .placeholder-icon {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n font-size: 32px;\r\n color: var(--plex-text-secondary);\r\n opacity: 0.5;\r\n}\r\n\r\n.playlist-item-duration {\r\n position: absolute;\r\n bottom: 4px;\r\n right: 4px;\r\n padding: 2px 6px;\r\n background: rgba(0, 0, 0, 0.8);\r\n border-radius: 3px;\r\n font-size: 11px;\r\n font-weight: 600;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n/* Playing Indicator */\r\n.playlist-item-playing-indicator {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n display: none;\r\n align-items: flex-end;\r\n justify-content: center;\r\n gap: 2px;\r\n width: 24px;\r\n height: 20px;\r\n}\r\n\r\n.playlist-item.playing .playlist-item-playing-indicator {\r\n display: flex;\r\n}\r\n\r\n.playlist-item-playing-indicator span {\r\n width: 4px;\r\n background: var(--plex-primary);\r\n border-radius: 1px;\r\n animation: equalizer 0.5s ease-in-out infinite alternate;\r\n}\r\n\r\n.playlist-item-playing-indicator span:nth-child(1) {\r\n height: 60%;\r\n animation-delay: 0s;\r\n}\r\n\r\n.playlist-item-playing-indicator span:nth-child(2) {\r\n height: 100%;\r\n animation-delay: 0.15s;\r\n}\r\n\r\n.playlist-item-playing-indicator span:nth-child(3) {\r\n height: 40%;\r\n animation-delay: 0.3s;\r\n}\r\n\r\n@keyframes equalizer {\r\n from {\r\n transform: scaleY(0.5);\r\n }\r\n to {\r\n transform: scaleY(1);\r\n }\r\n}\r\n\r\n/* Playlist Item Info */\r\n.playlist-item-info {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n}\r\n\r\n.playlist-item-title {\r\n font-size: 14px;\r\n font-weight: 500;\r\n color: var(--plex-text-primary);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n}\r\n\r\n.playlist-item-meta {\r\n font-size: 12px;\r\n color: var(--plex-text-secondary);\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n}\r\n\r\n/* Playlist Item Actions */\r\n.playlist-item-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n opacity: 0;\r\n transition: opacity var(--plex-transition-fast);\r\n}\r\n\r\n.playlist-item:hover .playlist-item-actions {\r\n opacity: 1;\r\n}\r\n\r\n.playlist-item-action {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 28px;\r\n height: 28px;\r\n background: transparent;\r\n border: none;\r\n border-radius: var(--plex-radius-sm);\r\n cursor: pointer;\r\n color: var(--plex-text-secondary);\r\n transition: all var(--plex-transition-fast);\r\n}\r\n\r\n.playlist-item-action:hover {\r\n background: rgba(255, 255, 255, 0.1);\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.playlist-item-action .material-icons {\r\n font-size: 18px;\r\n}\r\n\r\n/* Drag Handle */\r\n.playlist-item-drag-handle {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 20px;\r\n cursor: grab;\r\n color: var(--plex-text-secondary);\r\n opacity: 0;\r\n transition: opacity var(--plex-transition-fast);\r\n}\r\n\r\n.playlist-item:hover .playlist-item-drag-handle {\r\n opacity: 1;\r\n}\r\n\r\n.playlist-item-drag-handle:active {\r\n cursor: grabbing;\r\n}\r\n\r\n.playlist-item-drag-handle .material-icons {\r\n font-size: 18px;\r\n}\r\n\r\n/* Playlist Footer */\r\n.playlist-footer {\r\n padding: 16px;\r\n border-top: 1px solid var(--plex-border);\r\n flex-shrink: 0;\r\n}\r\n\r\n.playlist-add-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 8px;\r\n width: 100%;\r\n padding: 12px;\r\n background: rgba(255, 255, 255, 0.05);\r\n border: 2px dashed var(--plex-border);\r\n border-radius: var(--plex-radius-md);\r\n color: var(--plex-text-secondary);\r\n font-size: 14px;\r\n font-weight: 500;\r\n cursor: pointer;\r\n transition: all var(--plex-transition-fast);\r\n}\r\n\r\n.playlist-add-btn:hover {\r\n background: rgba(255, 255, 255, 0.08);\r\n border-color: var(--plex-primary);\r\n color: var(--plex-primary);\r\n}\r\n\r\n.playlist-add-btn .material-icons {\r\n font-size: 20px;\r\n}\r\n\r\n/* Playlist Stats */\r\n.playlist-stats {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 12px 16px;\r\n background: rgba(0, 0, 0, 0.3);\r\n border-top: 1px solid var(--plex-border);\r\n font-size: 12px;\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n/* Queue Next Indicator */\r\n.playlist-item-queue-next {\r\n position: absolute;\r\n top: 4px;\r\n left: 4px;\r\n padding: 2px 6px;\r\n background: var(--plex-primary);\r\n border-radius: 3px;\r\n font-size: 9px;\r\n font-weight: 700;\r\n color: #000;\r\n text-transform: uppercase;\r\n}\r\n\r\n/* Responsive Playlist */\r\n@media (max-width: 768px) {\r\n .playlist-panel {\r\n width: 100%;\r\n max-width: 100%;\r\n }\r\n \r\n .playlist-item-thumbnail {\r\n width: 80px;\r\n height: 45px;\r\n }\r\n \r\n .playlist-item-title {\r\n font-size: 13px;\r\n }\r\n \r\n .playlist-item-actions {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n@media (max-width: 480px) {\r\n .playlist-header {\r\n padding: 12px 16px;\r\n }\r\n \r\n .playlist-content {\r\n padding: 8px;\r\n }\r\n \r\n .playlist-item {\r\n padding: 8px;\r\n gap: 10px;\r\n }\r\n \r\n .playlist-item-thumbnail {\r\n width: 70px;\r\n height: 40px;\r\n }\r\n \r\n .playlist-item-drag-handle {\r\n display: none;\r\n }\r\n}\r\n\r\n/* Drag and Drop States */\r\n.playlist-content.drag-over {\r\n background: rgba(229, 160, 13, 0.05);\r\n}\r\n\r\n.playlist-item.drop-target-above::before {\r\n content: '';\r\n position: absolute;\r\n top: -4px;\r\n left: 0;\r\n right: 0;\r\n height: 2px;\r\n background: var(--plex-primary);\r\n border-radius: 1px;\r\n}\r\n\r\n.playlist-item.drop-target-below::after {\r\n content: '';\r\n position: absolute;\r\n bottom: -4px;\r\n left: 0;\r\n right: 0;\r\n height: 2px;\r\n background: var(--plex-primary);\r\n border-radius: 1px;\r\n}\r\n","/* =====================================================\r\n PLEX Video Player - Settings Styles\r\n ===================================================== */\r\n\r\n/* Settings Panel */\r\n.settings-panel {\r\n position: absolute;\r\n bottom: 80px;\r\n right: 20px;\r\n width: 300px;\r\n max-height: 400px;\r\n background: var(--plex-bg-dark);\r\n border: 1px solid var(--plex-border);\r\n border-radius: var(--plex-radius-lg);\r\n box-shadow: var(--plex-shadow);\r\n z-index: var(--plex-z-panel);\r\n overflow: hidden;\r\n transform-origin: bottom right;\r\n animation: settingsOpen 0.2s ease;\r\n}\r\n\r\n@keyframes settingsOpen {\r\n from {\r\n opacity: 0;\r\n transform: scale(0.95);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n}\r\n\r\n/* Settings Header */\r\n.settings-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 12px 16px;\r\n background: rgba(255, 255, 255, 0.03);\r\n border-bottom: 1px solid var(--plex-border);\r\n}\r\n\r\n.settings-title {\r\n font-size: 15px;\r\n font-weight: 600;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n/* Settings Content */\r\n.settings-content {\r\n max-height: 340px;\r\n overflow-y: auto;\r\n}\r\n\r\n.settings-content::-webkit-scrollbar {\r\n width: 6px;\r\n}\r\n\r\n.settings-content::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n\r\n.settings-content::-webkit-scrollbar-thumb {\r\n background: rgba(255, 255, 255, 0.2);\r\n border-radius: 3px;\r\n}\r\n\r\n/* Settings Menu */\r\n.settings-menu {\r\n padding: 8px 0;\r\n}\r\n\r\n/* Settings Item */\r\n.settings-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 12px 16px;\r\n cursor: pointer;\r\n transition: background var(--plex-transition-fast);\r\n}\r\n\r\n.settings-item:hover {\r\n background: rgba(255, 255, 255, 0.05);\r\n}\r\n\r\n.settings-item .material-icons:first-child {\r\n font-size: 22px;\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n.settings-item-label {\r\n flex: 1;\r\n font-size: 14px;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.settings-item-value {\r\n font-size: 13px;\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n.settings-item .material-icons:last-child {\r\n font-size: 20px;\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n/* Settings Submenu */\r\n.settings-submenu {\r\n padding: 8px 0;\r\n}\r\n\r\n/* Settings Option */\r\n.settings-option {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 12px 16px;\r\n cursor: pointer;\r\n transition: background var(--plex-transition-fast);\r\n font-size: 14px;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.settings-option:hover {\r\n background: rgba(255, 255, 255, 0.05);\r\n}\r\n\r\n.settings-option.active {\r\n color: var(--plex-primary);\r\n}\r\n\r\n.settings-option.active::after {\r\n content: 'check';\r\n font-family: 'Material Icons';\r\n font-size: 20px;\r\n color: var(--plex-primary);\r\n}\r\n\r\n/* Toggle Switch */\r\n.toggle-switch {\r\n position: relative;\r\n width: 44px;\r\n height: 24px;\r\n background: rgba(255, 255, 255, 0.2);\r\n border-radius: 12px;\r\n cursor: pointer;\r\n transition: background var(--plex-transition-fast);\r\n}\r\n\r\n.toggle-switch.active {\r\n background: var(--plex-primary);\r\n}\r\n\r\n.toggle-slider {\r\n position: absolute;\r\n top: 2px;\r\n left: 2px;\r\n width: 20px;\r\n height: 20px;\r\n background: #fff;\r\n border-radius: 50%;\r\n transition: transform var(--plex-transition-fast);\r\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\r\n}\r\n\r\n.toggle-switch.active .toggle-slider {\r\n transform: translateX(20px);\r\n}\r\n\r\n/* Subtitles Settings Panel */\r\n.subtitles-settings-panel {\r\n position: absolute;\r\n bottom: 80px;\r\n right: 20px;\r\n width: 320px;\r\n background: var(--plex-bg-dark);\r\n border: 1px solid var(--plex-border);\r\n border-radius: var(--plex-radius-lg);\r\n box-shadow: var(--plex-shadow);\r\n z-index: var(--plex-z-panel);\r\n overflow: hidden;\r\n}\r\n\r\n.subtitles-settings-content {\r\n padding: 16px;\r\n}\r\n\r\n/* Subtitle Setting Item */\r\n.subtitle-setting-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n margin-bottom: 16px;\r\n}\r\n\r\n.subtitle-setting-item label {\r\n flex: 0 0 100px;\r\n font-size: 13px;\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n.subtitle-setting-item input[type=\"range\"] {\r\n flex: 1;\r\n -webkit-appearance: none;\r\n appearance: none;\r\n height: 4px;\r\n background: rgba(255, 255, 255, 0.2);\r\n border-radius: 2px;\r\n outline: none;\r\n}\r\n\r\n.subtitle-setting-item input[type=\"range\"]::-webkit-slider-thumb {\r\n -webkit-appearance: none;\r\n appearance: none;\r\n width: 16px;\r\n height: 16px;\r\n background: var(--plex-primary);\r\n border-radius: 50%;\r\n cursor: pointer;\r\n}\r\n\r\n.subtitle-setting-item input[type=\"color\"] {\r\n -webkit-appearance: none;\r\n appearance: none;\r\n width: 40px;\r\n height: 30px;\r\n border: none;\r\n border-radius: var(--plex-radius-sm);\r\n cursor: pointer;\r\n background: transparent;\r\n}\r\n\r\n.subtitle-setting-item input[type=\"color\"]::-webkit-color-swatch-wrapper {\r\n padding: 0;\r\n}\r\n\r\n.subtitle-setting-item input[type=\"color\"]::-webkit-color-swatch {\r\n border: 2px solid var(--plex-border);\r\n border-radius: var(--plex-radius-sm);\r\n}\r\n\r\n.subtitle-setting-item span:last-child {\r\n flex: 0 0 50px;\r\n text-align: right;\r\n font-size: 13px;\r\n color: var(--plex-text-primary);\r\n font-weight: 500;\r\n}\r\n\r\n/* Subtitle Load Button */\r\n.subtitle-load-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 8px;\r\n width: 100%;\r\n padding: 12px;\r\n margin-top: 8px;\r\n background: rgba(255, 255, 255, 0.05);\r\n border: 1px solid var(--plex-border);\r\n border-radius: var(--plex-radius-md);\r\n color: var(--plex-text-primary);\r\n font-size: 14px;\r\n cursor: pointer;\r\n transition: all var(--plex-transition-fast);\r\n}\r\n\r\n.subtitle-load-btn:hover {\r\n background: rgba(255, 255, 255, 0.1);\r\n border-color: var(--plex-primary);\r\n}\r\n\r\n.subtitle-load-btn .material-icons {\r\n font-size: 20px;\r\n}\r\n\r\n/* Speed Panel (Alternative) */\r\n.speed-panel {\r\n position: absolute;\r\n bottom: 80px;\r\n right: 60px;\r\n width: 200px;\r\n background: var(--plex-bg-dark);\r\n border: 1px solid var(--plex-border);\r\n border-radius: var(--plex-radius-lg);\r\n box-shadow: var(--plex-shadow);\r\n z-index: var(--plex-z-panel);\r\n overflow: hidden;\r\n padding: 8px 0;\r\n}\r\n\r\n/* Quality Badge */\r\n.quality-badge {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 2px 6px;\r\n background: var(--plex-primary);\r\n border-radius: 3px;\r\n font-size: 10px;\r\n font-weight: 700;\r\n color: #000;\r\n text-transform: uppercase;\r\n margin-left: 8px;\r\n}\r\n\r\n/* Section Divider */\r\n.settings-divider {\r\n height: 1px;\r\n background: var(--plex-border);\r\n margin: 8px 16px;\r\n}\r\n\r\n/* Settings Group Label */\r\n.settings-group-label {\r\n padding: 8px 16px 4px;\r\n font-size: 11px;\r\n font-weight: 600;\r\n color: var(--plex-text-secondary);\r\n text-transform: uppercase;\r\n letter-spacing: 0.5px;\r\n}\r\n\r\n/* Responsive Settings */\r\n@media (max-width: 768px) {\r\n .settings-panel {\r\n position: fixed;\r\n top: auto;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n width: 100%;\r\n max-height: 60vh;\r\n border-radius: var(--plex-radius-lg) var(--plex-radius-lg) 0 0;\r\n transform-origin: bottom center;\r\n }\r\n \r\n .subtitles-settings-panel {\r\n position: fixed;\r\n top: auto;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n width: 100%;\r\n max-height: 70vh;\r\n border-radius: var(--plex-radius-lg) var(--plex-radius-lg) 0 0;\r\n }\r\n \r\n .settings-item {\r\n padding: 14px 20px;\r\n }\r\n \r\n .settings-option {\r\n padding: 14px 20px;\r\n }\r\n}\r\n\r\n@media (max-width: 480px) {\r\n .settings-content {\r\n max-height: 50vh;\r\n }\r\n \r\n .subtitle-setting-item {\r\n flex-wrap: wrap;\r\n }\r\n \r\n .subtitle-setting-item label {\r\n flex: 0 0 100%;\r\n margin-bottom: 8px;\r\n }\r\n \r\n .subtitle-setting-item input[type=\"range\"] {\r\n flex: 1;\r\n }\r\n}\r\n\r\n/* Animation for panel open/close */\r\n.settings-panel.closing {\r\n animation: settingsClose 0.15s ease forwards;\r\n}\r\n\r\n@keyframes settingsClose {\r\n from {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n to {\r\n opacity: 0;\r\n transform: scale(0.95);\r\n }\r\n}\r\n\r\n/* Keyboard Shortcut Hints */\r\n.shortcut-hint {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n min-width: 24px;\r\n height: 24px;\r\n padding: 0 6px;\r\n background: rgba(255, 255, 255, 0.1);\r\n border: 1px solid var(--plex-border);\r\n border-radius: 4px;\r\n font-size: 11px;\r\n font-weight: 600;\r\n color: var(--plex-text-secondary);\r\n margin-left: auto;\r\n}\r\n\r\n/* Audio Track Indicator */\r\n.audio-track-indicator {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n font-size: 12px;\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n.audio-track-indicator .material-icons {\r\n font-size: 16px;\r\n}\r\n"]}
1
+ {"version":3,"sources":["main.css","controls.css","playlist.css","settings.css"],"names":[],"mappings":"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","file":"plex-player.css","sourcesContent":["/* =====================================================\r\n PLEX Video Player - Main Styles\r\n ===================================================== */\r\n\r\n/* CSS Variables - scoped to player */\r\n.plex-player,\r\n.plex-player-container {\r\n --plex-primary: #e5a00d;\r\n --plex-primary-hover: #f5b82e;\r\n --plex-bg-dark: #1a1a1a;\r\n --plex-bg-darker: #0d0d0d;\r\n --plex-bg-overlay: rgba(0, 0, 0, 0.85);\r\n --plex-text-primary: #ffffff;\r\n --plex-text-secondary: #a0a0a0;\r\n --plex-border: rgba(255, 255, 255, 0.1);\r\n --plex-gradient: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, transparent 100%);\r\n --plex-gradient-top: linear-gradient(to bottom, rgba(0, 0, 0, 0.7) 0%, transparent 100%);\r\n --plex-transition-fast: 0.15s ease;\r\n --plex-transition-normal: 0.25s ease;\r\n --plex-transition-slow: 0.4s ease;\r\n --plex-radius-sm: 4px;\r\n --plex-radius-md: 8px;\r\n --plex-radius-lg: 12px;\r\n --plex-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);\r\n --plex-z-video: 1;\r\n --plex-z-overlay: 10;\r\n --plex-z-controls: 20;\r\n --plex-z-panel: 30;\r\n --plex-z-modal: 40;\r\n --plex-z-toast: 50;\r\n}\r\n\r\n/* Scoped Reset - only inside player */\r\n.plex-player *,\r\n.plex-player *::before,\r\n.plex-player *::after {\r\n box-sizing: border-box;\r\n margin: 0;\r\n padding: 0;\r\n}\r\n\r\n/* Player Container Wrapper */\r\n.plex-player-container {\r\n position: relative;\r\n width: 100%;\r\n aspect-ratio: 16 / 9;\r\n background: var(--plex-bg-darker);\r\n border-radius: var(--plex-radius-md);\r\n overflow: hidden;\r\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n -webkit-font-smoothing: antialiased;\r\n -moz-osx-font-smoothing: grayscale;\r\n}\r\n\r\n/* Player Container */\r\n.plex-player {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\r\n background: var(--plex-bg-darker);\r\n overflow: hidden;\r\n user-select: none;\r\n -webkit-user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.plex-player.fullscreen {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100vw;\r\n height: 100vh;\r\n z-index: 9999;\r\n}\r\n\r\n/* Video Container */\r\n.video-container {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n background: #000;\r\n z-index: var(--plex-z-video);\r\n}\r\n\r\n.video-container video {\r\n width: 100%;\r\n height: 100%;\r\n max-width: 100%;\r\n max-height: 100%;\r\n object-fit: contain;\r\n background: #000;\r\n}\r\n\r\n/* Controls Visibility */\r\n.plex-player.controls-visible .top-controls,\r\n.plex-player.controls-visible .bottom-controls {\r\n opacity: 1;\r\n visibility: visible;\r\n transform: translateY(0);\r\n}\r\n\r\n.plex-player:not(.controls-visible) .top-controls,\r\n.plex-player:not(.controls-visible) .bottom-controls {\r\n opacity: 0;\r\n visibility: hidden;\r\n}\r\n\r\n.plex-player:not(.controls-visible) .top-controls {\r\n transform: translateY(-100%);\r\n}\r\n\r\n.plex-player:not(.controls-visible) .bottom-controls {\r\n transform: translateY(100%);\r\n}\r\n\r\n/* Cursor hiding */\r\n.plex-player.hide-cursor {\r\n cursor: none;\r\n}\r\n\r\n.plex-player.hide-cursor video {\r\n cursor: none;\r\n}\r\n\r\n/* Loading Spinner */\r\n.loading-spinner {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n z-index: var(--plex-z-overlay);\r\n}\r\n\r\n.loading-spinner .spinner {\r\n width: 60px;\r\n height: 60px;\r\n border: 4px solid rgba(255, 255, 255, 0.2);\r\n border-top-color: var(--plex-primary);\r\n border-radius: 50%;\r\n animation: spin 1s linear infinite;\r\n}\r\n\r\n@keyframes spin {\r\n to {\r\n transform: rotate(360deg);\r\n }\r\n}\r\n\r\n/* Big Play Button */\r\n.big-play-btn {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%) scale(1);\r\n width: 80px;\r\n height: 80px;\r\n background: var(--plex-primary);\r\n border-radius: 50%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n z-index: var(--plex-z-overlay);\r\n transition: all var(--plex-transition-normal);\r\n box-shadow: 0 4px 30px rgba(229, 160, 13, 0.4);\r\n}\r\n\r\n.big-play-btn:hover {\r\n transform: translate(-50%, -50%) scale(1.1);\r\n background: var(--plex-primary-hover);\r\n}\r\n\r\n.big-play-btn .material-icons {\r\n font-size: 48px;\r\n color: #000;\r\n margin-left: 4px;\r\n}\r\n\r\n.big-play-btn.hidden {\r\n opacity: 0;\r\n visibility: hidden;\r\n transform: translate(-50%, -50%) scale(0.8);\r\n}\r\n\r\n/* Gesture Overlay */\r\n.gesture-overlay {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n display: flex;\r\n z-index: var(--plex-z-overlay);\r\n pointer-events: none;\r\n}\r\n\r\n.gesture-left,\r\n.gesture-right {\r\n flex: 1;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n.gesture-center {\r\n flex: 1;\r\n}\r\n\r\n.gesture-indicator {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 20px;\r\n background: rgba(0, 0, 0, 0.7);\r\n border-radius: var(--plex-radius-lg);\r\n opacity: 0;\r\n transform: scale(0.8);\r\n transition: all var(--plex-transition-fast);\r\n}\r\n\r\n.gesture-indicator.active {\r\n opacity: 1;\r\n transform: scale(1);\r\n}\r\n\r\n.gesture-indicator .material-icons {\r\n font-size: 48px;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.gesture-indicator .gesture-text {\r\n font-size: 14px;\r\n font-weight: 600;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n/* Volume/Brightness Indicators */\r\n.volume-indicator,\r\n.brightness-indicator {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 24px;\r\n background: rgba(0, 0, 0, 0.8);\r\n border-radius: var(--plex-radius-lg);\r\n z-index: var(--plex-z-overlay);\r\n transition: opacity var(--plex-transition-fast);\r\n}\r\n\r\n.volume-indicator .material-icons,\r\n.brightness-indicator .material-icons {\r\n font-size: 36px;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.volume-indicator-bar,\r\n.brightness-indicator-bar {\r\n width: 120px;\r\n height: 4px;\r\n background: rgba(255, 255, 255, 0.2);\r\n border-radius: 2px;\r\n overflow: hidden;\r\n}\r\n\r\n.volume-indicator-fill,\r\n.brightness-indicator-fill {\r\n height: 100%;\r\n background: var(--plex-primary);\r\n border-radius: 2px;\r\n transition: width var(--plex-transition-fast);\r\n}\r\n\r\n/* Subtitles Container */\r\n.subtitles-container {\r\n position: absolute;\r\n bottom: 80px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n width: 80%;\r\n max-width: 800px;\r\n text-align: center;\r\n z-index: var(--plex-z-overlay);\r\n pointer-events: none;\r\n}\r\n\r\n.subtitle-line {\r\n display: inline-block;\r\n padding: 8px 16px;\r\n margin: 4px 0;\r\n background: rgba(0, 0, 0, 0.75);\r\n border-radius: var(--plex-radius-sm);\r\n font-size: 24px;\r\n line-height: 1.4;\r\n color: #fff;\r\n text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8);\r\n}\r\n\r\n/* Cast Overlay */\r\n.cast-overlay {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background: var(--plex-bg-darker);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: var(--plex-z-overlay);\r\n}\r\n\r\n.cast-overlay.hidden {\r\n display: none;\r\n}\r\n\r\n.cast-overlay-content {\r\n text-align: center;\r\n animation: castPulse 2s ease-in-out infinite;\r\n}\r\n\r\n.cast-overlay .cast-icon {\r\n font-size: 80px;\r\n color: var(--plex-primary);\r\n margin-bottom: 24px;\r\n}\r\n\r\n.cast-overlay .cast-title {\r\n font-size: 18px;\r\n color: var(--plex-text-secondary);\r\n margin-bottom: 8px;\r\n}\r\n\r\n.cast-overlay .cast-device {\r\n font-size: 28px;\r\n font-weight: 600;\r\n color: var(--plex-text-primary);\r\n margin-bottom: 16px;\r\n}\r\n\r\n.cast-overlay .cast-video {\r\n font-size: 16px;\r\n color: var(--plex-text-secondary);\r\n max-width: 300px;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n}\r\n\r\n@keyframes castPulse {\r\n 0%, 100% { opacity: 1; }\r\n 50% { opacity: 0.7; }\r\n}\r\n\r\n/* Utility Classes */\r\n.hidden {\r\n display: none !important;\r\n}\r\n\r\n.visually-hidden {\r\n opacity: 0;\r\n visibility: hidden;\r\n}\r\n\r\n/* Toast Notification */\r\n.toast {\r\n position: absolute;\r\n bottom: 100px;\r\n left: 50%;\r\n transform: translateX(-50%) translateY(20px);\r\n background: var(--plex-bg-overlay);\r\n padding: 12px 24px;\r\n border-radius: var(--plex-radius-md);\r\n z-index: var(--plex-z-toast);\r\n opacity: 0;\r\n visibility: hidden;\r\n transition: all var(--plex-transition-normal);\r\n}\r\n\r\n.toast.show {\r\n opacity: 1;\r\n visibility: visible;\r\n transform: translateX(-50%) translateY(0);\r\n}\r\n\r\n.toast-message {\r\n font-size: 14px;\r\n font-weight: 500;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n/* Context Menu */\r\n.context-menu {\r\n position: fixed;\r\n min-width: 200px;\r\n background: var(--plex-bg-dark);\r\n border: 1px solid var(--plex-border);\r\n border-radius: var(--plex-radius-md);\r\n box-shadow: var(--plex-shadow);\r\n z-index: var(--plex-z-modal);\r\n overflow: hidden;\r\n}\r\n\r\n.context-menu-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 12px 16px;\r\n cursor: pointer;\r\n transition: background var(--plex-transition-fast);\r\n}\r\n\r\n.context-menu-item:hover {\r\n background: rgba(255, 255, 255, 0.1);\r\n}\r\n\r\n.context-menu-item .material-icons {\r\n font-size: 20px;\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n.context-menu-item span:last-child {\r\n font-size: 14px;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.context-menu-divider {\r\n height: 1px;\r\n background: var(--plex-border);\r\n margin: 4px 0;\r\n}\r\n\r\n/* Stats Overlay */\r\n.stats-overlay {\r\n position: absolute;\r\n top: 80px;\r\n left: 20px;\r\n width: 280px;\r\n background: var(--plex-bg-overlay);\r\n border-radius: var(--plex-radius-md);\r\n z-index: var(--plex-z-panel);\r\n overflow: hidden;\r\n}\r\n\r\n.stats-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 12px 16px;\r\n background: rgba(255, 255, 255, 0.05);\r\n border-bottom: 1px solid var(--plex-border);\r\n font-size: 14px;\r\n font-weight: 600;\r\n}\r\n\r\n.stats-content {\r\n padding: 12px 16px;\r\n}\r\n\r\n.stat-item {\r\n display: flex;\r\n justify-content: space-between;\r\n padding: 8px 0;\r\n font-size: 13px;\r\n border-bottom: 1px solid var(--plex-border);\r\n}\r\n\r\n.stat-item:last-child {\r\n border-bottom: none;\r\n}\r\n\r\n.stat-label {\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n.stat-value {\r\n color: var(--plex-text-primary);\r\n font-weight: 500;\r\n}\r\n\r\n/* Responsive */\r\n@media (max-width: 768px) {\r\n .big-play-btn {\r\n width: 64px;\r\n height: 64px;\r\n }\r\n \r\n .big-play-btn .material-icons {\r\n font-size: 36px;\r\n }\r\n \r\n .subtitle-line {\r\n font-size: 18px;\r\n padding: 6px 12px;\r\n }\r\n \r\n .subtitles-container {\r\n width: 90%;\r\n bottom: 70px;\r\n }\r\n \r\n .gesture-indicator .material-icons {\r\n font-size: 36px;\r\n }\r\n \r\n .stats-overlay {\r\n top: 60px;\r\n left: 10px;\r\n width: 240px;\r\n }\r\n}\r\n\r\n@media (max-width: 480px) {\r\n .big-play-btn {\r\n width: 56px;\r\n height: 56px;\r\n }\r\n \r\n .big-play-btn .material-icons {\r\n font-size: 32px;\r\n }\r\n \r\n .subtitle-line {\r\n font-size: 16px;\r\n }\r\n}\r\n\r\n/* Touch Device Optimizations */\r\n@media (hover: none) and (pointer: coarse) {\r\n .control-btn {\r\n min-width: 44px;\r\n min-height: 44px;\r\n }\r\n \r\n .volume-slider-container {\r\n display: none;\r\n }\r\n}\r\n\r\n/* Animations */\r\n@keyframes fadeIn {\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n@keyframes slideUp {\r\n from {\r\n opacity: 0;\r\n transform: translateY(20px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n}\r\n\r\n@keyframes pulse {\r\n 0%, 100% {\r\n transform: translate(-50%, -50%) scale(1);\r\n }\r\n 50% {\r\n transform: translate(-50%, -50%) scale(1.05);\r\n }\r\n}\r\n","/* =====================================================\r\n PLEX Video Player - Controls Styles\r\n ===================================================== */\r\n\r\n/* Top Controls Bar */\r\n.top-controls {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 16px 20px;\r\n background: var(--plex-gradient-top);\r\n z-index: var(--plex-z-controls);\r\n transition: all var(--plex-transition-normal);\r\n}\r\n\r\n.top-left,\r\n.top-right {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n}\r\n\r\n.video-title {\r\n font-size: 16px;\r\n font-weight: 600;\r\n color: var(--plex-text-primary);\r\n margin-left: 8px;\r\n max-width: 400px;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n}\r\n\r\n/* Bottom Controls */\r\n.bottom-controls {\r\n position: absolute;\r\n bottom: 0;\r\n left: 0;\r\n width: 100%;\r\n padding: 0 16px 16px;\r\n background: var(--plex-gradient);\r\n z-index: var(--plex-z-controls);\r\n transition: all var(--plex-transition-normal);\r\n}\r\n\r\n/* Progress Container */\r\n.progress-container {\r\n position: relative;\r\n width: 100%;\r\n height: 24px;\r\n display: flex;\r\n align-items: center;\r\n cursor: pointer;\r\n padding: 8px 0;\r\n}\r\n\r\n.progress-bar {\r\n position: relative;\r\n width: 100%;\r\n height: 4px;\r\n background: rgba(255, 255, 255, 0.2);\r\n border-radius: 2px;\r\n overflow: visible;\r\n transition: height var(--plex-transition-fast);\r\n}\r\n\r\n.progress-container:hover .progress-bar {\r\n height: 6px;\r\n}\r\n\r\n.progress-buffered {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n height: 100%;\r\n background: rgba(255, 255, 255, 0.35);\r\n border-radius: 2px;\r\n pointer-events: none;\r\n}\r\n\r\n.progress-played {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n height: 100%;\r\n background: var(--plex-primary);\r\n border-radius: 2px;\r\n pointer-events: none;\r\n}\r\n\r\n.progress-handle {\r\n position: absolute;\r\n top: 50%;\r\n left: 0;\r\n width: 14px;\r\n height: 14px;\r\n background: var(--plex-primary);\r\n border-radius: 50%;\r\n transform: translate(-50%, -50%) scale(0);\r\n transition: transform var(--plex-transition-fast);\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);\r\n pointer-events: none;\r\n}\r\n\r\n.progress-container:hover .progress-handle,\r\n.progress-container.dragging .progress-handle {\r\n transform: translate(-50%, -50%) scale(1);\r\n}\r\n\r\n.progress-container.dragging .progress-bar {\r\n height: 6px;\r\n}\r\n\r\n/* Progress Tooltip */\r\n.progress-tooltip {\r\n position: absolute;\r\n bottom: 100%;\r\n left: 0;\r\n padding: 6px 10px;\r\n background: var(--plex-bg-dark);\r\n border-radius: var(--plex-radius-sm);\r\n font-size: 13px;\r\n font-weight: 500;\r\n white-space: nowrap;\r\n opacity: 0;\r\n visibility: hidden;\r\n transform: translateX(-50%) translateY(4px);\r\n transition: all var(--plex-transition-fast);\r\n pointer-events: none;\r\n z-index: 50;\r\n}\r\n\r\n.progress-container:hover .progress-tooltip {\r\n opacity: 1;\r\n visibility: visible;\r\n transform: translateX(-50%) translateY(-4px);\r\n}\r\n\r\n/* Hide tooltip when preview is visible */\r\n.progress-container:hover .progress-preview[style*=\"display: flex\"] ~ .progress-tooltip,\r\n.progress-preview:not([style*=\"display: none\"]) + .progress-tooltip {\r\n opacity: 0;\r\n visibility: hidden;\r\n}\r\n\r\n/* Progress Preview (Thumbnail) */\r\n.progress-preview {\r\n position: absolute;\r\n bottom: calc(100% + 16px);\r\n left: 0;\r\n display: none;\r\n flex-direction: column;\r\n align-items: center;\r\n z-index: 100;\r\n pointer-events: none;\r\n background: rgba(0, 0, 0, 0.9);\r\n padding: 4px;\r\n border-radius: var(--plex-radius-sm);\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);\r\n}\r\n\r\n#preview-canvas {\r\n width: 160px;\r\n height: 90px;\r\n background: var(--plex-bg-dark);\r\n border: 2px solid var(--plex-primary);\r\n border-radius: var(--plex-radius-sm);\r\n object-fit: contain;\r\n}\r\n\r\n.preview-time {\r\n margin-top: 6px;\r\n padding: 4px 10px;\r\n background: var(--plex-primary);\r\n color: #000;\r\n border-radius: var(--plex-radius-sm);\r\n font-size: 12px;\r\n font-weight: 700;\r\n}\r\n\r\n/* Time Display */\r\n.time-display {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n padding: 8px 0;\r\n font-size: 13px;\r\n font-weight: 500;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.time-separator {\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n/* Main Controls Row */\r\n.main-controls {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n margin-top: 4px;\r\n}\r\n\r\n.controls-left,\r\n.controls-right {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n}\r\n\r\n/* Control Button */\r\n.control-btn {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 40px;\r\n height: 40px;\r\n background: transparent;\r\n border: none;\r\n border-radius: var(--plex-radius-sm);\r\n cursor: pointer;\r\n transition: all var(--plex-transition-fast);\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.control-btn:hover {\r\n background: rgba(255, 255, 255, 0.1);\r\n}\r\n\r\n.control-btn:active {\r\n transform: scale(0.95);\r\n}\r\n\r\n.control-btn .material-icons {\r\n font-size: 24px;\r\n}\r\n\r\n.control-btn.active {\r\n color: var(--plex-primary);\r\n}\r\n\r\n/* Cast Button */\r\n#cast-btn {\r\n transition: all var(--plex-transition-fast);\r\n}\r\n\r\n#cast-btn.active {\r\n color: var(--plex-primary);\r\n animation: pulse-cast 2s ease-in-out infinite;\r\n}\r\n\r\n#cast-btn.hidden {\r\n display: none;\r\n}\r\n\r\n@keyframes pulse-cast {\r\n 0%, 100% { opacity: 1; }\r\n 50% { opacity: 0.6; }\r\n}\r\n\r\n/* Play Button (Larger) */\r\n.play-btn {\r\n width: 48px;\r\n height: 48px;\r\n}\r\n\r\n.play-btn .material-icons {\r\n font-size: 32px;\r\n}\r\n\r\n/* Speed Text */\r\n.speed-text {\r\n font-size: 14px;\r\n font-weight: 600;\r\n min-width: 28px;\r\n}\r\n\r\n/* Volume Control */\r\n.volume-control {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n}\r\n\r\n.volume-slider-container {\r\n position: relative;\r\n width: 0;\r\n overflow: hidden;\r\n transition: width var(--plex-transition-normal);\r\n}\r\n\r\n.volume-control:hover .volume-slider-container {\r\n width: 80px;\r\n}\r\n\r\n.volume-slider {\r\n -webkit-appearance: none;\r\n appearance: none;\r\n width: 80px;\r\n height: 4px;\r\n background: rgba(255, 255, 255, 0.2);\r\n border-radius: 2px;\r\n outline: none;\r\n cursor: pointer;\r\n}\r\n\r\n.volume-slider::-webkit-slider-thumb {\r\n -webkit-appearance: none;\r\n appearance: none;\r\n width: 14px;\r\n height: 14px;\r\n background: var(--plex-primary);\r\n border-radius: 50%;\r\n cursor: pointer;\r\n transition: transform var(--plex-transition-fast);\r\n}\r\n\r\n.volume-slider::-webkit-slider-thumb:hover {\r\n transform: scale(1.2);\r\n}\r\n\r\n.volume-slider::-moz-range-thumb {\r\n width: 14px;\r\n height: 14px;\r\n background: var(--plex-primary);\r\n border: none;\r\n border-radius: 50%;\r\n cursor: pointer;\r\n}\r\n\r\n.volume-slider-fill {\r\n position: absolute;\r\n top: 50%;\r\n left: 0;\r\n height: 4px;\r\n background: var(--plex-primary);\r\n border-radius: 2px;\r\n transform: translateY(-50%);\r\n pointer-events: none;\r\n}\r\n\r\n/* Chapters Markers (on progress bar) */\r\n.chapter-marker {\r\n position: absolute;\r\n top: 0;\r\n width: 3px;\r\n height: 100%;\r\n background: rgba(255, 255, 255, 0.8);\r\n border-radius: 1px;\r\n transform: translateX(-50%);\r\n cursor: pointer;\r\n z-index: 2;\r\n}\r\n\r\n.chapter-marker:hover {\r\n background: var(--plex-primary);\r\n}\r\n\r\n/* Skip Intro Button */\r\n.skip-intro-btn {\r\n position: absolute;\r\n right: 20px;\r\n bottom: 100px;\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 12px 20px;\r\n background: rgba(255, 255, 255, 0.9);\r\n color: #000;\r\n border: none;\r\n border-radius: var(--plex-radius-md);\r\n font-size: 14px;\r\n font-weight: 600;\r\n cursor: pointer;\r\n z-index: var(--plex-z-controls);\r\n transition: all var(--plex-transition-normal);\r\n}\r\n\r\n.skip-intro-btn:hover {\r\n background: #fff;\r\n transform: scale(1.02);\r\n}\r\n\r\n.skip-intro-btn .material-icons {\r\n font-size: 20px;\r\n}\r\n\r\n/* Double Tap Ripple Effect */\r\n.tap-ripple {\r\n position: absolute;\r\n width: 100px;\r\n height: 100px;\r\n border-radius: 50%;\r\n background: rgba(255, 255, 255, 0.3);\r\n transform: translate(-50%, -50%) scale(0);\r\n animation: ripple 0.5s ease-out forwards;\r\n pointer-events: none;\r\n}\r\n\r\n@keyframes ripple {\r\n to {\r\n transform: translate(-50%, -50%) scale(2);\r\n opacity: 0;\r\n }\r\n}\r\n\r\n/* Responsive Controls */\r\n@media (max-width: 768px) {\r\n .top-controls {\r\n padding: 12px 16px;\r\n }\r\n \r\n .video-title {\r\n font-size: 14px;\r\n max-width: 200px;\r\n }\r\n \r\n .bottom-controls {\r\n padding: 0 12px 12px;\r\n }\r\n \r\n .control-btn {\r\n width: 36px;\r\n height: 36px;\r\n }\r\n \r\n .control-btn .material-icons {\r\n font-size: 22px;\r\n }\r\n \r\n .play-btn {\r\n width: 44px;\r\n height: 44px;\r\n }\r\n \r\n .play-btn .material-icons {\r\n font-size: 28px;\r\n }\r\n \r\n .time-display {\r\n font-size: 12px;\r\n }\r\n \r\n .speed-text {\r\n font-size: 12px;\r\n }\r\n \r\n #preview-canvas {\r\n width: 120px;\r\n height: 68px;\r\n }\r\n}\r\n\r\n@media (max-width: 480px) {\r\n .controls-left,\r\n .controls-right {\r\n gap: 0;\r\n }\r\n \r\n .control-btn {\r\n width: 32px;\r\n height: 32px;\r\n }\r\n \r\n .control-btn .material-icons {\r\n font-size: 20px;\r\n }\r\n \r\n .video-title {\r\n max-width: 140px;\r\n font-size: 13px;\r\n }\r\n \r\n /* Hide some buttons on very small screens */\r\n #cast-btn,\r\n #quality-btn {\r\n display: none;\r\n }\r\n}\r\n\r\n/* Hover/Focus States for Accessibility */\r\n.control-btn:focus-visible {\r\n outline: 2px solid var(--plex-primary);\r\n outline-offset: 2px;\r\n}\r\n\r\n.progress-container:focus-visible {\r\n outline: 2px solid var(--plex-primary);\r\n outline-offset: 2px;\r\n}\r\n\r\n/* Disabled State */\r\n.control-btn:disabled {\r\n opacity: 0.4;\r\n cursor: not-allowed;\r\n}\r\n\r\n.control-btn:disabled:hover {\r\n background: transparent;\r\n}\r\n","/* =====================================================\r\n PLEX Video Player - Playlist Styles\r\n ===================================================== */\r\n\r\n/* Playlist Panel */\r\n.playlist-panel {\r\n position: absolute;\r\n top: 0;\r\n right: 0;\r\n width: 360px;\r\n height: 100%;\r\n background: var(--plex-bg-dark);\r\n border-left: 1px solid var(--plex-border);\r\n z-index: var(--plex-z-panel);\r\n display: flex;\r\n flex-direction: column;\r\n transform: translateX(100%);\r\n transition: transform var(--plex-transition-normal);\r\n}\r\n\r\n.playlist-panel.visible {\r\n transform: translateX(0);\r\n}\r\n\r\n/* Playlist Header */\r\n.playlist-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 16px 20px;\r\n background: rgba(255, 255, 255, 0.03);\r\n border-bottom: 1px solid var(--plex-border);\r\n flex-shrink: 0;\r\n}\r\n\r\n.playlist-title {\r\n font-size: 16px;\r\n font-weight: 600;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.playlist-header-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n}\r\n\r\n/* Playlist Content */\r\n.playlist-content {\r\n flex: 1;\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n padding: 12px;\r\n}\r\n\r\n.playlist-content::-webkit-scrollbar {\r\n width: 6px;\r\n}\r\n\r\n.playlist-content::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n\r\n.playlist-content::-webkit-scrollbar-thumb {\r\n background: rgba(255, 255, 255, 0.2);\r\n border-radius: 3px;\r\n}\r\n\r\n.playlist-content::-webkit-scrollbar-thumb:hover {\r\n background: rgba(255, 255, 255, 0.3);\r\n}\r\n\r\n/* Playlist Empty State */\r\n.playlist-empty {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n height: 100%;\r\n padding: 40px;\r\n text-align: center;\r\n}\r\n\r\n.playlist-empty .material-icons {\r\n font-size: 64px;\r\n color: var(--plex-text-secondary);\r\n margin-bottom: 16px;\r\n opacity: 0.5;\r\n}\r\n\r\n.playlist-empty-title {\r\n font-size: 18px;\r\n font-weight: 600;\r\n color: var(--plex-text-primary);\r\n margin-bottom: 8px;\r\n}\r\n\r\n.playlist-empty-text {\r\n font-size: 14px;\r\n color: var(--plex-text-secondary);\r\n line-height: 1.5;\r\n}\r\n\r\n/* Playlist Item */\r\n.playlist-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 10px 12px;\r\n background: rgba(255, 255, 255, 0.02);\r\n border-radius: var(--plex-radius-md);\r\n cursor: pointer;\r\n transition: all var(--plex-transition-fast);\r\n margin-bottom: 8px;\r\n position: relative;\r\n}\r\n\r\n.playlist-item:hover {\r\n background: rgba(255, 255, 255, 0.08);\r\n}\r\n\r\n.playlist-item.active {\r\n background: rgba(229, 160, 13, 0.15);\r\n border: 1px solid rgba(229, 160, 13, 0.3);\r\n}\r\n\r\n.playlist-item.playing {\r\n background: rgba(229, 160, 13, 0.2);\r\n}\r\n\r\n.playlist-item.dragging {\r\n opacity: 0.5;\r\n transform: scale(0.98);\r\n}\r\n\r\n/* Playlist Item Thumbnail */\r\n.playlist-item-thumbnail {\r\n position: relative;\r\n width: 100px;\r\n height: 56px;\r\n background: var(--plex-bg-darker);\r\n border-radius: var(--plex-radius-sm);\r\n overflow: hidden;\r\n flex-shrink: 0;\r\n}\r\n\r\n.playlist-item-thumbnail img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n}\r\n\r\n.playlist-item-thumbnail .placeholder-icon {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n font-size: 32px;\r\n color: var(--plex-text-secondary);\r\n opacity: 0.5;\r\n}\r\n\r\n.playlist-item-duration {\r\n position: absolute;\r\n bottom: 4px;\r\n right: 4px;\r\n padding: 2px 6px;\r\n background: rgba(0, 0, 0, 0.8);\r\n border-radius: 3px;\r\n font-size: 11px;\r\n font-weight: 600;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n/* Playing Indicator */\r\n.playlist-item-playing-indicator {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n display: none;\r\n align-items: flex-end;\r\n justify-content: center;\r\n gap: 2px;\r\n width: 24px;\r\n height: 20px;\r\n}\r\n\r\n.playlist-item.playing .playlist-item-playing-indicator {\r\n display: flex;\r\n}\r\n\r\n.playlist-item-playing-indicator span {\r\n width: 4px;\r\n background: var(--plex-primary);\r\n border-radius: 1px;\r\n animation: equalizer 0.5s ease-in-out infinite alternate;\r\n}\r\n\r\n.playlist-item-playing-indicator span:nth-child(1) {\r\n height: 60%;\r\n animation-delay: 0s;\r\n}\r\n\r\n.playlist-item-playing-indicator span:nth-child(2) {\r\n height: 100%;\r\n animation-delay: 0.15s;\r\n}\r\n\r\n.playlist-item-playing-indicator span:nth-child(3) {\r\n height: 40%;\r\n animation-delay: 0.3s;\r\n}\r\n\r\n@keyframes equalizer {\r\n from {\r\n transform: scaleY(0.5);\r\n }\r\n to {\r\n transform: scaleY(1);\r\n }\r\n}\r\n\r\n/* Playlist Item Info */\r\n.playlist-item-info {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n}\r\n\r\n.playlist-item-title {\r\n font-size: 14px;\r\n font-weight: 500;\r\n color: var(--plex-text-primary);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n}\r\n\r\n.playlist-item-meta {\r\n font-size: 12px;\r\n color: var(--plex-text-secondary);\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n}\r\n\r\n/* Playlist Item Actions */\r\n.playlist-item-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n opacity: 0;\r\n transition: opacity var(--plex-transition-fast);\r\n}\r\n\r\n.playlist-item:hover .playlist-item-actions {\r\n opacity: 1;\r\n}\r\n\r\n.playlist-item-action {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 28px;\r\n height: 28px;\r\n background: transparent;\r\n border: none;\r\n border-radius: var(--plex-radius-sm);\r\n cursor: pointer;\r\n color: var(--plex-text-secondary);\r\n transition: all var(--plex-transition-fast);\r\n}\r\n\r\n.playlist-item-action:hover {\r\n background: rgba(255, 255, 255, 0.1);\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.playlist-item-action .material-icons {\r\n font-size: 18px;\r\n}\r\n\r\n/* Drag Handle */\r\n.playlist-item-drag-handle {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 20px;\r\n cursor: grab;\r\n color: var(--plex-text-secondary);\r\n opacity: 0;\r\n transition: opacity var(--plex-transition-fast);\r\n}\r\n\r\n.playlist-item:hover .playlist-item-drag-handle {\r\n opacity: 1;\r\n}\r\n\r\n.playlist-item-drag-handle:active {\r\n cursor: grabbing;\r\n}\r\n\r\n.playlist-item-drag-handle .material-icons {\r\n font-size: 18px;\r\n}\r\n\r\n/* Playlist Footer */\r\n.playlist-footer {\r\n padding: 16px;\r\n border-top: 1px solid var(--plex-border);\r\n flex-shrink: 0;\r\n}\r\n\r\n.playlist-add-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 8px;\r\n width: 100%;\r\n padding: 12px;\r\n background: rgba(255, 255, 255, 0.05);\r\n border: 2px dashed var(--plex-border);\r\n border-radius: var(--plex-radius-md);\r\n color: var(--plex-text-secondary);\r\n font-size: 14px;\r\n font-weight: 500;\r\n cursor: pointer;\r\n transition: all var(--plex-transition-fast);\r\n}\r\n\r\n.playlist-add-btn:hover {\r\n background: rgba(255, 255, 255, 0.08);\r\n border-color: var(--plex-primary);\r\n color: var(--plex-primary);\r\n}\r\n\r\n.playlist-add-btn .material-icons {\r\n font-size: 20px;\r\n}\r\n\r\n/* Playlist Stats */\r\n.playlist-stats {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 12px 16px;\r\n background: rgba(0, 0, 0, 0.3);\r\n border-top: 1px solid var(--plex-border);\r\n font-size: 12px;\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n/* Queue Next Indicator */\r\n.playlist-item-queue-next {\r\n position: absolute;\r\n top: 4px;\r\n left: 4px;\r\n padding: 2px 6px;\r\n background: var(--plex-primary);\r\n border-radius: 3px;\r\n font-size: 9px;\r\n font-weight: 700;\r\n color: #000;\r\n text-transform: uppercase;\r\n}\r\n\r\n/* Responsive Playlist */\r\n@media (max-width: 768px) {\r\n .playlist-panel {\r\n width: 100%;\r\n max-width: 100%;\r\n }\r\n \r\n .playlist-item-thumbnail {\r\n width: 80px;\r\n height: 45px;\r\n }\r\n \r\n .playlist-item-title {\r\n font-size: 13px;\r\n }\r\n \r\n .playlist-item-actions {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n@media (max-width: 480px) {\r\n .playlist-header {\r\n padding: 12px 16px;\r\n }\r\n \r\n .playlist-content {\r\n padding: 8px;\r\n }\r\n \r\n .playlist-item {\r\n padding: 8px;\r\n gap: 10px;\r\n }\r\n \r\n .playlist-item-thumbnail {\r\n width: 70px;\r\n height: 40px;\r\n }\r\n \r\n .playlist-item-drag-handle {\r\n display: none;\r\n }\r\n}\r\n\r\n/* Drag and Drop States */\r\n.playlist-content.drag-over {\r\n background: rgba(229, 160, 13, 0.05);\r\n}\r\n\r\n.playlist-item.drop-target-above::before {\r\n content: '';\r\n position: absolute;\r\n top: -4px;\r\n left: 0;\r\n right: 0;\r\n height: 2px;\r\n background: var(--plex-primary);\r\n border-radius: 1px;\r\n}\r\n\r\n.playlist-item.drop-target-below::after {\r\n content: '';\r\n position: absolute;\r\n bottom: -4px;\r\n left: 0;\r\n right: 0;\r\n height: 2px;\r\n background: var(--plex-primary);\r\n border-radius: 1px;\r\n}\r\n","/* =====================================================\r\n PLEX Video Player - Settings Styles\r\n ===================================================== */\r\n\r\n/* Settings Panel */\r\n.settings-panel {\r\n position: absolute;\r\n bottom: 80px;\r\n right: 20px;\r\n width: 300px;\r\n max-height: 400px;\r\n background: var(--plex-bg-dark);\r\n border: 1px solid var(--plex-border);\r\n border-radius: var(--plex-radius-lg);\r\n box-shadow: var(--plex-shadow);\r\n z-index: var(--plex-z-panel);\r\n overflow: hidden;\r\n transform-origin: bottom right;\r\n animation: settingsOpen 0.2s ease;\r\n}\r\n\r\n@keyframes settingsOpen {\r\n from {\r\n opacity: 0;\r\n transform: scale(0.95);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n}\r\n\r\n/* Settings Header */\r\n.settings-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 12px 16px;\r\n background: rgba(255, 255, 255, 0.03);\r\n border-bottom: 1px solid var(--plex-border);\r\n}\r\n\r\n.settings-title {\r\n font-size: 15px;\r\n font-weight: 600;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n/* Settings Content */\r\n.settings-content {\r\n max-height: 340px;\r\n overflow-y: auto;\r\n}\r\n\r\n.settings-content::-webkit-scrollbar {\r\n width: 6px;\r\n}\r\n\r\n.settings-content::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n\r\n.settings-content::-webkit-scrollbar-thumb {\r\n background: rgba(255, 255, 255, 0.2);\r\n border-radius: 3px;\r\n}\r\n\r\n/* Settings Menu */\r\n.settings-menu {\r\n padding: 8px 0;\r\n}\r\n\r\n/* Settings Item */\r\n.settings-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 12px 16px;\r\n cursor: pointer;\r\n transition: background var(--plex-transition-fast);\r\n}\r\n\r\n.settings-item:hover {\r\n background: rgba(255, 255, 255, 0.05);\r\n}\r\n\r\n.settings-item .material-icons:first-child {\r\n font-size: 22px;\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n.settings-item-label {\r\n flex: 1;\r\n font-size: 14px;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.settings-item-value {\r\n font-size: 13px;\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n.settings-item .material-icons:last-child {\r\n font-size: 20px;\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n/* Settings Submenu */\r\n.settings-submenu {\r\n padding: 8px 0;\r\n}\r\n\r\n/* Settings Option */\r\n.settings-option {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 12px 16px;\r\n cursor: pointer;\r\n transition: background var(--plex-transition-fast);\r\n font-size: 14px;\r\n color: var(--plex-text-primary);\r\n}\r\n\r\n.settings-option:hover {\r\n background: rgba(255, 255, 255, 0.05);\r\n}\r\n\r\n.settings-option.active {\r\n color: var(--plex-primary);\r\n}\r\n\r\n.settings-option.active::after {\r\n content: 'check';\r\n font-family: 'Material Icons';\r\n font-size: 20px;\r\n color: var(--plex-primary);\r\n}\r\n\r\n/* Toggle Switch */\r\n.toggle-switch {\r\n position: relative;\r\n width: 44px;\r\n height: 24px;\r\n background: rgba(255, 255, 255, 0.2);\r\n border-radius: 12px;\r\n cursor: pointer;\r\n transition: background var(--plex-transition-fast);\r\n}\r\n\r\n.toggle-switch.active {\r\n background: var(--plex-primary);\r\n}\r\n\r\n.toggle-slider {\r\n position: absolute;\r\n top: 2px;\r\n left: 2px;\r\n width: 20px;\r\n height: 20px;\r\n background: #fff;\r\n border-radius: 50%;\r\n transition: transform var(--plex-transition-fast);\r\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\r\n}\r\n\r\n.toggle-switch.active .toggle-slider {\r\n transform: translateX(20px);\r\n}\r\n\r\n/* Subtitles Settings Panel */\r\n.subtitles-settings-panel {\r\n position: absolute;\r\n bottom: 80px;\r\n right: 20px;\r\n width: 320px;\r\n background: var(--plex-bg-dark);\r\n border: 1px solid var(--plex-border);\r\n border-radius: var(--plex-radius-lg);\r\n box-shadow: var(--plex-shadow);\r\n z-index: var(--plex-z-panel);\r\n overflow: hidden;\r\n}\r\n\r\n.subtitles-settings-content {\r\n padding: 16px;\r\n}\r\n\r\n/* Subtitle Setting Item */\r\n.subtitle-setting-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n margin-bottom: 16px;\r\n}\r\n\r\n.subtitle-setting-item label {\r\n flex: 0 0 100px;\r\n font-size: 13px;\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n.subtitle-setting-item input[type=\"range\"] {\r\n flex: 1;\r\n -webkit-appearance: none;\r\n appearance: none;\r\n height: 4px;\r\n background: rgba(255, 255, 255, 0.2);\r\n border-radius: 2px;\r\n outline: none;\r\n}\r\n\r\n.subtitle-setting-item input[type=\"range\"]::-webkit-slider-thumb {\r\n -webkit-appearance: none;\r\n appearance: none;\r\n width: 16px;\r\n height: 16px;\r\n background: var(--plex-primary);\r\n border-radius: 50%;\r\n cursor: pointer;\r\n}\r\n\r\n.subtitle-setting-item input[type=\"color\"] {\r\n -webkit-appearance: none;\r\n appearance: none;\r\n width: 40px;\r\n height: 30px;\r\n border: none;\r\n border-radius: var(--plex-radius-sm);\r\n cursor: pointer;\r\n background: transparent;\r\n}\r\n\r\n.subtitle-setting-item input[type=\"color\"]::-webkit-color-swatch-wrapper {\r\n padding: 0;\r\n}\r\n\r\n.subtitle-setting-item input[type=\"color\"]::-webkit-color-swatch {\r\n border: 2px solid var(--plex-border);\r\n border-radius: var(--plex-radius-sm);\r\n}\r\n\r\n.subtitle-setting-item span:last-child {\r\n flex: 0 0 50px;\r\n text-align: right;\r\n font-size: 13px;\r\n color: var(--plex-text-primary);\r\n font-weight: 500;\r\n}\r\n\r\n/* Subtitle Load Button */\r\n.subtitle-load-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 8px;\r\n width: 100%;\r\n padding: 12px;\r\n margin-top: 8px;\r\n background: rgba(255, 255, 255, 0.05);\r\n border: 1px solid var(--plex-border);\r\n border-radius: var(--plex-radius-md);\r\n color: var(--plex-text-primary);\r\n font-size: 14px;\r\n cursor: pointer;\r\n transition: all var(--plex-transition-fast);\r\n}\r\n\r\n.subtitle-load-btn:hover {\r\n background: rgba(255, 255, 255, 0.1);\r\n border-color: var(--plex-primary);\r\n}\r\n\r\n.subtitle-load-btn .material-icons {\r\n font-size: 20px;\r\n}\r\n\r\n/* Speed Panel (Alternative) */\r\n.speed-panel {\r\n position: absolute;\r\n bottom: 80px;\r\n right: 60px;\r\n width: 200px;\r\n background: var(--plex-bg-dark);\r\n border: 1px solid var(--plex-border);\r\n border-radius: var(--plex-radius-lg);\r\n box-shadow: var(--plex-shadow);\r\n z-index: var(--plex-z-panel);\r\n overflow: hidden;\r\n padding: 8px 0;\r\n}\r\n\r\n/* Quality Badge */\r\n.quality-badge {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 2px 6px;\r\n background: var(--plex-primary);\r\n border-radius: 3px;\r\n font-size: 10px;\r\n font-weight: 700;\r\n color: #000;\r\n text-transform: uppercase;\r\n margin-left: 8px;\r\n}\r\n\r\n/* Section Divider */\r\n.settings-divider {\r\n height: 1px;\r\n background: var(--plex-border);\r\n margin: 8px 16px;\r\n}\r\n\r\n/* Settings Group Label */\r\n.settings-group-label {\r\n padding: 8px 16px 4px;\r\n font-size: 11px;\r\n font-weight: 600;\r\n color: var(--plex-text-secondary);\r\n text-transform: uppercase;\r\n letter-spacing: 0.5px;\r\n}\r\n\r\n/* Responsive Settings */\r\n@media (max-width: 768px) {\r\n .settings-panel {\r\n position: fixed;\r\n top: auto;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n width: 100%;\r\n max-height: 60vh;\r\n border-radius: var(--plex-radius-lg) var(--plex-radius-lg) 0 0;\r\n transform-origin: bottom center;\r\n }\r\n \r\n .subtitles-settings-panel {\r\n position: fixed;\r\n top: auto;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n width: 100%;\r\n max-height: 70vh;\r\n border-radius: var(--plex-radius-lg) var(--plex-radius-lg) 0 0;\r\n }\r\n \r\n .settings-item {\r\n padding: 14px 20px;\r\n }\r\n \r\n .settings-option {\r\n padding: 14px 20px;\r\n }\r\n}\r\n\r\n@media (max-width: 480px) {\r\n .settings-content {\r\n max-height: 50vh;\r\n }\r\n \r\n .subtitle-setting-item {\r\n flex-wrap: wrap;\r\n }\r\n \r\n .subtitle-setting-item label {\r\n flex: 0 0 100%;\r\n margin-bottom: 8px;\r\n }\r\n \r\n .subtitle-setting-item input[type=\"range\"] {\r\n flex: 1;\r\n }\r\n}\r\n\r\n/* Animation for panel open/close */\r\n.settings-panel.closing {\r\n animation: settingsClose 0.15s ease forwards;\r\n}\r\n\r\n@keyframes settingsClose {\r\n from {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n to {\r\n opacity: 0;\r\n transform: scale(0.95);\r\n }\r\n}\r\n\r\n/* Keyboard Shortcut Hints */\r\n.shortcut-hint {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n min-width: 24px;\r\n height: 24px;\r\n padding: 0 6px;\r\n background: rgba(255, 255, 255, 0.1);\r\n border: 1px solid var(--plex-border);\r\n border-radius: 4px;\r\n font-size: 11px;\r\n font-weight: 600;\r\n color: var(--plex-text-secondary);\r\n margin-left: auto;\r\n}\r\n\r\n/* Audio Track Indicator */\r\n.audio-track-indicator {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n font-size: 12px;\r\n color: var(--plex-text-secondary);\r\n}\r\n\r\n.audio-track-indicator .material-icons {\r\n font-size: 16px;\r\n}\r\n"]}
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @frameset/plex-player v1.0.3
2
+ * @frameset/plex-player v1.0.4
3
3
  * Professional video player with VAST ads, Chromecast, PiP, subtitles, playlists and more. Built by FRAMESET Studio.
4
4
  * (c) 2026 FRAMESET Studio
5
5
  * Released under the MIT License
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @frameset/plex-player v1.0.3
2
+ * @frameset/plex-player v1.0.4
3
3
  * Professional video player with VAST ads, Chromecast, PiP, subtitles, playlists and more. Built by FRAMESET Studio.
4
4
  * (c) 2026 FRAMESET Studio
5
5
  * Released under the MIT License
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @frameset/plex-player v1.0.3
2
+ * @frameset/plex-player v1.0.4
3
3
  * Professional video player with VAST ads, Chromecast, PiP, subtitles, playlists and more. Built by FRAMESET Studio.
4
4
  * (c) 2026 FRAMESET Studio
5
5
  * Released under the MIT License
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @frameset/plex-player v1.0.3
2
+ * @frameset/plex-player v1.0.4
3
3
  * Professional video player with VAST ads, Chromecast, PiP, subtitles, playlists and more. Built by FRAMESET Studio.
4
4
  * (c) 2026 FRAMESET Studio
5
5
  * Released under the MIT License
@@ -192,7 +192,7 @@ const PlexPlayerReact = /*#__PURE__*/forwardRef(function PlexPlayerReact(props,
192
192
  className: `plex-player-container ${className}`,
193
193
  style: {
194
194
  width: '100%',
195
- height: '100%',
195
+ aspectRatio: '16 / 9',
196
196
  position: 'relative',
197
197
  ...style
198
198
  },
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../../src/react/index.jsx"],"sourcesContent":["/**\r\n * @frameset/plex-player - React Component\r\n * Professional Video Player by FRAMESET Studio\r\n * https://frameset.dev\r\n */\r\n\r\nimport React, {\r\n useEffect,\r\n useRef,\r\n useImperativeHandle,\r\n forwardRef,\r\n useState,\r\n useCallback,\r\n createContext,\r\n useContext,\r\n} from 'react';\r\n\r\n// Import core player\r\nimport PlexPlayer from '../core/index.js';\r\n\r\n// Context for nested components\r\nconst PlexPlayerContext = createContext(null);\r\n\r\n/**\r\n * Hook to access player instance from child components\r\n */\r\nexport const usePlexPlayer = () => {\r\n const player = useContext(PlexPlayerContext);\r\n return player;\r\n};\r\n\r\n/**\r\n * PlexPlayer React Component\r\n */\r\nexport const PlexPlayerReact = forwardRef(function PlexPlayerReact(props, ref) {\r\n const {\r\n src,\r\n playlist,\r\n className = '',\r\n style = {},\r\n autoplay = false,\r\n muted = false,\r\n loop = false,\r\n volume = 1,\r\n poster,\r\n preload = 'metadata',\r\n keyboard = true,\r\n touch = true,\r\n pip = true,\r\n cast = true,\r\n fullscreen = true,\r\n controlsHideDelay = 3000,\r\n theme,\r\n subtitles,\r\n ads,\r\n i18n,\r\n // Event callbacks\r\n onPlay,\r\n onPause,\r\n onEnded,\r\n onTimeUpdate,\r\n onProgress,\r\n onVolumeChange,\r\n onFullscreenChange,\r\n onError,\r\n onReady,\r\n // Children for custom overlays\r\n children,\r\n ...restProps\r\n } = props;\r\n\r\n const containerRef = useRef(null);\r\n const playerRef = useRef(null);\r\n const [isReady, setIsReady] = useState(false);\r\n\r\n // Initialize player\r\n useEffect(() => {\r\n if (!containerRef.current) return;\r\n\r\n // Create player instance\r\n const player = new PlexPlayer({\r\n container: containerRef.current,\r\n autoplay,\r\n muted,\r\n loop,\r\n volume,\r\n poster,\r\n preload,\r\n keyboard,\r\n touch,\r\n pip,\r\n cast,\r\n fullscreen,\r\n controlsHideDelay,\r\n theme,\r\n subtitles,\r\n ads,\r\n i18n,\r\n });\r\n\r\n playerRef.current = player;\r\n\r\n // Bind events\r\n if (onPlay) player.on('play', onPlay);\r\n if (onPause) player.on('pause', onPause);\r\n if (onEnded) player.on('ended', onEnded);\r\n if (onTimeUpdate) {\r\n player.on('timeupdate', (data) => onTimeUpdate(data.currentTime));\r\n }\r\n if (onProgress) {\r\n player.on('progress', (data) => onProgress(data.buffered));\r\n }\r\n if (onVolumeChange) {\r\n player.on('volumechange', (data) => onVolumeChange(data.volume, data.muted));\r\n }\r\n if (onFullscreenChange) {\r\n player.on('fullscreenchange', (data) => onFullscreenChange(data.isFullscreen));\r\n }\r\n if (onError) {\r\n player.on('error', onError);\r\n }\r\n\r\n setIsReady(true);\r\n\r\n if (onReady) {\r\n onReady(player);\r\n }\r\n\r\n // Cleanup\r\n return () => {\r\n player.destroy();\r\n playerRef.current = null;\r\n };\r\n }, []);\r\n\r\n // Load source when src changes\r\n useEffect(() => {\r\n if (!playerRef.current || !isReady) return;\r\n\r\n if (src) {\r\n playerRef.current.load(src);\r\n }\r\n }, [src, isReady]);\r\n\r\n // Load playlist when playlist changes\r\n useEffect(() => {\r\n if (!playerRef.current || !isReady || !playlist) return;\r\n\r\n playerRef.current.loadPlaylist(playlist);\r\n }, [playlist, isReady]);\r\n\r\n // Update volume\r\n useEffect(() => {\r\n if (playerRef.current && isReady) {\r\n playerRef.current.setVolume(volume);\r\n }\r\n }, [volume, isReady]);\r\n\r\n // Update muted\r\n useEffect(() => {\r\n if (playerRef.current && isReady) {\r\n if (muted) {\r\n playerRef.current.mute();\r\n } else {\r\n playerRef.current.unmute();\r\n }\r\n }\r\n }, [muted, isReady]);\r\n\r\n // Expose player methods via ref\r\n useImperativeHandle(ref, () => ({\r\n play: () => playerRef.current?.play(),\r\n pause: () => playerRef.current?.pause(),\r\n togglePlay: () => playerRef.current?.togglePlay(),\r\n seek: (time) => playerRef.current?.seek(time),\r\n seekPercent: (percent) => playerRef.current?.seekPercent(percent),\r\n setVolume: (vol) => playerRef.current?.setVolume(vol),\r\n getVolume: () => playerRef.current?.getVolume(),\r\n mute: () => playerRef.current?.mute(),\r\n unmute: () => playerRef.current?.unmute(),\r\n toggleMute: () => playerRef.current?.toggleMute(),\r\n isMuted: () => playerRef.current?.isMuted(),\r\n setPlaybackRate: (rate) => playerRef.current?.setPlaybackRate(rate),\r\n enterFullscreen: () => playerRef.current?.enterFullscreen(),\r\n exitFullscreen: () => playerRef.current?.exitFullscreen(),\r\n toggleFullscreen: () => playerRef.current?.toggleFullscreen(),\r\n enterPiP: () => playerRef.current?.enterPiP(),\r\n exitPiP: () => playerRef.current?.exitPiP(),\r\n togglePiP: () => playerRef.current?.togglePiP(),\r\n cast: () => playerRef.current?.cast(),\r\n getState: () => playerRef.current?.getState(),\r\n getPlayer: () => playerRef.current,\r\n next: () => playerRef.current?.next(),\r\n previous: () => playerRef.current?.previous(),\r\n playAt: (index) => playerRef.current?.playAt(index),\r\n }));\r\n\r\n return (\r\n <PlexPlayerContext.Provider value={playerRef.current}>\r\n <div\r\n ref={containerRef}\r\n className={`plex-player-container ${className}`}\r\n style={{\r\n width: '100%',\r\n height: '100%',\r\n position: 'relative',\r\n ...style,\r\n }}\r\n {...restProps}\r\n >\r\n {children}\r\n </div>\r\n </PlexPlayerContext.Provider>\r\n );\r\n});\r\n\r\n// Additional hooks for convenience\r\nexport const usePlexPlayerState = () => {\r\n const player = usePlexPlayer();\r\n const [state, setState] = useState(null);\r\n\r\n useEffect(() => {\r\n if (!player) return;\r\n\r\n const updateState = () => {\r\n setState(player.getState());\r\n };\r\n\r\n // Update on every timeupdate\r\n player.on('timeupdate', updateState);\r\n player.on('play', updateState);\r\n player.on('pause', updateState);\r\n player.on('volumechange', updateState);\r\n player.on('fullscreenchange', updateState);\r\n\r\n // Initial state\r\n updateState();\r\n\r\n return () => {\r\n player.off('timeupdate', updateState);\r\n player.off('play', updateState);\r\n player.off('pause', updateState);\r\n player.off('volumechange', updateState);\r\n player.off('fullscreenchange', updateState);\r\n };\r\n }, [player]);\r\n\r\n return state;\r\n};\r\n\r\nexport const usePlexPlayerTime = () => {\r\n const player = usePlexPlayer();\r\n const [time, setTime] = useState({ current: 0, duration: 0 });\r\n\r\n useEffect(() => {\r\n if (!player) return;\r\n\r\n const updateTime = (data) => {\r\n setTime({\r\n current: data.currentTime,\r\n duration: data.duration,\r\n });\r\n };\r\n\r\n player.on('timeupdate', updateTime);\r\n\r\n return () => {\r\n player.off('timeupdate', updateTime);\r\n };\r\n }, [player]);\r\n\r\n return time;\r\n};\r\n\r\n// Named exports\r\nexport { PlexPlayer };\r\nexport default PlexPlayerReact;\r\n"],"names":["PlexPlayerContext","createContext","usePlexPlayer","player","useContext","PlexPlayerReact","forwardRef","props","ref","src","playlist","className","style","autoplay","muted","loop","volume","poster","preload","keyboard","touch","pip","cast","fullscreen","controlsHideDelay","theme","subtitles","ads","i18n","onPlay","onPause","onEnded","onTimeUpdate","onProgress","onVolumeChange","onFullscreenChange","onError","onReady","children","restProps","containerRef","useRef","playerRef","isReady","setIsReady","useState","useEffect","current","PlexPlayer","container","on","data","currentTime","buffered","isFullscreen","destroy","load","loadPlaylist","setVolume","mute","unmute","useImperativeHandle","play","pause","togglePlay","seek","time","seekPercent","percent","vol","getVolume","toggleMute","isMuted","setPlaybackRate","rate","enterFullscreen","exitFullscreen","toggleFullscreen","enterPiP","exitPiP","togglePiP","getState","getPlayer","next","previous","playAt","index","_jsx","Provider","value","width","height","position","usePlexPlayerState","state","setState","updateState","off","usePlexPlayerTime","setTime","duration","updateTime"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../../src/react/index.jsx"],"sourcesContent":["/**\r\n * @frameset/plex-player - React Component\r\n * Professional Video Player by FRAMESET Studio\r\n * https://frameset.dev\r\n */\r\n\r\nimport React, {\r\n useEffect,\r\n useRef,\r\n useImperativeHandle,\r\n forwardRef,\r\n useState,\r\n useCallback,\r\n createContext,\r\n useContext,\r\n} from 'react';\r\n\r\n// Import core player\r\nimport PlexPlayer from '../core/index.js';\r\n\r\n// Context for nested components\r\nconst PlexPlayerContext = createContext(null);\r\n\r\n/**\r\n * Hook to access player instance from child components\r\n */\r\nexport const usePlexPlayer = () => {\r\n const player = useContext(PlexPlayerContext);\r\n return player;\r\n};\r\n\r\n/**\r\n * PlexPlayer React Component\r\n */\r\nexport const PlexPlayerReact = forwardRef(function PlexPlayerReact(props, ref) {\r\n const {\r\n src,\r\n playlist,\r\n className = '',\r\n style = {},\r\n autoplay = false,\r\n muted = false,\r\n loop = false,\r\n volume = 1,\r\n poster,\r\n preload = 'metadata',\r\n keyboard = true,\r\n touch = true,\r\n pip = true,\r\n cast = true,\r\n fullscreen = true,\r\n controlsHideDelay = 3000,\r\n theme,\r\n subtitles,\r\n ads,\r\n i18n,\r\n // Event callbacks\r\n onPlay,\r\n onPause,\r\n onEnded,\r\n onTimeUpdate,\r\n onProgress,\r\n onVolumeChange,\r\n onFullscreenChange,\r\n onError,\r\n onReady,\r\n // Children for custom overlays\r\n children,\r\n ...restProps\r\n } = props;\r\n\r\n const containerRef = useRef(null);\r\n const playerRef = useRef(null);\r\n const [isReady, setIsReady] = useState(false);\r\n\r\n // Initialize player\r\n useEffect(() => {\r\n if (!containerRef.current) return;\r\n\r\n // Create player instance\r\n const player = new PlexPlayer({\r\n container: containerRef.current,\r\n autoplay,\r\n muted,\r\n loop,\r\n volume,\r\n poster,\r\n preload,\r\n keyboard,\r\n touch,\r\n pip,\r\n cast,\r\n fullscreen,\r\n controlsHideDelay,\r\n theme,\r\n subtitles,\r\n ads,\r\n i18n,\r\n });\r\n\r\n playerRef.current = player;\r\n\r\n // Bind events\r\n if (onPlay) player.on('play', onPlay);\r\n if (onPause) player.on('pause', onPause);\r\n if (onEnded) player.on('ended', onEnded);\r\n if (onTimeUpdate) {\r\n player.on('timeupdate', (data) => onTimeUpdate(data.currentTime));\r\n }\r\n if (onProgress) {\r\n player.on('progress', (data) => onProgress(data.buffered));\r\n }\r\n if (onVolumeChange) {\r\n player.on('volumechange', (data) => onVolumeChange(data.volume, data.muted));\r\n }\r\n if (onFullscreenChange) {\r\n player.on('fullscreenchange', (data) => onFullscreenChange(data.isFullscreen));\r\n }\r\n if (onError) {\r\n player.on('error', onError);\r\n }\r\n\r\n setIsReady(true);\r\n\r\n if (onReady) {\r\n onReady(player);\r\n }\r\n\r\n // Cleanup\r\n return () => {\r\n player.destroy();\r\n playerRef.current = null;\r\n };\r\n }, []);\r\n\r\n // Load source when src changes\r\n useEffect(() => {\r\n if (!playerRef.current || !isReady) return;\r\n\r\n if (src) {\r\n playerRef.current.load(src);\r\n }\r\n }, [src, isReady]);\r\n\r\n // Load playlist when playlist changes\r\n useEffect(() => {\r\n if (!playerRef.current || !isReady || !playlist) return;\r\n\r\n playerRef.current.loadPlaylist(playlist);\r\n }, [playlist, isReady]);\r\n\r\n // Update volume\r\n useEffect(() => {\r\n if (playerRef.current && isReady) {\r\n playerRef.current.setVolume(volume);\r\n }\r\n }, [volume, isReady]);\r\n\r\n // Update muted\r\n useEffect(() => {\r\n if (playerRef.current && isReady) {\r\n if (muted) {\r\n playerRef.current.mute();\r\n } else {\r\n playerRef.current.unmute();\r\n }\r\n }\r\n }, [muted, isReady]);\r\n\r\n // Expose player methods via ref\r\n useImperativeHandle(ref, () => ({\r\n play: () => playerRef.current?.play(),\r\n pause: () => playerRef.current?.pause(),\r\n togglePlay: () => playerRef.current?.togglePlay(),\r\n seek: (time) => playerRef.current?.seek(time),\r\n seekPercent: (percent) => playerRef.current?.seekPercent(percent),\r\n setVolume: (vol) => playerRef.current?.setVolume(vol),\r\n getVolume: () => playerRef.current?.getVolume(),\r\n mute: () => playerRef.current?.mute(),\r\n unmute: () => playerRef.current?.unmute(),\r\n toggleMute: () => playerRef.current?.toggleMute(),\r\n isMuted: () => playerRef.current?.isMuted(),\r\n setPlaybackRate: (rate) => playerRef.current?.setPlaybackRate(rate),\r\n enterFullscreen: () => playerRef.current?.enterFullscreen(),\r\n exitFullscreen: () => playerRef.current?.exitFullscreen(),\r\n toggleFullscreen: () => playerRef.current?.toggleFullscreen(),\r\n enterPiP: () => playerRef.current?.enterPiP(),\r\n exitPiP: () => playerRef.current?.exitPiP(),\r\n togglePiP: () => playerRef.current?.togglePiP(),\r\n cast: () => playerRef.current?.cast(),\r\n getState: () => playerRef.current?.getState(),\r\n getPlayer: () => playerRef.current,\r\n next: () => playerRef.current?.next(),\r\n previous: () => playerRef.current?.previous(),\r\n playAt: (index) => playerRef.current?.playAt(index),\r\n }));\r\n\r\n return (\r\n <PlexPlayerContext.Provider value={playerRef.current}>\r\n <div\r\n ref={containerRef}\r\n className={`plex-player-container ${className}`}\r\n style={{\r\n width: '100%',\r\n aspectRatio: '16 / 9',\r\n position: 'relative',\r\n ...style,\r\n }}\r\n {...restProps}\r\n >\r\n {children}\r\n </div>\r\n </PlexPlayerContext.Provider>\r\n );\r\n});\r\n\r\n// Additional hooks for convenience\r\nexport const usePlexPlayerState = () => {\r\n const player = usePlexPlayer();\r\n const [state, setState] = useState(null);\r\n\r\n useEffect(() => {\r\n if (!player) return;\r\n\r\n const updateState = () => {\r\n setState(player.getState());\r\n };\r\n\r\n // Update on every timeupdate\r\n player.on('timeupdate', updateState);\r\n player.on('play', updateState);\r\n player.on('pause', updateState);\r\n player.on('volumechange', updateState);\r\n player.on('fullscreenchange', updateState);\r\n\r\n // Initial state\r\n updateState();\r\n\r\n return () => {\r\n player.off('timeupdate', updateState);\r\n player.off('play', updateState);\r\n player.off('pause', updateState);\r\n player.off('volumechange', updateState);\r\n player.off('fullscreenchange', updateState);\r\n };\r\n }, [player]);\r\n\r\n return state;\r\n};\r\n\r\nexport const usePlexPlayerTime = () => {\r\n const player = usePlexPlayer();\r\n const [time, setTime] = useState({ current: 0, duration: 0 });\r\n\r\n useEffect(() => {\r\n if (!player) return;\r\n\r\n const updateTime = (data) => {\r\n setTime({\r\n current: data.currentTime,\r\n duration: data.duration,\r\n });\r\n };\r\n\r\n player.on('timeupdate', updateTime);\r\n\r\n return () => {\r\n player.off('timeupdate', updateTime);\r\n };\r\n }, [player]);\r\n\r\n return time;\r\n};\r\n\r\n// Named exports\r\nexport { PlexPlayer };\r\nexport default PlexPlayerReact;\r\n"],"names":["PlexPlayerContext","createContext","usePlexPlayer","player","useContext","PlexPlayerReact","forwardRef","props","ref","src","playlist","className","style","autoplay","muted","loop","volume","poster","preload","keyboard","touch","pip","cast","fullscreen","controlsHideDelay","theme","subtitles","ads","i18n","onPlay","onPause","onEnded","onTimeUpdate","onProgress","onVolumeChange","onFullscreenChange","onError","onReady","children","restProps","containerRef","useRef","playerRef","isReady","setIsReady","useState","useEffect","current","PlexPlayer","container","on","data","currentTime","buffered","isFullscreen","destroy","load","loadPlaylist","setVolume","mute","unmute","useImperativeHandle","play","pause","togglePlay","seek","time","seekPercent","percent","vol","getVolume","toggleMute","isMuted","setPlaybackRate","rate","enterFullscreen","exitFullscreen","toggleFullscreen","enterPiP","exitPiP","togglePiP","getState","getPlayer","next","previous","playAt","index","_jsx","Provider","value","width","aspectRatio","position","usePlexPlayerState","state","setState","updateState","off","usePlexPlayerTime","setTime","duration","updateTime"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @frameset/plex-player v1.0.3
2
+ * @frameset/plex-player v1.0.4
3
3
  * Professional video player with VAST ads, Chromecast, PiP, subtitles, playlists and more. Built by FRAMESET Studio.
4
4
  * (c) 2026 FRAMESET Studio
5
5
  * Released under the MIT License
@@ -195,7 +195,7 @@ const PlexPlayerReact = /*#__PURE__*/react.forwardRef(function PlexPlayerReact(p
195
195
  className: `plex-player-container ${className}`,
196
196
  style: {
197
197
  width: '100%',
198
- height: '100%',
198
+ aspectRatio: '16 / 9',
199
199
  position: 'relative',
200
200
  ...style
201
201
  },
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/react/index.jsx"],"sourcesContent":["/**\r\n * @frameset/plex-player - React Component\r\n * Professional Video Player by FRAMESET Studio\r\n * https://frameset.dev\r\n */\r\n\r\nimport React, {\r\n useEffect,\r\n useRef,\r\n useImperativeHandle,\r\n forwardRef,\r\n useState,\r\n useCallback,\r\n createContext,\r\n useContext,\r\n} from 'react';\r\n\r\n// Import core player\r\nimport PlexPlayer from '../core/index.js';\r\n\r\n// Context for nested components\r\nconst PlexPlayerContext = createContext(null);\r\n\r\n/**\r\n * Hook to access player instance from child components\r\n */\r\nexport const usePlexPlayer = () => {\r\n const player = useContext(PlexPlayerContext);\r\n return player;\r\n};\r\n\r\n/**\r\n * PlexPlayer React Component\r\n */\r\nexport const PlexPlayerReact = forwardRef(function PlexPlayerReact(props, ref) {\r\n const {\r\n src,\r\n playlist,\r\n className = '',\r\n style = {},\r\n autoplay = false,\r\n muted = false,\r\n loop = false,\r\n volume = 1,\r\n poster,\r\n preload = 'metadata',\r\n keyboard = true,\r\n touch = true,\r\n pip = true,\r\n cast = true,\r\n fullscreen = true,\r\n controlsHideDelay = 3000,\r\n theme,\r\n subtitles,\r\n ads,\r\n i18n,\r\n // Event callbacks\r\n onPlay,\r\n onPause,\r\n onEnded,\r\n onTimeUpdate,\r\n onProgress,\r\n onVolumeChange,\r\n onFullscreenChange,\r\n onError,\r\n onReady,\r\n // Children for custom overlays\r\n children,\r\n ...restProps\r\n } = props;\r\n\r\n const containerRef = useRef(null);\r\n const playerRef = useRef(null);\r\n const [isReady, setIsReady] = useState(false);\r\n\r\n // Initialize player\r\n useEffect(() => {\r\n if (!containerRef.current) return;\r\n\r\n // Create player instance\r\n const player = new PlexPlayer({\r\n container: containerRef.current,\r\n autoplay,\r\n muted,\r\n loop,\r\n volume,\r\n poster,\r\n preload,\r\n keyboard,\r\n touch,\r\n pip,\r\n cast,\r\n fullscreen,\r\n controlsHideDelay,\r\n theme,\r\n subtitles,\r\n ads,\r\n i18n,\r\n });\r\n\r\n playerRef.current = player;\r\n\r\n // Bind events\r\n if (onPlay) player.on('play', onPlay);\r\n if (onPause) player.on('pause', onPause);\r\n if (onEnded) player.on('ended', onEnded);\r\n if (onTimeUpdate) {\r\n player.on('timeupdate', (data) => onTimeUpdate(data.currentTime));\r\n }\r\n if (onProgress) {\r\n player.on('progress', (data) => onProgress(data.buffered));\r\n }\r\n if (onVolumeChange) {\r\n player.on('volumechange', (data) => onVolumeChange(data.volume, data.muted));\r\n }\r\n if (onFullscreenChange) {\r\n player.on('fullscreenchange', (data) => onFullscreenChange(data.isFullscreen));\r\n }\r\n if (onError) {\r\n player.on('error', onError);\r\n }\r\n\r\n setIsReady(true);\r\n\r\n if (onReady) {\r\n onReady(player);\r\n }\r\n\r\n // Cleanup\r\n return () => {\r\n player.destroy();\r\n playerRef.current = null;\r\n };\r\n }, []);\r\n\r\n // Load source when src changes\r\n useEffect(() => {\r\n if (!playerRef.current || !isReady) return;\r\n\r\n if (src) {\r\n playerRef.current.load(src);\r\n }\r\n }, [src, isReady]);\r\n\r\n // Load playlist when playlist changes\r\n useEffect(() => {\r\n if (!playerRef.current || !isReady || !playlist) return;\r\n\r\n playerRef.current.loadPlaylist(playlist);\r\n }, [playlist, isReady]);\r\n\r\n // Update volume\r\n useEffect(() => {\r\n if (playerRef.current && isReady) {\r\n playerRef.current.setVolume(volume);\r\n }\r\n }, [volume, isReady]);\r\n\r\n // Update muted\r\n useEffect(() => {\r\n if (playerRef.current && isReady) {\r\n if (muted) {\r\n playerRef.current.mute();\r\n } else {\r\n playerRef.current.unmute();\r\n }\r\n }\r\n }, [muted, isReady]);\r\n\r\n // Expose player methods via ref\r\n useImperativeHandle(ref, () => ({\r\n play: () => playerRef.current?.play(),\r\n pause: () => playerRef.current?.pause(),\r\n togglePlay: () => playerRef.current?.togglePlay(),\r\n seek: (time) => playerRef.current?.seek(time),\r\n seekPercent: (percent) => playerRef.current?.seekPercent(percent),\r\n setVolume: (vol) => playerRef.current?.setVolume(vol),\r\n getVolume: () => playerRef.current?.getVolume(),\r\n mute: () => playerRef.current?.mute(),\r\n unmute: () => playerRef.current?.unmute(),\r\n toggleMute: () => playerRef.current?.toggleMute(),\r\n isMuted: () => playerRef.current?.isMuted(),\r\n setPlaybackRate: (rate) => playerRef.current?.setPlaybackRate(rate),\r\n enterFullscreen: () => playerRef.current?.enterFullscreen(),\r\n exitFullscreen: () => playerRef.current?.exitFullscreen(),\r\n toggleFullscreen: () => playerRef.current?.toggleFullscreen(),\r\n enterPiP: () => playerRef.current?.enterPiP(),\r\n exitPiP: () => playerRef.current?.exitPiP(),\r\n togglePiP: () => playerRef.current?.togglePiP(),\r\n cast: () => playerRef.current?.cast(),\r\n getState: () => playerRef.current?.getState(),\r\n getPlayer: () => playerRef.current,\r\n next: () => playerRef.current?.next(),\r\n previous: () => playerRef.current?.previous(),\r\n playAt: (index) => playerRef.current?.playAt(index),\r\n }));\r\n\r\n return (\r\n <PlexPlayerContext.Provider value={playerRef.current}>\r\n <div\r\n ref={containerRef}\r\n className={`plex-player-container ${className}`}\r\n style={{\r\n width: '100%',\r\n height: '100%',\r\n position: 'relative',\r\n ...style,\r\n }}\r\n {...restProps}\r\n >\r\n {children}\r\n </div>\r\n </PlexPlayerContext.Provider>\r\n );\r\n});\r\n\r\n// Additional hooks for convenience\r\nexport const usePlexPlayerState = () => {\r\n const player = usePlexPlayer();\r\n const [state, setState] = useState(null);\r\n\r\n useEffect(() => {\r\n if (!player) return;\r\n\r\n const updateState = () => {\r\n setState(player.getState());\r\n };\r\n\r\n // Update on every timeupdate\r\n player.on('timeupdate', updateState);\r\n player.on('play', updateState);\r\n player.on('pause', updateState);\r\n player.on('volumechange', updateState);\r\n player.on('fullscreenchange', updateState);\r\n\r\n // Initial state\r\n updateState();\r\n\r\n return () => {\r\n player.off('timeupdate', updateState);\r\n player.off('play', updateState);\r\n player.off('pause', updateState);\r\n player.off('volumechange', updateState);\r\n player.off('fullscreenchange', updateState);\r\n };\r\n }, [player]);\r\n\r\n return state;\r\n};\r\n\r\nexport const usePlexPlayerTime = () => {\r\n const player = usePlexPlayer();\r\n const [time, setTime] = useState({ current: 0, duration: 0 });\r\n\r\n useEffect(() => {\r\n if (!player) return;\r\n\r\n const updateTime = (data) => {\r\n setTime({\r\n current: data.currentTime,\r\n duration: data.duration,\r\n });\r\n };\r\n\r\n player.on('timeupdate', updateTime);\r\n\r\n return () => {\r\n player.off('timeupdate', updateTime);\r\n };\r\n }, [player]);\r\n\r\n return time;\r\n};\r\n\r\n// Named exports\r\nexport { PlexPlayer };\r\nexport default PlexPlayerReact;\r\n"],"names":["PlexPlayerContext","createContext","usePlexPlayer","player","useContext","PlexPlayerReact","forwardRef","props","ref","src","playlist","className","style","autoplay","muted","loop","volume","poster","preload","keyboard","touch","pip","cast","fullscreen","controlsHideDelay","theme","subtitles","ads","i18n","onPlay","onPause","onEnded","onTimeUpdate","onProgress","onVolumeChange","onFullscreenChange","onError","onReady","children","restProps","containerRef","useRef","playerRef","isReady","setIsReady","useState","useEffect","current","PlexPlayer","container","on","data","currentTime","buffered","isFullscreen","destroy","load","loadPlaylist","setVolume","mute","unmute","useImperativeHandle","play","pause","togglePlay","seek","time","seekPercent","percent","vol","getVolume","toggleMute","isMuted","setPlaybackRate","rate","enterFullscreen","exitFullscreen","toggleFullscreen","enterPiP","exitPiP","togglePiP","getState","getPlayer","next","previous","playAt","index","_jsx","Provider","value","width","height","position","usePlexPlayerState","state","setState","updateState","off","usePlexPlayerTime","setTime","duration","updateTime"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/react/index.jsx"],"sourcesContent":["/**\r\n * @frameset/plex-player - React Component\r\n * Professional Video Player by FRAMESET Studio\r\n * https://frameset.dev\r\n */\r\n\r\nimport React, {\r\n useEffect,\r\n useRef,\r\n useImperativeHandle,\r\n forwardRef,\r\n useState,\r\n useCallback,\r\n createContext,\r\n useContext,\r\n} from 'react';\r\n\r\n// Import core player\r\nimport PlexPlayer from '../core/index.js';\r\n\r\n// Context for nested components\r\nconst PlexPlayerContext = createContext(null);\r\n\r\n/**\r\n * Hook to access player instance from child components\r\n */\r\nexport const usePlexPlayer = () => {\r\n const player = useContext(PlexPlayerContext);\r\n return player;\r\n};\r\n\r\n/**\r\n * PlexPlayer React Component\r\n */\r\nexport const PlexPlayerReact = forwardRef(function PlexPlayerReact(props, ref) {\r\n const {\r\n src,\r\n playlist,\r\n className = '',\r\n style = {},\r\n autoplay = false,\r\n muted = false,\r\n loop = false,\r\n volume = 1,\r\n poster,\r\n preload = 'metadata',\r\n keyboard = true,\r\n touch = true,\r\n pip = true,\r\n cast = true,\r\n fullscreen = true,\r\n controlsHideDelay = 3000,\r\n theme,\r\n subtitles,\r\n ads,\r\n i18n,\r\n // Event callbacks\r\n onPlay,\r\n onPause,\r\n onEnded,\r\n onTimeUpdate,\r\n onProgress,\r\n onVolumeChange,\r\n onFullscreenChange,\r\n onError,\r\n onReady,\r\n // Children for custom overlays\r\n children,\r\n ...restProps\r\n } = props;\r\n\r\n const containerRef = useRef(null);\r\n const playerRef = useRef(null);\r\n const [isReady, setIsReady] = useState(false);\r\n\r\n // Initialize player\r\n useEffect(() => {\r\n if (!containerRef.current) return;\r\n\r\n // Create player instance\r\n const player = new PlexPlayer({\r\n container: containerRef.current,\r\n autoplay,\r\n muted,\r\n loop,\r\n volume,\r\n poster,\r\n preload,\r\n keyboard,\r\n touch,\r\n pip,\r\n cast,\r\n fullscreen,\r\n controlsHideDelay,\r\n theme,\r\n subtitles,\r\n ads,\r\n i18n,\r\n });\r\n\r\n playerRef.current = player;\r\n\r\n // Bind events\r\n if (onPlay) player.on('play', onPlay);\r\n if (onPause) player.on('pause', onPause);\r\n if (onEnded) player.on('ended', onEnded);\r\n if (onTimeUpdate) {\r\n player.on('timeupdate', (data) => onTimeUpdate(data.currentTime));\r\n }\r\n if (onProgress) {\r\n player.on('progress', (data) => onProgress(data.buffered));\r\n }\r\n if (onVolumeChange) {\r\n player.on('volumechange', (data) => onVolumeChange(data.volume, data.muted));\r\n }\r\n if (onFullscreenChange) {\r\n player.on('fullscreenchange', (data) => onFullscreenChange(data.isFullscreen));\r\n }\r\n if (onError) {\r\n player.on('error', onError);\r\n }\r\n\r\n setIsReady(true);\r\n\r\n if (onReady) {\r\n onReady(player);\r\n }\r\n\r\n // Cleanup\r\n return () => {\r\n player.destroy();\r\n playerRef.current = null;\r\n };\r\n }, []);\r\n\r\n // Load source when src changes\r\n useEffect(() => {\r\n if (!playerRef.current || !isReady) return;\r\n\r\n if (src) {\r\n playerRef.current.load(src);\r\n }\r\n }, [src, isReady]);\r\n\r\n // Load playlist when playlist changes\r\n useEffect(() => {\r\n if (!playerRef.current || !isReady || !playlist) return;\r\n\r\n playerRef.current.loadPlaylist(playlist);\r\n }, [playlist, isReady]);\r\n\r\n // Update volume\r\n useEffect(() => {\r\n if (playerRef.current && isReady) {\r\n playerRef.current.setVolume(volume);\r\n }\r\n }, [volume, isReady]);\r\n\r\n // Update muted\r\n useEffect(() => {\r\n if (playerRef.current && isReady) {\r\n if (muted) {\r\n playerRef.current.mute();\r\n } else {\r\n playerRef.current.unmute();\r\n }\r\n }\r\n }, [muted, isReady]);\r\n\r\n // Expose player methods via ref\r\n useImperativeHandle(ref, () => ({\r\n play: () => playerRef.current?.play(),\r\n pause: () => playerRef.current?.pause(),\r\n togglePlay: () => playerRef.current?.togglePlay(),\r\n seek: (time) => playerRef.current?.seek(time),\r\n seekPercent: (percent) => playerRef.current?.seekPercent(percent),\r\n setVolume: (vol) => playerRef.current?.setVolume(vol),\r\n getVolume: () => playerRef.current?.getVolume(),\r\n mute: () => playerRef.current?.mute(),\r\n unmute: () => playerRef.current?.unmute(),\r\n toggleMute: () => playerRef.current?.toggleMute(),\r\n isMuted: () => playerRef.current?.isMuted(),\r\n setPlaybackRate: (rate) => playerRef.current?.setPlaybackRate(rate),\r\n enterFullscreen: () => playerRef.current?.enterFullscreen(),\r\n exitFullscreen: () => playerRef.current?.exitFullscreen(),\r\n toggleFullscreen: () => playerRef.current?.toggleFullscreen(),\r\n enterPiP: () => playerRef.current?.enterPiP(),\r\n exitPiP: () => playerRef.current?.exitPiP(),\r\n togglePiP: () => playerRef.current?.togglePiP(),\r\n cast: () => playerRef.current?.cast(),\r\n getState: () => playerRef.current?.getState(),\r\n getPlayer: () => playerRef.current,\r\n next: () => playerRef.current?.next(),\r\n previous: () => playerRef.current?.previous(),\r\n playAt: (index) => playerRef.current?.playAt(index),\r\n }));\r\n\r\n return (\r\n <PlexPlayerContext.Provider value={playerRef.current}>\r\n <div\r\n ref={containerRef}\r\n className={`plex-player-container ${className}`}\r\n style={{\r\n width: '100%',\r\n aspectRatio: '16 / 9',\r\n position: 'relative',\r\n ...style,\r\n }}\r\n {...restProps}\r\n >\r\n {children}\r\n </div>\r\n </PlexPlayerContext.Provider>\r\n );\r\n});\r\n\r\n// Additional hooks for convenience\r\nexport const usePlexPlayerState = () => {\r\n const player = usePlexPlayer();\r\n const [state, setState] = useState(null);\r\n\r\n useEffect(() => {\r\n if (!player) return;\r\n\r\n const updateState = () => {\r\n setState(player.getState());\r\n };\r\n\r\n // Update on every timeupdate\r\n player.on('timeupdate', updateState);\r\n player.on('play', updateState);\r\n player.on('pause', updateState);\r\n player.on('volumechange', updateState);\r\n player.on('fullscreenchange', updateState);\r\n\r\n // Initial state\r\n updateState();\r\n\r\n return () => {\r\n player.off('timeupdate', updateState);\r\n player.off('play', updateState);\r\n player.off('pause', updateState);\r\n player.off('volumechange', updateState);\r\n player.off('fullscreenchange', updateState);\r\n };\r\n }, [player]);\r\n\r\n return state;\r\n};\r\n\r\nexport const usePlexPlayerTime = () => {\r\n const player = usePlexPlayer();\r\n const [time, setTime] = useState({ current: 0, duration: 0 });\r\n\r\n useEffect(() => {\r\n if (!player) return;\r\n\r\n const updateTime = (data) => {\r\n setTime({\r\n current: data.currentTime,\r\n duration: data.duration,\r\n });\r\n };\r\n\r\n player.on('timeupdate', updateTime);\r\n\r\n return () => {\r\n player.off('timeupdate', updateTime);\r\n };\r\n }, [player]);\r\n\r\n return time;\r\n};\r\n\r\n// Named exports\r\nexport { PlexPlayer };\r\nexport default PlexPlayerReact;\r\n"],"names":["PlexPlayerContext","createContext","usePlexPlayer","player","useContext","PlexPlayerReact","forwardRef","props","ref","src","playlist","className","style","autoplay","muted","loop","volume","poster","preload","keyboard","touch","pip","cast","fullscreen","controlsHideDelay","theme","subtitles","ads","i18n","onPlay","onPause","onEnded","onTimeUpdate","onProgress","onVolumeChange","onFullscreenChange","onError","onReady","children","restProps","containerRef","useRef","playerRef","isReady","setIsReady","useState","useEffect","current","PlexPlayer","container","on","data","currentTime","buffered","isFullscreen","destroy","load","loadPlaylist","setVolume","mute","unmute","useImperativeHandle","play","pause","togglePlay","seek","time","seekPercent","percent","vol","getVolume","toggleMute","isMuted","setPlaybackRate","rate","enterFullscreen","exitFullscreen","toggleFullscreen","enterPiP","exitPiP","togglePiP","getState","getPlayer","next","previous","playAt","index","_jsx","Provider","value","width","aspectRatio","position","usePlexPlayerState","state","setState","updateState","off","usePlexPlayerTime","setTime","duration","updateTime"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @frameset/plex-player v1.0.3
2
+ * @frameset/plex-player v1.0.4
3
3
  * Professional video player with VAST ads, Chromecast, PiP, subtitles, playlists and more. Built by FRAMESET Studio.
4
4
  * (c) 2026 FRAMESET Studio
5
5
  * Released under the MIT License
@@ -233,7 +233,7 @@ const PlexPlayerVue = defineComponent({
233
233
  class: 'plex-player-container',
234
234
  style: {
235
235
  width: '100%',
236
- height: '100%',
236
+ aspectRatio: '16 / 9',
237
237
  position: 'relative'
238
238
  }
239
239
  }, slots.default?.());
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../../src/vue/index.js"],"sourcesContent":["/**\r\n * @frameset/plex-player - Vue Component\r\n * Professional Video Player by FRAMESET Studio\r\n * https://frameset.dev\r\n */\r\n\r\nimport { \r\n defineComponent, \r\n ref, \r\n onMounted, \r\n onBeforeUnmount, \r\n watch,\r\n provide,\r\n inject,\r\n h\r\n} from 'vue';\r\n\r\n// Import core player\r\nimport PlexPlayer from '../core/index.js';\r\n\r\n// Provide/inject key\r\nconst PlexPlayerKey = Symbol('PlexPlayer');\r\n\r\n/**\r\n * Composable to access player instance\r\n */\r\nexport function usePlexPlayer() {\r\n return inject(PlexPlayerKey, ref(null));\r\n}\r\n\r\n/**\r\n * PlexPlayer Vue Component\r\n */\r\nexport const PlexPlayerVue = defineComponent({\r\n name: 'PlexPlayer',\r\n\r\n props: {\r\n src: {\r\n type: String,\r\n default: '',\r\n },\r\n playlist: {\r\n type: Array,\r\n default: () => [],\r\n },\r\n autoplay: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n muted: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n loop: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n volume: {\r\n type: Number,\r\n default: 1,\r\n },\r\n poster: {\r\n type: String,\r\n default: '',\r\n },\r\n preload: {\r\n type: String,\r\n default: 'metadata',\r\n },\r\n keyboard: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n touch: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n pip: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n cast: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n fullscreen: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n controlsHideDelay: {\r\n type: Number,\r\n default: 3000,\r\n },\r\n theme: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n subtitles: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n ads: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n i18n: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n },\r\n\r\n emits: [\r\n 'play',\r\n 'pause',\r\n 'ended',\r\n 'timeupdate',\r\n 'progress',\r\n 'volumechange',\r\n 'fullscreenchange',\r\n 'error',\r\n 'ready',\r\n ],\r\n\r\n setup(props, { emit, slots, expose }) {\r\n const containerRef = ref(null);\r\n const playerRef = ref(null);\r\n const isReady = ref(false);\r\n\r\n // Provide player to child components\r\n provide(PlexPlayerKey, playerRef);\r\n\r\n onMounted(() => {\r\n if (!containerRef.value) return;\r\n\r\n // Create player instance\r\n const player = new PlexPlayer({\r\n container: containerRef.value,\r\n autoplay: props.autoplay,\r\n muted: props.muted,\r\n loop: props.loop,\r\n volume: props.volume,\r\n poster: props.poster,\r\n preload: props.preload,\r\n keyboard: props.keyboard,\r\n touch: props.touch,\r\n pip: props.pip,\r\n cast: props.cast,\r\n fullscreen: props.fullscreen,\r\n controlsHideDelay: props.controlsHideDelay,\r\n theme: props.theme,\r\n subtitles: props.subtitles,\r\n ads: props.ads,\r\n i18n: props.i18n,\r\n });\r\n\r\n playerRef.value = player;\r\n\r\n // Bind events\r\n player.on('play', () => emit('play'));\r\n player.on('pause', () => emit('pause'));\r\n player.on('ended', () => emit('ended'));\r\n player.on('timeupdate', (data) => emit('timeupdate', data.currentTime));\r\n player.on('progress', (data) => emit('progress', data.buffered));\r\n player.on('volumechange', (data) => emit('volumechange', data));\r\n player.on('fullscreenchange', (data) => emit('fullscreenchange', data.isFullscreen));\r\n player.on('error', (error) => emit('error', error));\r\n\r\n isReady.value = true;\r\n emit('ready', player);\r\n\r\n // Load initial source\r\n if (props.src) {\r\n player.load(props.src);\r\n } else if (props.playlist.length > 0) {\r\n player.loadPlaylist(props.playlist);\r\n }\r\n });\r\n\r\n onBeforeUnmount(() => {\r\n if (playerRef.value) {\r\n playerRef.value.destroy();\r\n playerRef.value = null;\r\n }\r\n });\r\n\r\n // Watch for src changes\r\n watch(() => props.src, (newSrc) => {\r\n if (playerRef.value && newSrc) {\r\n playerRef.value.load(newSrc);\r\n }\r\n });\r\n\r\n // Watch for playlist changes\r\n watch(() => props.playlist, (newPlaylist) => {\r\n if (playerRef.value && newPlaylist?.length > 0) {\r\n playerRef.value.loadPlaylist(newPlaylist);\r\n }\r\n }, { deep: true });\r\n\r\n // Watch for volume changes\r\n watch(() => props.volume, (newVolume) => {\r\n if (playerRef.value) {\r\n playerRef.value.setVolume(newVolume);\r\n }\r\n });\r\n\r\n // Watch for muted changes\r\n watch(() => props.muted, (newMuted) => {\r\n if (playerRef.value) {\r\n if (newMuted) {\r\n playerRef.value.mute();\r\n } else {\r\n playerRef.value.unmute();\r\n }\r\n }\r\n });\r\n\r\n // Expose methods\r\n expose({\r\n play: () => playerRef.value?.play(),\r\n pause: () => playerRef.value?.pause(),\r\n togglePlay: () => playerRef.value?.togglePlay(),\r\n seek: (time) => playerRef.value?.seek(time),\r\n seekPercent: (percent) => playerRef.value?.seekPercent(percent),\r\n setVolume: (vol) => playerRef.value?.setVolume(vol),\r\n getVolume: () => playerRef.value?.getVolume(),\r\n mute: () => playerRef.value?.mute(),\r\n unmute: () => playerRef.value?.unmute(),\r\n toggleMute: () => playerRef.value?.toggleMute(),\r\n setPlaybackRate: (rate) => playerRef.value?.setPlaybackRate(rate),\r\n enterFullscreen: () => playerRef.value?.enterFullscreen(),\r\n exitFullscreen: () => playerRef.value?.exitFullscreen(),\r\n toggleFullscreen: () => playerRef.value?.toggleFullscreen(),\r\n enterPiP: () => playerRef.value?.enterPiP(),\r\n exitPiP: () => playerRef.value?.exitPiP(),\r\n togglePiP: () => playerRef.value?.togglePiP(),\r\n cast: () => playerRef.value?.cast(),\r\n getState: () => playerRef.value?.getState(),\r\n getPlayer: () => playerRef.value,\r\n next: () => playerRef.value?.next(),\r\n previous: () => playerRef.value?.previous(),\r\n playAt: (index) => playerRef.value?.playAt(index),\r\n });\r\n\r\n return () => h(\r\n 'div',\r\n {\r\n ref: containerRef,\r\n class: 'plex-player-container',\r\n style: {\r\n width: '100%',\r\n height: '100%',\r\n position: 'relative',\r\n },\r\n },\r\n slots.default?.()\r\n );\r\n },\r\n});\r\n\r\n// Composables\r\nexport function usePlexPlayerState() {\r\n const player = usePlexPlayer();\r\n const state = ref(null);\r\n\r\n watch(player, (p) => {\r\n if (!p) return;\r\n\r\n const updateState = () => {\r\n state.value = p.getState();\r\n };\r\n\r\n p.on('timeupdate', updateState);\r\n p.on('play', updateState);\r\n p.on('pause', updateState);\r\n p.on('volumechange', updateState);\r\n\r\n updateState();\r\n }, { immediate: true });\r\n\r\n return state;\r\n}\r\n\r\nexport function usePlexPlayerTime() {\r\n const player = usePlexPlayer();\r\n const time = ref({ current: 0, duration: 0 });\r\n\r\n watch(player, (p) => {\r\n if (!p) return;\r\n\r\n p.on('timeupdate', (data) => {\r\n time.value = {\r\n current: data.currentTime,\r\n duration: data.duration,\r\n };\r\n });\r\n }, { immediate: true });\r\n\r\n return time;\r\n}\r\n\r\n// Named exports\r\nexport { PlexPlayer };\r\nexport default PlexPlayerVue;\r\n"],"names":["PlexPlayerKey","Symbol","usePlexPlayer","inject","ref","PlexPlayerVue","defineComponent","name","props","src","type","String","default","playlist","Array","autoplay","Boolean","muted","loop","volume","Number","poster","preload","keyboard","touch","pip","cast","fullscreen","controlsHideDelay","theme","Object","subtitles","ads","i18n","emits","setup","emit","slots","expose","containerRef","playerRef","isReady","provide","onMounted","value","player","PlexPlayer","container","on","data","currentTime","buffered","isFullscreen","error","load","length","loadPlaylist","onBeforeUnmount","destroy","watch","newSrc","newPlaylist","deep","newVolume","setVolume","newMuted","mute","unmute","play","pause","togglePlay","seek","time","seekPercent","percent","vol","getVolume","toggleMute","setPlaybackRate","rate","enterFullscreen","exitFullscreen","toggleFullscreen","enterPiP","exitPiP","togglePiP","getState","getPlayer","next","previous","playAt","index","h","class","style","width","height","position","usePlexPlayerState","state","p","updateState","immediate","usePlexPlayerTime","current","duration"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../../src/vue/index.js"],"sourcesContent":["/**\r\n * @frameset/plex-player - Vue Component\r\n * Professional Video Player by FRAMESET Studio\r\n * https://frameset.dev\r\n */\r\n\r\nimport { \r\n defineComponent, \r\n ref, \r\n onMounted, \r\n onBeforeUnmount, \r\n watch,\r\n provide,\r\n inject,\r\n h\r\n} from 'vue';\r\n\r\n// Import core player\r\nimport PlexPlayer from '../core/index.js';\r\n\r\n// Provide/inject key\r\nconst PlexPlayerKey = Symbol('PlexPlayer');\r\n\r\n/**\r\n * Composable to access player instance\r\n */\r\nexport function usePlexPlayer() {\r\n return inject(PlexPlayerKey, ref(null));\r\n}\r\n\r\n/**\r\n * PlexPlayer Vue Component\r\n */\r\nexport const PlexPlayerVue = defineComponent({\r\n name: 'PlexPlayer',\r\n\r\n props: {\r\n src: {\r\n type: String,\r\n default: '',\r\n },\r\n playlist: {\r\n type: Array,\r\n default: () => [],\r\n },\r\n autoplay: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n muted: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n loop: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n volume: {\r\n type: Number,\r\n default: 1,\r\n },\r\n poster: {\r\n type: String,\r\n default: '',\r\n },\r\n preload: {\r\n type: String,\r\n default: 'metadata',\r\n },\r\n keyboard: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n touch: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n pip: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n cast: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n fullscreen: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n controlsHideDelay: {\r\n type: Number,\r\n default: 3000,\r\n },\r\n theme: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n subtitles: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n ads: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n i18n: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n },\r\n\r\n emits: [\r\n 'play',\r\n 'pause',\r\n 'ended',\r\n 'timeupdate',\r\n 'progress',\r\n 'volumechange',\r\n 'fullscreenchange',\r\n 'error',\r\n 'ready',\r\n ],\r\n\r\n setup(props, { emit, slots, expose }) {\r\n const containerRef = ref(null);\r\n const playerRef = ref(null);\r\n const isReady = ref(false);\r\n\r\n // Provide player to child components\r\n provide(PlexPlayerKey, playerRef);\r\n\r\n onMounted(() => {\r\n if (!containerRef.value) return;\r\n\r\n // Create player instance\r\n const player = new PlexPlayer({\r\n container: containerRef.value,\r\n autoplay: props.autoplay,\r\n muted: props.muted,\r\n loop: props.loop,\r\n volume: props.volume,\r\n poster: props.poster,\r\n preload: props.preload,\r\n keyboard: props.keyboard,\r\n touch: props.touch,\r\n pip: props.pip,\r\n cast: props.cast,\r\n fullscreen: props.fullscreen,\r\n controlsHideDelay: props.controlsHideDelay,\r\n theme: props.theme,\r\n subtitles: props.subtitles,\r\n ads: props.ads,\r\n i18n: props.i18n,\r\n });\r\n\r\n playerRef.value = player;\r\n\r\n // Bind events\r\n player.on('play', () => emit('play'));\r\n player.on('pause', () => emit('pause'));\r\n player.on('ended', () => emit('ended'));\r\n player.on('timeupdate', (data) => emit('timeupdate', data.currentTime));\r\n player.on('progress', (data) => emit('progress', data.buffered));\r\n player.on('volumechange', (data) => emit('volumechange', data));\r\n player.on('fullscreenchange', (data) => emit('fullscreenchange', data.isFullscreen));\r\n player.on('error', (error) => emit('error', error));\r\n\r\n isReady.value = true;\r\n emit('ready', player);\r\n\r\n // Load initial source\r\n if (props.src) {\r\n player.load(props.src);\r\n } else if (props.playlist.length > 0) {\r\n player.loadPlaylist(props.playlist);\r\n }\r\n });\r\n\r\n onBeforeUnmount(() => {\r\n if (playerRef.value) {\r\n playerRef.value.destroy();\r\n playerRef.value = null;\r\n }\r\n });\r\n\r\n // Watch for src changes\r\n watch(() => props.src, (newSrc) => {\r\n if (playerRef.value && newSrc) {\r\n playerRef.value.load(newSrc);\r\n }\r\n });\r\n\r\n // Watch for playlist changes\r\n watch(() => props.playlist, (newPlaylist) => {\r\n if (playerRef.value && newPlaylist?.length > 0) {\r\n playerRef.value.loadPlaylist(newPlaylist);\r\n }\r\n }, { deep: true });\r\n\r\n // Watch for volume changes\r\n watch(() => props.volume, (newVolume) => {\r\n if (playerRef.value) {\r\n playerRef.value.setVolume(newVolume);\r\n }\r\n });\r\n\r\n // Watch for muted changes\r\n watch(() => props.muted, (newMuted) => {\r\n if (playerRef.value) {\r\n if (newMuted) {\r\n playerRef.value.mute();\r\n } else {\r\n playerRef.value.unmute();\r\n }\r\n }\r\n });\r\n\r\n // Expose methods\r\n expose({\r\n play: () => playerRef.value?.play(),\r\n pause: () => playerRef.value?.pause(),\r\n togglePlay: () => playerRef.value?.togglePlay(),\r\n seek: (time) => playerRef.value?.seek(time),\r\n seekPercent: (percent) => playerRef.value?.seekPercent(percent),\r\n setVolume: (vol) => playerRef.value?.setVolume(vol),\r\n getVolume: () => playerRef.value?.getVolume(),\r\n mute: () => playerRef.value?.mute(),\r\n unmute: () => playerRef.value?.unmute(),\r\n toggleMute: () => playerRef.value?.toggleMute(),\r\n setPlaybackRate: (rate) => playerRef.value?.setPlaybackRate(rate),\r\n enterFullscreen: () => playerRef.value?.enterFullscreen(),\r\n exitFullscreen: () => playerRef.value?.exitFullscreen(),\r\n toggleFullscreen: () => playerRef.value?.toggleFullscreen(),\r\n enterPiP: () => playerRef.value?.enterPiP(),\r\n exitPiP: () => playerRef.value?.exitPiP(),\r\n togglePiP: () => playerRef.value?.togglePiP(),\r\n cast: () => playerRef.value?.cast(),\r\n getState: () => playerRef.value?.getState(),\r\n getPlayer: () => playerRef.value,\r\n next: () => playerRef.value?.next(),\r\n previous: () => playerRef.value?.previous(),\r\n playAt: (index) => playerRef.value?.playAt(index),\r\n });\r\n\r\n return () => h(\r\n 'div',\r\n {\r\n ref: containerRef,\r\n class: 'plex-player-container',\r\n style: {\r\n width: '100%',\r\n aspectRatio: '16 / 9',\r\n position: 'relative',\r\n },\r\n },\r\n slots.default?.()\r\n );\r\n },\r\n});\r\n\r\n// Composables\r\nexport function usePlexPlayerState() {\r\n const player = usePlexPlayer();\r\n const state = ref(null);\r\n\r\n watch(player, (p) => {\r\n if (!p) return;\r\n\r\n const updateState = () => {\r\n state.value = p.getState();\r\n };\r\n\r\n p.on('timeupdate', updateState);\r\n p.on('play', updateState);\r\n p.on('pause', updateState);\r\n p.on('volumechange', updateState);\r\n\r\n updateState();\r\n }, { immediate: true });\r\n\r\n return state;\r\n}\r\n\r\nexport function usePlexPlayerTime() {\r\n const player = usePlexPlayer();\r\n const time = ref({ current: 0, duration: 0 });\r\n\r\n watch(player, (p) => {\r\n if (!p) return;\r\n\r\n p.on('timeupdate', (data) => {\r\n time.value = {\r\n current: data.currentTime,\r\n duration: data.duration,\r\n };\r\n });\r\n }, { immediate: true });\r\n\r\n return time;\r\n}\r\n\r\n// Named exports\r\nexport { PlexPlayer };\r\nexport default PlexPlayerVue;\r\n"],"names":["PlexPlayerKey","Symbol","usePlexPlayer","inject","ref","PlexPlayerVue","defineComponent","name","props","src","type","String","default","playlist","Array","autoplay","Boolean","muted","loop","volume","Number","poster","preload","keyboard","touch","pip","cast","fullscreen","controlsHideDelay","theme","Object","subtitles","ads","i18n","emits","setup","emit","slots","expose","containerRef","playerRef","isReady","provide","onMounted","value","player","PlexPlayer","container","on","data","currentTime","buffered","isFullscreen","error","load","length","loadPlaylist","onBeforeUnmount","destroy","watch","newSrc","newPlaylist","deep","newVolume","setVolume","newMuted","mute","unmute","play","pause","togglePlay","seek","time","seekPercent","percent","vol","getVolume","toggleMute","setPlaybackRate","rate","enterFullscreen","exitFullscreen","toggleFullscreen","enterPiP","exitPiP","togglePiP","getState","getPlayer","next","previous","playAt","index","h","class","style","width","aspectRatio","position","usePlexPlayerState","state","p","updateState","immediate","usePlexPlayerTime","current","duration"],"mappings":"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"}
package/dist/vue/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @frameset/plex-player v1.0.3
2
+ * @frameset/plex-player v1.0.4
3
3
  * Professional video player with VAST ads, Chromecast, PiP, subtitles, playlists and more. Built by FRAMESET Studio.
4
4
  * (c) 2026 FRAMESET Studio
5
5
  * Released under the MIT License
@@ -236,7 +236,7 @@ const PlexPlayerVue = vue.defineComponent({
236
236
  class: 'plex-player-container',
237
237
  style: {
238
238
  width: '100%',
239
- height: '100%',
239
+ aspectRatio: '16 / 9',
240
240
  position: 'relative'
241
241
  }
242
242
  }, slots.default?.());
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/vue/index.js"],"sourcesContent":["/**\r\n * @frameset/plex-player - Vue Component\r\n * Professional Video Player by FRAMESET Studio\r\n * https://frameset.dev\r\n */\r\n\r\nimport { \r\n defineComponent, \r\n ref, \r\n onMounted, \r\n onBeforeUnmount, \r\n watch,\r\n provide,\r\n inject,\r\n h\r\n} from 'vue';\r\n\r\n// Import core player\r\nimport PlexPlayer from '../core/index.js';\r\n\r\n// Provide/inject key\r\nconst PlexPlayerKey = Symbol('PlexPlayer');\r\n\r\n/**\r\n * Composable to access player instance\r\n */\r\nexport function usePlexPlayer() {\r\n return inject(PlexPlayerKey, ref(null));\r\n}\r\n\r\n/**\r\n * PlexPlayer Vue Component\r\n */\r\nexport const PlexPlayerVue = defineComponent({\r\n name: 'PlexPlayer',\r\n\r\n props: {\r\n src: {\r\n type: String,\r\n default: '',\r\n },\r\n playlist: {\r\n type: Array,\r\n default: () => [],\r\n },\r\n autoplay: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n muted: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n loop: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n volume: {\r\n type: Number,\r\n default: 1,\r\n },\r\n poster: {\r\n type: String,\r\n default: '',\r\n },\r\n preload: {\r\n type: String,\r\n default: 'metadata',\r\n },\r\n keyboard: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n touch: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n pip: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n cast: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n fullscreen: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n controlsHideDelay: {\r\n type: Number,\r\n default: 3000,\r\n },\r\n theme: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n subtitles: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n ads: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n i18n: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n },\r\n\r\n emits: [\r\n 'play',\r\n 'pause',\r\n 'ended',\r\n 'timeupdate',\r\n 'progress',\r\n 'volumechange',\r\n 'fullscreenchange',\r\n 'error',\r\n 'ready',\r\n ],\r\n\r\n setup(props, { emit, slots, expose }) {\r\n const containerRef = ref(null);\r\n const playerRef = ref(null);\r\n const isReady = ref(false);\r\n\r\n // Provide player to child components\r\n provide(PlexPlayerKey, playerRef);\r\n\r\n onMounted(() => {\r\n if (!containerRef.value) return;\r\n\r\n // Create player instance\r\n const player = new PlexPlayer({\r\n container: containerRef.value,\r\n autoplay: props.autoplay,\r\n muted: props.muted,\r\n loop: props.loop,\r\n volume: props.volume,\r\n poster: props.poster,\r\n preload: props.preload,\r\n keyboard: props.keyboard,\r\n touch: props.touch,\r\n pip: props.pip,\r\n cast: props.cast,\r\n fullscreen: props.fullscreen,\r\n controlsHideDelay: props.controlsHideDelay,\r\n theme: props.theme,\r\n subtitles: props.subtitles,\r\n ads: props.ads,\r\n i18n: props.i18n,\r\n });\r\n\r\n playerRef.value = player;\r\n\r\n // Bind events\r\n player.on('play', () => emit('play'));\r\n player.on('pause', () => emit('pause'));\r\n player.on('ended', () => emit('ended'));\r\n player.on('timeupdate', (data) => emit('timeupdate', data.currentTime));\r\n player.on('progress', (data) => emit('progress', data.buffered));\r\n player.on('volumechange', (data) => emit('volumechange', data));\r\n player.on('fullscreenchange', (data) => emit('fullscreenchange', data.isFullscreen));\r\n player.on('error', (error) => emit('error', error));\r\n\r\n isReady.value = true;\r\n emit('ready', player);\r\n\r\n // Load initial source\r\n if (props.src) {\r\n player.load(props.src);\r\n } else if (props.playlist.length > 0) {\r\n player.loadPlaylist(props.playlist);\r\n }\r\n });\r\n\r\n onBeforeUnmount(() => {\r\n if (playerRef.value) {\r\n playerRef.value.destroy();\r\n playerRef.value = null;\r\n }\r\n });\r\n\r\n // Watch for src changes\r\n watch(() => props.src, (newSrc) => {\r\n if (playerRef.value && newSrc) {\r\n playerRef.value.load(newSrc);\r\n }\r\n });\r\n\r\n // Watch for playlist changes\r\n watch(() => props.playlist, (newPlaylist) => {\r\n if (playerRef.value && newPlaylist?.length > 0) {\r\n playerRef.value.loadPlaylist(newPlaylist);\r\n }\r\n }, { deep: true });\r\n\r\n // Watch for volume changes\r\n watch(() => props.volume, (newVolume) => {\r\n if (playerRef.value) {\r\n playerRef.value.setVolume(newVolume);\r\n }\r\n });\r\n\r\n // Watch for muted changes\r\n watch(() => props.muted, (newMuted) => {\r\n if (playerRef.value) {\r\n if (newMuted) {\r\n playerRef.value.mute();\r\n } else {\r\n playerRef.value.unmute();\r\n }\r\n }\r\n });\r\n\r\n // Expose methods\r\n expose({\r\n play: () => playerRef.value?.play(),\r\n pause: () => playerRef.value?.pause(),\r\n togglePlay: () => playerRef.value?.togglePlay(),\r\n seek: (time) => playerRef.value?.seek(time),\r\n seekPercent: (percent) => playerRef.value?.seekPercent(percent),\r\n setVolume: (vol) => playerRef.value?.setVolume(vol),\r\n getVolume: () => playerRef.value?.getVolume(),\r\n mute: () => playerRef.value?.mute(),\r\n unmute: () => playerRef.value?.unmute(),\r\n toggleMute: () => playerRef.value?.toggleMute(),\r\n setPlaybackRate: (rate) => playerRef.value?.setPlaybackRate(rate),\r\n enterFullscreen: () => playerRef.value?.enterFullscreen(),\r\n exitFullscreen: () => playerRef.value?.exitFullscreen(),\r\n toggleFullscreen: () => playerRef.value?.toggleFullscreen(),\r\n enterPiP: () => playerRef.value?.enterPiP(),\r\n exitPiP: () => playerRef.value?.exitPiP(),\r\n togglePiP: () => playerRef.value?.togglePiP(),\r\n cast: () => playerRef.value?.cast(),\r\n getState: () => playerRef.value?.getState(),\r\n getPlayer: () => playerRef.value,\r\n next: () => playerRef.value?.next(),\r\n previous: () => playerRef.value?.previous(),\r\n playAt: (index) => playerRef.value?.playAt(index),\r\n });\r\n\r\n return () => h(\r\n 'div',\r\n {\r\n ref: containerRef,\r\n class: 'plex-player-container',\r\n style: {\r\n width: '100%',\r\n height: '100%',\r\n position: 'relative',\r\n },\r\n },\r\n slots.default?.()\r\n );\r\n },\r\n});\r\n\r\n// Composables\r\nexport function usePlexPlayerState() {\r\n const player = usePlexPlayer();\r\n const state = ref(null);\r\n\r\n watch(player, (p) => {\r\n if (!p) return;\r\n\r\n const updateState = () => {\r\n state.value = p.getState();\r\n };\r\n\r\n p.on('timeupdate', updateState);\r\n p.on('play', updateState);\r\n p.on('pause', updateState);\r\n p.on('volumechange', updateState);\r\n\r\n updateState();\r\n }, { immediate: true });\r\n\r\n return state;\r\n}\r\n\r\nexport function usePlexPlayerTime() {\r\n const player = usePlexPlayer();\r\n const time = ref({ current: 0, duration: 0 });\r\n\r\n watch(player, (p) => {\r\n if (!p) return;\r\n\r\n p.on('timeupdate', (data) => {\r\n time.value = {\r\n current: data.currentTime,\r\n duration: data.duration,\r\n };\r\n });\r\n }, { immediate: true });\r\n\r\n return time;\r\n}\r\n\r\n// Named exports\r\nexport { PlexPlayer };\r\nexport default PlexPlayerVue;\r\n"],"names":["PlexPlayerKey","Symbol","usePlexPlayer","inject","ref","PlexPlayerVue","defineComponent","name","props","src","type","String","default","playlist","Array","autoplay","Boolean","muted","loop","volume","Number","poster","preload","keyboard","touch","pip","cast","fullscreen","controlsHideDelay","theme","Object","subtitles","ads","i18n","emits","setup","emit","slots","expose","containerRef","playerRef","isReady","provide","onMounted","value","player","PlexPlayer","container","on","data","currentTime","buffered","isFullscreen","error","load","length","loadPlaylist","onBeforeUnmount","destroy","watch","newSrc","newPlaylist","deep","newVolume","setVolume","newMuted","mute","unmute","play","pause","togglePlay","seek","time","seekPercent","percent","vol","getVolume","toggleMute","setPlaybackRate","rate","enterFullscreen","exitFullscreen","toggleFullscreen","enterPiP","exitPiP","togglePiP","getState","getPlayer","next","previous","playAt","index","h","class","style","width","height","position","usePlexPlayerState","state","p","updateState","immediate","usePlexPlayerTime","current","duration"],"mappings":";;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;;;AAgBA;AACA,MAAMA,aAAa,GAAGC,MAAM,CAAC,YAAY,CAAC;;AAE1C;AACA;AACA;AACO,SAASC,aAAaA,GAAG;EAC9B,OAAOC,UAAM,CAACH,aAAa,EAAEI,OAAG,CAAC,IAAI,CAAC,CAAC;AACzC;;AAEA;AACA;AACA;AACO,MAAMC,aAAa,GAAGC,mBAAe,CAAC;AAC3CC,EAAAA,IAAI,EAAE,YAAY;AAElBC,EAAAA,KAAK,EAAE;AACLC,IAAAA,GAAG,EAAE;AACHC,MAAAA,IAAI,EAAEC,MAAM;AACZC,MAAAA,OAAO,EAAE;KACV;AACDC,IAAAA,QAAQ,EAAE;AACRH,MAAAA,IAAI,EAAEI,KAAK;MACXF,OAAO,EAAEA,MAAM;KAChB;AACDG,IAAAA,QAAQ,EAAE;AACRL,MAAAA,IAAI,EAAEM,OAAO;AACbJ,MAAAA,OAAO,EAAE;KACV;AACDK,IAAAA,KAAK,EAAE;AACLP,MAAAA,IAAI,EAAEM,OAAO;AACbJ,MAAAA,OAAO,EAAE;KACV;AACDM,IAAAA,IAAI,EAAE;AACJR,MAAAA,IAAI,EAAEM,OAAO;AACbJ,MAAAA,OAAO,EAAE;KACV;AACDO,IAAAA,MAAM,EAAE;AACNT,MAAAA,IAAI,EAAEU,MAAM;AACZR,MAAAA,OAAO,EAAE;KACV;AACDS,IAAAA,MAAM,EAAE;AACNX,MAAAA,IAAI,EAAEC,MAAM;AACZC,MAAAA,OAAO,EAAE;KACV;AACDU,IAAAA,OAAO,EAAE;AACPZ,MAAAA,IAAI,EAAEC,MAAM;AACZC,MAAAA,OAAO,EAAE;KACV;AACDW,IAAAA,QAAQ,EAAE;AACRb,MAAAA,IAAI,EAAEM,OAAO;AACbJ,MAAAA,OAAO,EAAE;KACV;AACDY,IAAAA,KAAK,EAAE;AACLd,MAAAA,IAAI,EAAEM,OAAO;AACbJ,MAAAA,OAAO,EAAE;KACV;AACDa,IAAAA,GAAG,EAAE;AACHf,MAAAA,IAAI,EAAEM,OAAO;AACbJ,MAAAA,OAAO,EAAE;KACV;AACDc,IAAAA,IAAI,EAAE;AACJhB,MAAAA,IAAI,EAAEM,OAAO;AACbJ,MAAAA,OAAO,EAAE;KACV;AACDe,IAAAA,UAAU,EAAE;AACVjB,MAAAA,IAAI,EAAEM,OAAO;AACbJ,MAAAA,OAAO,EAAE;KACV;AACDgB,IAAAA,iBAAiB,EAAE;AACjBlB,MAAAA,IAAI,EAAEU,MAAM;AACZR,MAAAA,OAAO,EAAE;KACV;AACDiB,IAAAA,KAAK,EAAE;AACLnB,MAAAA,IAAI,EAAEoB,MAAM;AACZlB,MAAAA,OAAO,EAAEA,OAAO,EAAE;KACnB;AACDmB,IAAAA,SAAS,EAAE;AACTrB,MAAAA,IAAI,EAAEoB,MAAM;AACZlB,MAAAA,OAAO,EAAEA,OAAO,EAAE;KACnB;AACDoB,IAAAA,GAAG,EAAE;AACHtB,MAAAA,IAAI,EAAEoB,MAAM;AACZlB,MAAAA,OAAO,EAAEA,OAAO,EAAE;KACnB;AACDqB,IAAAA,IAAI,EAAE;AACJvB,MAAAA,IAAI,EAAEoB,MAAM;AACZlB,MAAAA,OAAO,EAAEA,OAAO,EAAE;AACpB;GACD;AAEDsB,EAAAA,KAAK,EAAE,CACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,YAAY,EACZ,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,OAAO,EACP,OAAO,CACR;EAEDC,KAAKA,CAAC3B,KAAK,EAAE;IAAE4B,IAAI;IAAEC,KAAK;AAAEC,IAAAA;AAAO,GAAC,EAAE;AACpC,IAAA,MAAMC,YAAY,GAAGnC,OAAG,CAAC,IAAI,CAAC;AAC9B,IAAA,MAAMoC,SAAS,GAAGpC,OAAG,CAAC,IAAI,CAAC;AAC3B,IAAA,MAAMqC,OAAO,GAAGrC,OAAG,CAAC,KAAK,CAAC;;AAE1B;AACAsC,IAAAA,WAAO,CAAC1C,aAAa,EAAEwC,SAAS,CAAC;AAEjCG,IAAAA,aAAS,CAAC,MAAM;AACd,MAAA,IAAI,CAACJ,YAAY,CAACK,KAAK,EAAE;;AAEzB;AACA,MAAA,MAAMC,MAAM,GAAG,IAAIC,UAAU,CAAC;QAC5BC,SAAS,EAAER,YAAY,CAACK,KAAK;QAC7B7B,QAAQ,EAAEP,KAAK,CAACO,QAAQ;QACxBE,KAAK,EAAET,KAAK,CAACS,KAAK;QAClBC,IAAI,EAAEV,KAAK,CAACU,IAAI;QAChBC,MAAM,EAAEX,KAAK,CAACW,MAAM;QACpBE,MAAM,EAAEb,KAAK,CAACa,MAAM;QACpBC,OAAO,EAAEd,KAAK,CAACc,OAAO;QACtBC,QAAQ,EAAEf,KAAK,CAACe,QAAQ;QACxBC,KAAK,EAAEhB,KAAK,CAACgB,KAAK;QAClBC,GAAG,EAAEjB,KAAK,CAACiB,GAAG;QACdC,IAAI,EAAElB,KAAK,CAACkB,IAAI;QAChBC,UAAU,EAAEnB,KAAK,CAACmB,UAAU;QAC5BC,iBAAiB,EAAEpB,KAAK,CAACoB,iBAAiB;QAC1CC,KAAK,EAAErB,KAAK,CAACqB,KAAK;QAClBE,SAAS,EAAEvB,KAAK,CAACuB,SAAS;QAC1BC,GAAG,EAAExB,KAAK,CAACwB,GAAG;QACdC,IAAI,EAAEzB,KAAK,CAACyB;AACd,OAAC,CAAC;MAEFO,SAAS,CAACI,KAAK,GAAGC,MAAM;;AAExB;MACAA,MAAM,CAACG,EAAE,CAAC,MAAM,EAAE,MAAMZ,IAAI,CAAC,MAAM,CAAC,CAAC;MACrCS,MAAM,CAACG,EAAE,CAAC,OAAO,EAAE,MAAMZ,IAAI,CAAC,OAAO,CAAC,CAAC;MACvCS,MAAM,CAACG,EAAE,CAAC,OAAO,EAAE,MAAMZ,IAAI,CAAC,OAAO,CAAC,CAAC;AACvCS,MAAAA,MAAM,CAACG,EAAE,CAAC,YAAY,EAAGC,IAAI,IAAKb,IAAI,CAAC,YAAY,EAAEa,IAAI,CAACC,WAAW,CAAC,CAAC;AACvEL,MAAAA,MAAM,CAACG,EAAE,CAAC,UAAU,EAAGC,IAAI,IAAKb,IAAI,CAAC,UAAU,EAAEa,IAAI,CAACE,QAAQ,CAAC,CAAC;AAChEN,MAAAA,MAAM,CAACG,EAAE,CAAC,cAAc,EAAGC,IAAI,IAAKb,IAAI,CAAC,cAAc,EAAEa,IAAI,CAAC,CAAC;AAC/DJ,MAAAA,MAAM,CAACG,EAAE,CAAC,kBAAkB,EAAGC,IAAI,IAAKb,IAAI,CAAC,kBAAkB,EAAEa,IAAI,CAACG,YAAY,CAAC,CAAC;AACpFP,MAAAA,MAAM,CAACG,EAAE,CAAC,OAAO,EAAGK,KAAK,IAAKjB,IAAI,CAAC,OAAO,EAAEiB,KAAK,CAAC,CAAC;MAEnDZ,OAAO,CAACG,KAAK,GAAG,IAAI;AACpBR,MAAAA,IAAI,CAAC,OAAO,EAAES,MAAM,CAAC;;AAErB;MACA,IAAIrC,KAAK,CAACC,GAAG,EAAE;AACboC,QAAAA,MAAM,CAACS,IAAI,CAAC9C,KAAK,CAACC,GAAG,CAAC;MACxB,CAAC,MAAM,IAAID,KAAK,CAACK,QAAQ,CAAC0C,MAAM,GAAG,CAAC,EAAE;AACpCV,QAAAA,MAAM,CAACW,YAAY,CAAChD,KAAK,CAACK,QAAQ,CAAC;AACrC,MAAA;AACF,IAAA,CAAC,CAAC;AAEF4C,IAAAA,mBAAe,CAAC,MAAM;MACpB,IAAIjB,SAAS,CAACI,KAAK,EAAE;AACnBJ,QAAAA,SAAS,CAACI,KAAK,CAACc,OAAO,EAAE;QACzBlB,SAAS,CAACI,KAAK,GAAG,IAAI;AACxB,MAAA;AACF,IAAA,CAAC,CAAC;;AAEF;AACAe,IAAAA,SAAK,CAAC,MAAMnD,KAAK,CAACC,GAAG,EAAGmD,MAAM,IAAK;AACjC,MAAA,IAAIpB,SAAS,CAACI,KAAK,IAAIgB,MAAM,EAAE;AAC7BpB,QAAAA,SAAS,CAACI,KAAK,CAACU,IAAI,CAACM,MAAM,CAAC;AAC9B,MAAA;AACF,IAAA,CAAC,CAAC;;AAEF;AACAD,IAAAA,SAAK,CAAC,MAAMnD,KAAK,CAACK,QAAQ,EAAGgD,WAAW,IAAK;MAC3C,IAAIrB,SAAS,CAACI,KAAK,IAAIiB,WAAW,EAAEN,MAAM,GAAG,CAAC,EAAE;AAC9Cf,QAAAA,SAAS,CAACI,KAAK,CAACY,YAAY,CAACK,WAAW,CAAC;AAC3C,MAAA;AACF,IAAA,CAAC,EAAE;AAAEC,MAAAA,IAAI,EAAE;AAAK,KAAC,CAAC;;AAElB;AACAH,IAAAA,SAAK,CAAC,MAAMnD,KAAK,CAACW,MAAM,EAAG4C,SAAS,IAAK;MACvC,IAAIvB,SAAS,CAACI,KAAK,EAAE;AACnBJ,QAAAA,SAAS,CAACI,KAAK,CAACoB,SAAS,CAACD,SAAS,CAAC;AACtC,MAAA;AACF,IAAA,CAAC,CAAC;;AAEF;AACAJ,IAAAA,SAAK,CAAC,MAAMnD,KAAK,CAACS,KAAK,EAAGgD,QAAQ,IAAK;MACrC,IAAIzB,SAAS,CAACI,KAAK,EAAE;AACnB,QAAA,IAAIqB,QAAQ,EAAE;AACZzB,UAAAA,SAAS,CAACI,KAAK,CAACsB,IAAI,EAAE;AACxB,QAAA,CAAC,MAAM;AACL1B,UAAAA,SAAS,CAACI,KAAK,CAACuB,MAAM,EAAE;AAC1B,QAAA;AACF,MAAA;AACF,IAAA,CAAC,CAAC;;AAEF;AACA7B,IAAAA,MAAM,CAAC;MACL8B,IAAI,EAAEA,MAAM5B,SAAS,CAACI,KAAK,EAAEwB,IAAI,EAAE;MACnCC,KAAK,EAAEA,MAAM7B,SAAS,CAACI,KAAK,EAAEyB,KAAK,EAAE;MACrCC,UAAU,EAAEA,MAAM9B,SAAS,CAACI,KAAK,EAAE0B,UAAU,EAAE;MAC/CC,IAAI,EAAGC,IAAI,IAAKhC,SAAS,CAACI,KAAK,EAAE2B,IAAI,CAACC,IAAI,CAAC;MAC3CC,WAAW,EAAGC,OAAO,IAAKlC,SAAS,CAACI,KAAK,EAAE6B,WAAW,CAACC,OAAO,CAAC;MAC/DV,SAAS,EAAGW,GAAG,IAAKnC,SAAS,CAACI,KAAK,EAAEoB,SAAS,CAACW,GAAG,CAAC;MACnDC,SAAS,EAAEA,MAAMpC,SAAS,CAACI,KAAK,EAAEgC,SAAS,EAAE;MAC7CV,IAAI,EAAEA,MAAM1B,SAAS,CAACI,KAAK,EAAEsB,IAAI,EAAE;MACnCC,MAAM,EAAEA,MAAM3B,SAAS,CAACI,KAAK,EAAEuB,MAAM,EAAE;MACvCU,UAAU,EAAEA,MAAMrC,SAAS,CAACI,KAAK,EAAEiC,UAAU,EAAE;MAC/CC,eAAe,EAAGC,IAAI,IAAKvC,SAAS,CAACI,KAAK,EAAEkC,eAAe,CAACC,IAAI,CAAC;MACjEC,eAAe,EAAEA,MAAMxC,SAAS,CAACI,KAAK,EAAEoC,eAAe,EAAE;MACzDC,cAAc,EAAEA,MAAMzC,SAAS,CAACI,KAAK,EAAEqC,cAAc,EAAE;MACvDC,gBAAgB,EAAEA,MAAM1C,SAAS,CAACI,KAAK,EAAEsC,gBAAgB,EAAE;MAC3DC,QAAQ,EAAEA,MAAM3C,SAAS,CAACI,KAAK,EAAEuC,QAAQ,EAAE;MAC3CC,OAAO,EAAEA,MAAM5C,SAAS,CAACI,KAAK,EAAEwC,OAAO,EAAE;MACzCC,SAAS,EAAEA,MAAM7C,SAAS,CAACI,KAAK,EAAEyC,SAAS,EAAE;MAC7C3D,IAAI,EAAEA,MAAMc,SAAS,CAACI,KAAK,EAAElB,IAAI,EAAE;MACnC4D,QAAQ,EAAEA,MAAM9C,SAAS,CAACI,KAAK,EAAE0C,QAAQ,EAAE;AAC3CC,MAAAA,SAAS,EAAEA,MAAM/C,SAAS,CAACI,KAAK;MAChC4C,IAAI,EAAEA,MAAMhD,SAAS,CAACI,KAAK,EAAE4C,IAAI,EAAE;MACnCC,QAAQ,EAAEA,MAAMjD,SAAS,CAACI,KAAK,EAAE6C,QAAQ,EAAE;MAC3CC,MAAM,EAAGC,KAAK,IAAKnD,SAAS,CAACI,KAAK,EAAE8C,MAAM,CAACC,KAAK;AAClD,KAAC,CAAC;AAEF,IAAA,OAAO,MAAMC,KAAC,CACZ,KAAK,EACL;AACExF,MAAAA,GAAG,EAAEmC,YAAY;AACjBsD,MAAAA,KAAK,EAAE,uBAAuB;AAC9BC,MAAAA,KAAK,EAAE;AACLC,QAAAA,KAAK,EAAE,MAAM;AACbC,QAAAA,MAAM,EAAE,MAAM;AACdC,QAAAA,QAAQ,EAAE;AACZ;AACF,KAAC,EACD5D,KAAK,CAACzB,OAAO,IACf,CAAC;AACH,EAAA;AACF,CAAC;;AAED;AACO,SAASsF,kBAAkBA,GAAG;AACnC,EAAA,MAAMrD,MAAM,GAAG3C,aAAa,EAAE;AAC9B,EAAA,MAAMiG,KAAK,GAAG/F,OAAG,CAAC,IAAI,CAAC;AAEvBuD,EAAAA,SAAK,CAACd,MAAM,EAAGuD,CAAC,IAAK;IACnB,IAAI,CAACA,CAAC,EAAE;IAER,MAAMC,WAAW,GAAGA,MAAM;AACxBF,MAAAA,KAAK,CAACvD,KAAK,GAAGwD,CAAC,CAACd,QAAQ,EAAE;IAC5B,CAAC;AAEDc,IAAAA,CAAC,CAACpD,EAAE,CAAC,YAAY,EAAEqD,WAAW,CAAC;AAC/BD,IAAAA,CAAC,CAACpD,EAAE,CAAC,MAAM,EAAEqD,WAAW,CAAC;AACzBD,IAAAA,CAAC,CAACpD,EAAE,CAAC,OAAO,EAAEqD,WAAW,CAAC;AAC1BD,IAAAA,CAAC,CAACpD,EAAE,CAAC,cAAc,EAAEqD,WAAW,CAAC;AAEjCA,IAAAA,WAAW,EAAE;AACf,EAAA,CAAC,EAAE;AAAEC,IAAAA,SAAS,EAAE;AAAK,GAAC,CAAC;AAEvB,EAAA,OAAOH,KAAK;AACd;AAEO,SAASI,iBAAiBA,GAAG;AAClC,EAAA,MAAM1D,MAAM,GAAG3C,aAAa,EAAE;EAC9B,MAAMsE,IAAI,GAAGpE,OAAG,CAAC;AAAEoG,IAAAA,OAAO,EAAE,CAAC;AAAEC,IAAAA,QAAQ,EAAE;AAAE,GAAC,CAAC;AAE7C9C,EAAAA,SAAK,CAACd,MAAM,EAAGuD,CAAC,IAAK;IACnB,IAAI,CAACA,CAAC,EAAE;AAERA,IAAAA,CAAC,CAACpD,EAAE,CAAC,YAAY,EAAGC,IAAI,IAAK;MAC3BuB,IAAI,CAAC5B,KAAK,GAAG;QACX4D,OAAO,EAAEvD,IAAI,CAACC,WAAW;QACzBuD,QAAQ,EAAExD,IAAI,CAACwD;OAChB;AACH,IAAA,CAAC,CAAC;AACJ,EAAA,CAAC,EAAE;AAAEH,IAAAA,SAAS,EAAE;AAAK,GAAC,CAAC;AAEvB,EAAA,OAAO9B,IAAI;AACb;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/vue/index.js"],"sourcesContent":["/**\r\n * @frameset/plex-player - Vue Component\r\n * Professional Video Player by FRAMESET Studio\r\n * https://frameset.dev\r\n */\r\n\r\nimport { \r\n defineComponent, \r\n ref, \r\n onMounted, \r\n onBeforeUnmount, \r\n watch,\r\n provide,\r\n inject,\r\n h\r\n} from 'vue';\r\n\r\n// Import core player\r\nimport PlexPlayer from '../core/index.js';\r\n\r\n// Provide/inject key\r\nconst PlexPlayerKey = Symbol('PlexPlayer');\r\n\r\n/**\r\n * Composable to access player instance\r\n */\r\nexport function usePlexPlayer() {\r\n return inject(PlexPlayerKey, ref(null));\r\n}\r\n\r\n/**\r\n * PlexPlayer Vue Component\r\n */\r\nexport const PlexPlayerVue = defineComponent({\r\n name: 'PlexPlayer',\r\n\r\n props: {\r\n src: {\r\n type: String,\r\n default: '',\r\n },\r\n playlist: {\r\n type: Array,\r\n default: () => [],\r\n },\r\n autoplay: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n muted: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n loop: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n volume: {\r\n type: Number,\r\n default: 1,\r\n },\r\n poster: {\r\n type: String,\r\n default: '',\r\n },\r\n preload: {\r\n type: String,\r\n default: 'metadata',\r\n },\r\n keyboard: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n touch: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n pip: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n cast: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n fullscreen: {\r\n type: Boolean,\r\n default: true,\r\n },\r\n controlsHideDelay: {\r\n type: Number,\r\n default: 3000,\r\n },\r\n theme: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n subtitles: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n ads: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n i18n: {\r\n type: Object,\r\n default: () => ({}),\r\n },\r\n },\r\n\r\n emits: [\r\n 'play',\r\n 'pause',\r\n 'ended',\r\n 'timeupdate',\r\n 'progress',\r\n 'volumechange',\r\n 'fullscreenchange',\r\n 'error',\r\n 'ready',\r\n ],\r\n\r\n setup(props, { emit, slots, expose }) {\r\n const containerRef = ref(null);\r\n const playerRef = ref(null);\r\n const isReady = ref(false);\r\n\r\n // Provide player to child components\r\n provide(PlexPlayerKey, playerRef);\r\n\r\n onMounted(() => {\r\n if (!containerRef.value) return;\r\n\r\n // Create player instance\r\n const player = new PlexPlayer({\r\n container: containerRef.value,\r\n autoplay: props.autoplay,\r\n muted: props.muted,\r\n loop: props.loop,\r\n volume: props.volume,\r\n poster: props.poster,\r\n preload: props.preload,\r\n keyboard: props.keyboard,\r\n touch: props.touch,\r\n pip: props.pip,\r\n cast: props.cast,\r\n fullscreen: props.fullscreen,\r\n controlsHideDelay: props.controlsHideDelay,\r\n theme: props.theme,\r\n subtitles: props.subtitles,\r\n ads: props.ads,\r\n i18n: props.i18n,\r\n });\r\n\r\n playerRef.value = player;\r\n\r\n // Bind events\r\n player.on('play', () => emit('play'));\r\n player.on('pause', () => emit('pause'));\r\n player.on('ended', () => emit('ended'));\r\n player.on('timeupdate', (data) => emit('timeupdate', data.currentTime));\r\n player.on('progress', (data) => emit('progress', data.buffered));\r\n player.on('volumechange', (data) => emit('volumechange', data));\r\n player.on('fullscreenchange', (data) => emit('fullscreenchange', data.isFullscreen));\r\n player.on('error', (error) => emit('error', error));\r\n\r\n isReady.value = true;\r\n emit('ready', player);\r\n\r\n // Load initial source\r\n if (props.src) {\r\n player.load(props.src);\r\n } else if (props.playlist.length > 0) {\r\n player.loadPlaylist(props.playlist);\r\n }\r\n });\r\n\r\n onBeforeUnmount(() => {\r\n if (playerRef.value) {\r\n playerRef.value.destroy();\r\n playerRef.value = null;\r\n }\r\n });\r\n\r\n // Watch for src changes\r\n watch(() => props.src, (newSrc) => {\r\n if (playerRef.value && newSrc) {\r\n playerRef.value.load(newSrc);\r\n }\r\n });\r\n\r\n // Watch for playlist changes\r\n watch(() => props.playlist, (newPlaylist) => {\r\n if (playerRef.value && newPlaylist?.length > 0) {\r\n playerRef.value.loadPlaylist(newPlaylist);\r\n }\r\n }, { deep: true });\r\n\r\n // Watch for volume changes\r\n watch(() => props.volume, (newVolume) => {\r\n if (playerRef.value) {\r\n playerRef.value.setVolume(newVolume);\r\n }\r\n });\r\n\r\n // Watch for muted changes\r\n watch(() => props.muted, (newMuted) => {\r\n if (playerRef.value) {\r\n if (newMuted) {\r\n playerRef.value.mute();\r\n } else {\r\n playerRef.value.unmute();\r\n }\r\n }\r\n });\r\n\r\n // Expose methods\r\n expose({\r\n play: () => playerRef.value?.play(),\r\n pause: () => playerRef.value?.pause(),\r\n togglePlay: () => playerRef.value?.togglePlay(),\r\n seek: (time) => playerRef.value?.seek(time),\r\n seekPercent: (percent) => playerRef.value?.seekPercent(percent),\r\n setVolume: (vol) => playerRef.value?.setVolume(vol),\r\n getVolume: () => playerRef.value?.getVolume(),\r\n mute: () => playerRef.value?.mute(),\r\n unmute: () => playerRef.value?.unmute(),\r\n toggleMute: () => playerRef.value?.toggleMute(),\r\n setPlaybackRate: (rate) => playerRef.value?.setPlaybackRate(rate),\r\n enterFullscreen: () => playerRef.value?.enterFullscreen(),\r\n exitFullscreen: () => playerRef.value?.exitFullscreen(),\r\n toggleFullscreen: () => playerRef.value?.toggleFullscreen(),\r\n enterPiP: () => playerRef.value?.enterPiP(),\r\n exitPiP: () => playerRef.value?.exitPiP(),\r\n togglePiP: () => playerRef.value?.togglePiP(),\r\n cast: () => playerRef.value?.cast(),\r\n getState: () => playerRef.value?.getState(),\r\n getPlayer: () => playerRef.value,\r\n next: () => playerRef.value?.next(),\r\n previous: () => playerRef.value?.previous(),\r\n playAt: (index) => playerRef.value?.playAt(index),\r\n });\r\n\r\n return () => h(\r\n 'div',\r\n {\r\n ref: containerRef,\r\n class: 'plex-player-container',\r\n style: {\r\n width: '100%',\r\n aspectRatio: '16 / 9',\r\n position: 'relative',\r\n },\r\n },\r\n slots.default?.()\r\n );\r\n },\r\n});\r\n\r\n// Composables\r\nexport function usePlexPlayerState() {\r\n const player = usePlexPlayer();\r\n const state = ref(null);\r\n\r\n watch(player, (p) => {\r\n if (!p) return;\r\n\r\n const updateState = () => {\r\n state.value = p.getState();\r\n };\r\n\r\n p.on('timeupdate', updateState);\r\n p.on('play', updateState);\r\n p.on('pause', updateState);\r\n p.on('volumechange', updateState);\r\n\r\n updateState();\r\n }, { immediate: true });\r\n\r\n return state;\r\n}\r\n\r\nexport function usePlexPlayerTime() {\r\n const player = usePlexPlayer();\r\n const time = ref({ current: 0, duration: 0 });\r\n\r\n watch(player, (p) => {\r\n if (!p) return;\r\n\r\n p.on('timeupdate', (data) => {\r\n time.value = {\r\n current: data.currentTime,\r\n duration: data.duration,\r\n };\r\n });\r\n }, { immediate: true });\r\n\r\n return time;\r\n}\r\n\r\n// Named exports\r\nexport { PlexPlayer };\r\nexport default PlexPlayerVue;\r\n"],"names":["PlexPlayerKey","Symbol","usePlexPlayer","inject","ref","PlexPlayerVue","defineComponent","name","props","src","type","String","default","playlist","Array","autoplay","Boolean","muted","loop","volume","Number","poster","preload","keyboard","touch","pip","cast","fullscreen","controlsHideDelay","theme","Object","subtitles","ads","i18n","emits","setup","emit","slots","expose","containerRef","playerRef","isReady","provide","onMounted","value","player","PlexPlayer","container","on","data","currentTime","buffered","isFullscreen","error","load","length","loadPlaylist","onBeforeUnmount","destroy","watch","newSrc","newPlaylist","deep","newVolume","setVolume","newMuted","mute","unmute","play","pause","togglePlay","seek","time","seekPercent","percent","vol","getVolume","toggleMute","setPlaybackRate","rate","enterFullscreen","exitFullscreen","toggleFullscreen","enterPiP","exitPiP","togglePiP","getState","getPlayer","next","previous","playAt","index","h","class","style","width","aspectRatio","position","usePlexPlayerState","state","p","updateState","immediate","usePlexPlayerTime","current","duration"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frameset/plex-player",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "type": "module",
5
5
  "description": "Professional video player with VAST ads, Chromecast, PiP, subtitles, playlists and more. Built by FRAMESET Studio.",
6
6
  "main": "dist/plex-player.cjs.js",
@@ -202,7 +202,7 @@ export const PlexPlayerReact = forwardRef(function PlexPlayerReact(props, ref) {
202
202
  className={`plex-player-container ${className}`}
203
203
  style={{
204
204
  width: '100%',
205
- height: '100%',
205
+ aspectRatio: '16 / 9',
206
206
  position: 'relative',
207
207
  ...style,
208
208
  }}
package/src/vue/index.js CHANGED
@@ -249,7 +249,7 @@ export const PlexPlayerVue = defineComponent({
249
249
  class: 'plex-player-container',
250
250
  style: {
251
251
  width: '100%',
252
- height: '100%',
252
+ aspectRatio: '16 / 9',
253
253
  position: 'relative',
254
254
  },
255
255
  },