@tiwz/react-video-player 2.0.4 → 2.0.6
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.
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @tiwz/react-video-player
|
|
2
2
|
|
|
3
|
-
A modern, fully-featured, and mobile-friendly React video player component with custom controls, double-tap seek, keyboard shortcuts, fullscreen, Picture-in-Picture (PiP), and smooth UX — built for both desktop and mobile.
|
|
3
|
+
A modern, fully-featured, and mobile-friendly React video player component with custom controls, double-tap seek, keyboard shortcuts, fullscreen, Picture-in-Picture (PiP), subtitles, and smooth UX — built for both desktop and mobile.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -15,6 +15,7 @@ A modern, fully-featured, and mobile-friendly React video player component with
|
|
|
15
15
|
- ⚡ Playback speed control (0.25x – 4x)
|
|
16
16
|
- 📡 HLS streaming support (built-in, no extra install needed)
|
|
17
17
|
- 🕒 Seek bar with buffered progress indicator
|
|
18
|
+
- 💬 Subtitle / caption support (VTT format)
|
|
18
19
|
- 🚀 Smooth UX with throttled interactions
|
|
19
20
|
- 💡 Auto-hide controls on inactivity
|
|
20
21
|
- 🧭 Landscape lock on fullscreen (mobile)
|
|
@@ -68,6 +69,7 @@ export default function App() {
|
|
|
68
69
|
| `title` | `string` | ❌ | Video title shown in top bar |
|
|
69
70
|
| `poster` | `string` | ❌ | Thumbnail image shown before playback |
|
|
70
71
|
| `hls` | `boolean \| Partial<HlsConfig>` | ❌ | Enable HLS streaming |
|
|
72
|
+
| `track` | `VideoTrack` | ❌ | Subtitle / caption track (VTT format) |
|
|
71
73
|
|
|
72
74
|
### VideoSourceQuality
|
|
73
75
|
|
|
@@ -78,6 +80,15 @@ type VideoSourceQuality = {
|
|
|
78
80
|
}
|
|
79
81
|
```
|
|
80
82
|
|
|
83
|
+
### VideoTrack
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
type VideoTrack = {
|
|
87
|
+
src: string // URL to .vtt subtitle file
|
|
88
|
+
lang: string // BCP 47 language tag, e.g. 'en', 'th'
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
81
92
|
**Example with multiple qualities:**
|
|
82
93
|
|
|
83
94
|
```tsx
|
|
@@ -97,6 +108,24 @@ type VideoSourceQuality = {
|
|
|
97
108
|
|
|
98
109
|
---
|
|
99
110
|
|
|
111
|
+
## 💬 Subtitles
|
|
112
|
+
|
|
113
|
+
Subtitle support uses the WebVTT format. Pass a `track` prop with the URL to your `.vtt` file and the language code.
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
<VideoPlayer
|
|
117
|
+
title="My Video"
|
|
118
|
+
source="/video.mp4"
|
|
119
|
+
track={{ src: '/subtitles-en.vtt', lang: 'en' }}
|
|
120
|
+
/>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Users can toggle subtitles on/off from the **Settings** panel in the player. Subtitles are displayed as an overlay above the controls, and will float up when the control bar is visible.
|
|
124
|
+
|
|
125
|
+
> **Note:** The `.vtt` file must be served from the same origin or with CORS headers to be loaded correctly by the browser.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
100
129
|
## 📡 HLS Streaming
|
|
101
130
|
|
|
102
131
|
HLS support is built-in — no extra packages needed.
|
|
@@ -145,6 +174,18 @@ HLS support is built-in — no extra packages needed.
|
|
|
145
174
|
|
|
146
175
|
---
|
|
147
176
|
|
|
177
|
+
## ⚙️ Settings Panel
|
|
178
|
+
|
|
179
|
+
The gear icon opens the settings panel with the following options:
|
|
180
|
+
|
|
181
|
+
| Setting | Description |
|
|
182
|
+
|---------|-------------|
|
|
183
|
+
| **Video quality** | Switch between available quality levels (shown only when multiple sources are provided) |
|
|
184
|
+
| **Playback speed** | Adjust speed from 0.25x to 4x |
|
|
185
|
+
| **Subtitle** | Toggle subtitles on/off (shown only when a `track` is provided) |
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
148
189
|
## 🖥 Fullscreen
|
|
149
190
|
|
|
150
191
|
Supports all modern browsers including:
|
|
@@ -180,14 +221,14 @@ Works on:
|
|
|
180
221
|
|
|
181
222
|
## 🧪 Browser Support
|
|
182
223
|
|
|
183
|
-
| Browser | Fullscreen | PiP | HLS | Orientation Lock |
|
|
184
|
-
|
|
185
|
-
| Chrome | ✅ | ✅ | ✅ | ✅ |
|
|
186
|
-
| Edge | ✅ | ✅ | ✅ | ✅ |
|
|
187
|
-
| Firefox | ✅ | ✅ | ✅ | ⚠️ Partial |
|
|
188
|
-
| Safari (desktop) | ✅ | ✅ | ✅ (native) | — |
|
|
189
|
-
| Mobile Safari | ✅ | ✅ (iPadOS) | ✅ (native) | ✅ |
|
|
190
|
-
| Chrome Android | ✅ | ✅ | ✅ | ✅ |
|
|
224
|
+
| Browser | Fullscreen | PiP | HLS | Subtitles | Orientation Lock |
|
|
225
|
+
|---------|-----------|-----|-----|-----------|-----------------|
|
|
226
|
+
| Chrome | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
227
|
+
| Edge | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
228
|
+
| Firefox | ✅ | ✅ | ✅ | ✅ | ⚠️ Partial |
|
|
229
|
+
| Safari (desktop) | ✅ | ✅ | ✅ (native) | ✅ | — |
|
|
230
|
+
| Mobile Safari | ✅ | ✅ (iPadOS) | ✅ (native) | ✅ | ✅ |
|
|
231
|
+
| Chrome Android | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
191
232
|
|
|
192
233
|
---
|
|
193
234
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@font-face{font-display:swap;font-family:ReactVideoPlayerFontFamily;font-style:normal;font-weight:
|
|
1
|
+
@font-face{font-display:swap;font-family:ReactVideoPlayerFontFamily;font-style:normal;font-weight:300;src:url(fonts/Kodchasan.woff2) format("woff2")}.style-module_PlayerButton__3pLMQ{align-items:center;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;border-radius:5px;display:flex;height:30px;justify-content:center;transition:background-color .2s;width:30px}.style-module_PlayerDesktop__ccJTe .style-module_PlayerButton__3pLMQ:hover{background-color:#00b2ff;cursor:pointer}.style-module_PlayerWrapper__37Xpc,.style-module_PlayerWrapper__37Xpc *,.style-module_PlayerWrapper__37Xpc :after,.style-module_PlayerWrapper__37Xpc :before{box-sizing:border-box;color:#fff;font-family:ReactVideoPlayerFontFamily,sans-serif;font-optical-sizing:auto;font-style:normal;font-variation-settings:"wdth" 100,"YTLC" 500;font-weight:300;margin:0;padding:0}.style-module_PlayerWrapper__37Xpc{align-items:center;aspect-ratio:16/9;background-color:#000;cursor:none;display:flex;justify-content:center;position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%}.style-module_PlayerVideo__NkoX3{height:100%;max-height:100%;max-width:100%;width:100%}.style-module_PlayerControls__IyMmM{background-color:#0000;display:flex;flex-direction:column;height:100%;left:0;opacity:0;position:absolute;top:0;transition:background-color .4s ease;visibility:hidden;width:100%}.style-module_PlayerControls__IyMmM.style-module_PlayerShown__uVIfu{background-color:#0006;cursor:default;opacity:1;visibility:visible}.style-module_PlayerPanelTop__x02Dp{align-items:center;display:flex;height:50px;padding-inline:14px}.style-module_PlayerTitle__yTvNu{flex:1;font-size:12pt;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.style-module_PlayerPanelCenter__y8jR0{display:flex;flex:1}.style-module_PlayerSeekArea__z-qY-{align-items:center;display:flex;flex:1;height:100%;justify-content:center}.style-module_PlayerPanelBottom__bdhhD{align-items:center;display:flex;gap:10px;height:50px;padding-inline:14px;position:relative}.style-module_PlayerCurrentTime__IaolO,.style-module_PlayerDurationTime__uCgjW{font-family:monospace;font-size:13pt;padding-inline:4px}.style-module_PlayerVolume__r7ll8{align-items:center;display:flex;gap:6px;padding-right:5px}.style-module_PlayerVolumeZone__7LHeR{align-items:center;display:flex;height:4px;position:relative;width:70px}.style-module_PlayerRangeVolume__8XBa1{-webkit-appearance:none;-moz-appearance:none;appearance:none;height:4px;width:100%}.style-module_PlayerSeekTime__SEypx{flex:1;height:4px;position:relative}.style-module_PlayerHoverTime__iBu1D{background-color:#fff;border-radius:99px;color:#000;font-family:monospace;font-size:10pt;left:var(--player-hover-position);padding:2px 8px;position:absolute;top:-34px;transform:translateX(-50%)}.style-module_PlayerHoverTime__iBu1D:before{border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #fff;content:"";height:0;left:50%;position:absolute;top:99%;transform:translateX(-50%);width:0}.style-module_PlayerRangeTime__QVr8d,.style-module_PlayerRangeVolume__8XBa1{align-items:center;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;background-image:linear-gradient(to right,#00b2ff var(--player-time-position),#fffa var(--player-time-position),#fffa var(--player-buffer-position),#fff6 var(--player-buffer-position));border-radius:4px;cursor:pointer;display:flex;height:100%;width:100%}.style-module_PlayerRangeTime__QVr8d::-webkit-slider-thumb,.style-module_PlayerRangeVolume__8XBa1::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;border:0;height:0;width:0}.style-module_PlayerRangeTime__QVr8d::-moz-range-thumb,.style-module_PlayerRangeVolume__8XBa1::-moz-range-thumb{-moz-appearance:none;appearance:none;border:0;height:0;width:0}.style-module_PlayerRangeTime__QVr8d::-ms-thumb,.style-module_PlayerRangeVolume__8XBa1::-ms-thumb{appearance:none;border:0;height:0;width:0}.style-module_PlayerRangeThumb__J5IcV{background-color:#fff;border-radius:11px;height:12px;left:var(--player-thumb-position);pointer-events:none;position:absolute;top:-4px;transform:translateX(-50%);transition:box-shadow .2s;width:12px}.style-module_PlayerRangeTime__QVr8d:hover+.style-module_PlayerRangeThumb__J5IcV,.style-module_PlayerRangeVolume__8XBa1:hover+.style-module_PlayerRangeThumb__J5IcV{box-shadow:0 0 1px 3px hsla(0,0%,100%,.28)}.style-module_PlayerCenter__qLy3K,.style-module_PlayerLoading__PBiIH{cursor:pointer;height:60px;left:50%;padding:2px;position:absolute;top:50%;transform:translate(-50%,-50%);width:60px}.style-module_PlayerLoading__PBiIH{height:80px;width:80px}.style-module_PlayerSetting__BhP11{background-color:#0006;cursor:default;height:100%;left:0;position:absolute;top:0;width:100%}.style-module_PlayerSettingPanelQuality__4UQId,.style-module_PlayerSettingPanelSpeed__ABgXy,.style-module_PlayerSettingPanel__tZE0z{background-color:#fff;border-radius:10px;bottom:20px;display:flex;flex-direction:column;gap:4px;left:50%;max-width:80%;padding:10px 8px;position:absolute;transform:translateX(-50%);width:300px}.style-module_PlayerSettingPanelQuality__4UQId *,.style-module_PlayerSettingPanelSpeed__ABgXy *,.style-module_PlayerSettingPanel__tZE0z *{color:#000}.style-module_PlayerSettingPanelQuality__4UQId{max-height:calc(100% - 40px)}.style-module_PlayerSettingList__KEYZR{align-items:center;border-radius:8px;cursor:pointer;display:flex;font-size:14pt;gap:8px;padding:6px 14px}.style-module_PlayerSettingDisplay__-yFqd{display:flex;flex:1;justify-content:space-between}.style-module_PlayerButtonCursor__4PyXl{align-items:center;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#eee;border:0;border-radius:55px;cursor:pointer;display:flex;height:30px;justify-content:center;width:30px}.style-module_PlayerSpeedShow__u1NIt{font-size:14pt;padding-block:4px;text-align:center;width:100%}.style-module_PlayerPlayback__EZYH2{align-items:center;display:flex;gap:8px;padding-inline:8px}.style-module_PlayerRangeSpeed__ElauL{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:linear-gradient(to right,#000 var(--spped-thumb-position),#0006 var(--spped-thumb-position));border-radius:4px;flex:1;height:4px}.style-module_PlayerRangeSpeed__ElauL::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;background-color:#000;border-radius:50%;cursor:pointer;height:12px;width:12px}.style-module_PlayerRangeSpeed__ElauL::-moz-range-thumb{background-color:#000;border:none;border-radius:50%;cursor:pointer;height:12px;width:12px}.style-module_PlayerRangeSpeed__ElauL::-ms-thumb{background-color:#000;border-radius:50%;cursor:pointer;height:12px;width:12px}.style-module_PlayerCheckbox__At22K{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#eee;border-radius:14px;height:14px;width:14px}.style-module_PlayerCheckbox__At22K:checked{background-image:radial-gradient(circle at center,#fff 34%,#00b2ff 0)}.style-module_PlayerQualityList__rvIel{display:flex;flex-direction:column;font-size:12pt;gap:4px;overflow-y:auto;padding-inline:10px}.style-module_PlayerSettingList__KEYZR:hover{background-color:#eee6}.style-module_seekLeft__9AAFX,.style-module_seekRight__RMywZ{animation:style-module_shaking__Hgx0x .2s;font-size:24pt;position:absolute;text-shadow:0 0 2px rgba(0,0,0,.3);top:50%;transform:translateY(-50%)}.style-module_PlayerSubtitle__3j2kh{word-wrap:break-word;background-color:#0005;border-radius:4px;bottom:16px;font-size:16pt;line-height:16pt;max-width:80%;padding:6px;position:absolute}.style-module_PlayerSubtitle__3j2kh.style-module_SubtitleFloat__Y4R7k{bottom:42px}.style-module_PlayerError__t9v1M{align-items:center;background-color:#000;cursor:default;display:flex;flex-direction:column;font-size:16pt;height:100%;justify-content:center;left:0;position:absolute;top:0;width:100%}@keyframes style-module_shaking__Hgx0x{0%{transform:translateY(-50%) scale(1)}50%{transform:translateY(-50%) scale(2)}to{transform:translateY(-50%) scale(1)}}@media (max-width:460px){.style-module_PlayerDurationTime__uCgjW,.style-module_PlayerVolumeZone__7LHeR{display:none}.style-module_PlayerVolume__r7ll8{padding-right:0}.style-module_seekLeft__9AAFX,.style-module_seekRight__RMywZ{font-size:18pt}.style-module_PlayerSubtitle__3j2kh{font-size:12pt}}
|
|
@@ -6,13 +6,17 @@ type VideoSourceQuality = {
|
|
|
6
6
|
quality: number;
|
|
7
7
|
};
|
|
8
8
|
type VideoPlayerProps = {
|
|
9
|
+
track?: {
|
|
10
|
+
lang: 'th' | 'en' | 'ja' | 'zh';
|
|
11
|
+
src: string;
|
|
12
|
+
};
|
|
9
13
|
title?: string;
|
|
10
14
|
poster?: string;
|
|
11
15
|
hls?: boolean | Partial<HlsConfig>;
|
|
12
16
|
source: string | VideoSourceQuality[];
|
|
13
17
|
};
|
|
14
18
|
|
|
15
|
-
declare function VideoPlayer({ title, poster, source, hls }: VideoPlayerProps): react_jsx_runtime.JSX.Element;
|
|
19
|
+
declare function VideoPlayer({ title, poster, source, track, hls }: VideoPlayerProps): react_jsx_runtime.JSX.Element;
|
|
16
20
|
|
|
17
21
|
export { VideoPlayer };
|
|
18
22
|
export type { VideoSourceQuality };
|