@zezosoft/react-player 0.0.3 → 0.0.5
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 +124 -23
- package/dist/VideoPlayer/VideoPlayer.d.ts +23 -2
- package/dist/VideoPlayer/_components/ControlsHeader.d.ts +1 -0
- package/dist/components/ui/FullScreenToggle.d.ts +9 -0
- package/dist/components/ui/PiPictureInPictureToggle.d.ts +8 -0
- package/dist/components/ui/Popover.d.ts +4 -2
- package/dist/components/ui/VideoActionButton.d.ts +10 -0
- package/dist/components/ui/tooltip.d.ts +1 -0
- package/dist/index.js +505 -126
- package/dist/store/VideoState.d.ts +53 -4
- package/package.json +11 -8
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @zezosoft/react-player 🎬
|
|
2
2
|
|
|
3
|
-
A powerful and flexible **React video player** by **Zezosoft**, supporting HLS, MP4, preview thumbnails, tracking, and advanced
|
|
3
|
+
A powerful and flexible **React video player** by **Zezosoft**, supporting HLS, MP4, preview thumbnails, tracking, subtitles, episode playback, and advanced controls.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -10,13 +10,16 @@ A powerful and flexible **React video player** by **Zezosoft**, supporting HLS,
|
|
|
10
10
|
✅ **Preview Thumbnails on Hover**
|
|
11
11
|
✅ **Event Tracking (Views, Watch Time, etc.)**
|
|
12
12
|
✅ **Customizable Player Size & Controls**
|
|
13
|
-
✅ **Time-Stamped Labels for Video Chapters**
|
|
13
|
+
✅ **Time-Stamped Labels for Video Chapters**
|
|
14
|
+
✅ **Subtitles (WebVTT)**
|
|
15
|
+
✅ **Intro Skipping**
|
|
16
|
+
✅ **Next Episode Auto Play and Button**
|
|
14
17
|
|
|
15
18
|
---
|
|
16
19
|
|
|
17
20
|
## 📦 Installation
|
|
18
21
|
|
|
19
|
-
Install the package using **npm**
|
|
22
|
+
Install the package using **npm**
|
|
20
23
|
|
|
21
24
|
```sh
|
|
22
25
|
npm install @zezosoft/react-player
|
|
@@ -35,7 +38,6 @@ import { VideoPlayer } from "@zezosoft/react-player";
|
|
|
35
38
|
function App() {
|
|
36
39
|
const previewImage = useRef("");
|
|
37
40
|
|
|
38
|
-
// Generate dynamic preview images based on hover time
|
|
39
41
|
const updatePreviewImage = (hoverTime: number) => {
|
|
40
42
|
const url = `https://fakeimg.pl/720x405?text=${hoverTime}`;
|
|
41
43
|
const image = document.createElement("img");
|
|
@@ -68,6 +70,25 @@ function App() {
|
|
|
68
70
|
onViewed: () => console.log("Video Viewed"),
|
|
69
71
|
onWatchTimeUpdated: (e) => console.log("Watch Time Updated", e),
|
|
70
72
|
}}
|
|
73
|
+
subtitles={[
|
|
74
|
+
{
|
|
75
|
+
lang: "en",
|
|
76
|
+
label: "English",
|
|
77
|
+
url: "https://example.com/subtitles-en.vtt",
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
lang: "hi",
|
|
81
|
+
label: "Hindi",
|
|
82
|
+
url: "https://example.com/subtitles-hi.vtt",
|
|
83
|
+
},
|
|
84
|
+
]}
|
|
85
|
+
episodeList={[
|
|
86
|
+
{ id: 1, title: "Episode 1", url: "https://example.com/ep1.m3u8" },
|
|
87
|
+
{ id: 2, title: "Episode 2", url: "https://example.com/ep2.m3u8" },
|
|
88
|
+
]}
|
|
89
|
+
currentEpisodeIndex={0}
|
|
90
|
+
intro={{ start: 5, end: 20 }}
|
|
91
|
+
nextEpisodeConfig={{ showAtTime: 300, showAtEnd: true }}
|
|
71
92
|
/>
|
|
72
93
|
</div>
|
|
73
94
|
);
|
|
@@ -80,33 +101,40 @@ export default App;
|
|
|
80
101
|
|
|
81
102
|
## 🎨 Props Reference
|
|
82
103
|
|
|
83
|
-
| Prop Name | Type
|
|
84
|
-
| --------------------- |
|
|
85
|
-
| `trackPoster` | `string`
|
|
86
|
-
| `trackSrc` | `string`
|
|
87
|
-
| `trackTitle` | `string`
|
|
88
|
-
| `isTrailer` | `boolean`
|
|
89
|
-
| `width` | `string`
|
|
90
|
-
| `height` | `string`
|
|
91
|
-
| `timeCodes` | `Array<{ fromMs: number, description: string }>`
|
|
92
|
-
| `getPreviewScreenUrl` | `(timeMs: number) => string`
|
|
93
|
-
| `tracking` | `object`
|
|
104
|
+
| Prop Name | Type | Default | Description |
|
|
105
|
+
| --------------------- | ----------------------------------------------------- | ----------- | ---------------------------------------------------------- |
|
|
106
|
+
| `trackPoster` | `string` | `""` | URL of the video poster image. |
|
|
107
|
+
| `trackSrc` | `string` | `""` | Video source URL (MP4, HLS, etc.). |
|
|
108
|
+
| `trackTitle` | `string` | `""` | Title of the video. |
|
|
109
|
+
| `isTrailer` | `boolean` | `false` | Specifies if the video is a trailer. |
|
|
110
|
+
| `width` | `string` | `"100%"` | Width of the video player. |
|
|
111
|
+
| `height` | `string` | `"auto"` | Height of the video player. |
|
|
112
|
+
| `timeCodes` | `Array<{ fromMs: number, description: string }>` | `[]` | List of time-based markers with descriptions. |
|
|
113
|
+
| `getPreviewScreenUrl` | `(timeMs: number) => string` | `null` | Function to generate preview screen URLs based on time. |
|
|
114
|
+
| `tracking` | `object` | `{}` | Tracking event callbacks. |
|
|
115
|
+
| `subtitles` | `Array<{ lang: string; label: string; url: string }>` | `[]` | Subtitle tracks in WebVTT format. |
|
|
116
|
+
| `episodeList` | `Array<{ id: number; title: string; url: string }>` | `[]` | List of episodes to support autoplay/playlist. |
|
|
117
|
+
| `currentEpisodeIndex` | `number` | `0` | Index of currently playing episode. |
|
|
118
|
+
| `intro` | `{ start: number; end: number }` | `undefined` | Defines intro duration in seconds. |
|
|
119
|
+
| `nextEpisodeConfig` | `{ showAtTime?: number; showAtEnd?: boolean }` | `undefined` | When to show next episode UI — at specific time or at end. |
|
|
120
|
+
| |
|
|
94
121
|
|
|
95
122
|
---
|
|
96
123
|
|
|
97
124
|
## 📢 Tracking Events
|
|
98
125
|
|
|
99
|
-
| Event Name | Description
|
|
100
|
-
| -------------------- |
|
|
101
|
-
| `onViewed` | Triggered when the video
|
|
102
|
-
| `onWatchTimeUpdated` | Triggered when
|
|
126
|
+
| Event Name | Description |
|
|
127
|
+
| -------------------- | ------------------------------------------------ |
|
|
128
|
+
| `onViewed` | Triggered when the video starts playing. |
|
|
129
|
+
| `onWatchTimeUpdated` | Triggered when user leaves with >30s watch time. |
|
|
103
130
|
|
|
104
131
|
#### Example usage:
|
|
105
132
|
|
|
106
133
|
```tsx
|
|
107
134
|
tracking={{
|
|
108
|
-
onViewed: () => console.log("
|
|
109
|
-
onWatchTimeUpdated: (
|
|
135
|
+
onViewed: () => console.log("Viewed!"),
|
|
136
|
+
onWatchTimeUpdated: ({ watchTime }) =>
|
|
137
|
+
console.log("Total watch time (sec):", watchTime),
|
|
110
138
|
}}
|
|
111
139
|
```
|
|
112
140
|
|
|
@@ -139,9 +167,77 @@ Mark important video sections:
|
|
|
139
167
|
```tsx
|
|
140
168
|
<VideoPlayer
|
|
141
169
|
timeCodes={[
|
|
142
|
-
{ fromMs: 0, description: "
|
|
143
|
-
{ fromMs: 120000, description: "
|
|
170
|
+
{ fromMs: 0, description: "Intro" },
|
|
171
|
+
{ fromMs: 120000, description: "Main Scene" },
|
|
172
|
+
]}
|
|
173
|
+
/>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
🔹 Subtitles Support
|
|
177
|
+
|
|
178
|
+
Add support for multiple subtitle tracks in .vtt format:
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
subtitles={[
|
|
182
|
+
{
|
|
183
|
+
lang: "en",
|
|
184
|
+
label: "English",
|
|
185
|
+
url: "https://example.com/subtitles-en.vtt",
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
lang: "fr",
|
|
189
|
+
label: "French",
|
|
190
|
+
url: "https://example.com/subtitles-fr.vtt",
|
|
191
|
+
},
|
|
192
|
+
]}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
🔹 Skip Intro Button
|
|
196
|
+
|
|
197
|
+
Automatically show a "Skip Intro" button between a specific start and end time
|
|
198
|
+
|
|
199
|
+
```tsx
|
|
200
|
+
<VideoPlayer intro={{ start: 5, end: 20 }} />
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
🔹 Next Episode Playback
|
|
204
|
+
|
|
205
|
+
Automatically show "Next Episode" option when video ends or reaches a set time
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
<VideoPlayer
|
|
209
|
+
nextEpisodeConfig={{
|
|
210
|
+
showAtTime: 300,
|
|
211
|
+
showAtEnd: true,
|
|
212
|
+
}}
|
|
213
|
+
/>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
🔹 Episode Playlist Support
|
|
217
|
+
|
|
218
|
+
Pass a playlist of episodes and control which one plays currently
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
<VideoPlayer
|
|
222
|
+
episodeList={[
|
|
223
|
+
{ id: 1, title: "Episode 1", url: "https://example.com/ep1.m3u8" },
|
|
224
|
+
{ id: 2, title: "Episode 2", url: "https://example.com/ep2.m3u8" },
|
|
144
225
|
]}
|
|
226
|
+
currentEpisodeIndex={0}
|
|
227
|
+
/>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
🔹 Tracking Events
|
|
231
|
+
|
|
232
|
+
Track when the video is viewed or how much time was watched
|
|
233
|
+
|
|
234
|
+
```tsx
|
|
235
|
+
<VideoPlayer
|
|
236
|
+
tracking={{
|
|
237
|
+
onViewed: () => console.log("User viewed the video."),
|
|
238
|
+
onWatchTimeUpdated: ({ watchTime }) =>
|
|
239
|
+
console.log("Total watch time in seconds:", watchTime),
|
|
240
|
+
}}
|
|
145
241
|
/>
|
|
146
242
|
```
|
|
147
243
|
|
|
@@ -155,6 +251,11 @@ Mark important video sections:
|
|
|
155
251
|
- Ensure the video format (MP4, HLS) is supported.
|
|
156
252
|
- If using HLS, ensure you're serving files correctly (CORS issues may block playback).
|
|
157
253
|
|
|
254
|
+
#### ❌ Subtitles not showing?
|
|
255
|
+
|
|
256
|
+
- Check that .vtt files are correctly hosted and publicly accessible.
|
|
257
|
+
- Ensure the subtitles prop includes proper lang, label, and url.
|
|
258
|
+
|
|
158
259
|
#### ❌ Preview thumbnails not loading?
|
|
159
260
|
|
|
160
261
|
- Confirm `getPreviewScreenUrl` is returning a valid image URL.
|
|
@@ -1,21 +1,42 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { TimeCode } from "./_components/TimeLine/TimeLine";
|
|
3
3
|
import { IOnWatchTimeUpdated } from "../types";
|
|
4
|
-
|
|
4
|
+
import "../../src/index.css";
|
|
5
|
+
export interface Props {
|
|
5
6
|
trackSrc: string;
|
|
6
7
|
trackTitle?: string;
|
|
7
8
|
trackPoster?: string;
|
|
8
9
|
isTrailer?: boolean;
|
|
9
10
|
className?: string;
|
|
10
|
-
type?: "hls" | "mp4" | "other";
|
|
11
|
+
type?: "hls" | "mp4" | "other" | "youtube" | undefined;
|
|
11
12
|
width?: string;
|
|
12
13
|
height?: string;
|
|
14
|
+
onClose?: () => void;
|
|
13
15
|
timeCodes?: TimeCode[];
|
|
14
16
|
getPreviewScreenUrl?: (hoverTimeValue: number) => string;
|
|
15
17
|
tracking?: {
|
|
16
18
|
onViewed?: () => void;
|
|
17
19
|
onWatchTimeUpdated?: (e: IOnWatchTimeUpdated) => void;
|
|
18
20
|
};
|
|
21
|
+
subtitles?: {
|
|
22
|
+
lang: string;
|
|
23
|
+
label: string;
|
|
24
|
+
url: string;
|
|
25
|
+
}[];
|
|
26
|
+
episodeList?: {
|
|
27
|
+
id: number;
|
|
28
|
+
title: string;
|
|
29
|
+
url: string;
|
|
30
|
+
}[];
|
|
31
|
+
currentEpisodeIndex?: number;
|
|
32
|
+
intro?: {
|
|
33
|
+
start: number;
|
|
34
|
+
end: number;
|
|
35
|
+
};
|
|
36
|
+
nextEpisodeConfig?: {
|
|
37
|
+
showAtTime?: number;
|
|
38
|
+
showAtEnd?: boolean;
|
|
39
|
+
};
|
|
19
40
|
}
|
|
20
41
|
declare const VideoPlayer: React.FC<Props>;
|
|
21
42
|
export default VideoPlayer;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import "../../VideoPlayer/_components/styles/video-controls.css";
|
|
3
|
+
interface FullScreenToggleProps {
|
|
4
|
+
isFullScreen: boolean;
|
|
5
|
+
onClick?: () => void;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
declare const FullScreenToggle: React.FC<FullScreenToggleProps>;
|
|
9
|
+
export default FullScreenToggle;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import "../../VideoPlayer/_components/styles/video-controls.css";
|
|
3
|
+
interface PiPictureInPictureToggleProps {
|
|
4
|
+
onClick?: () => void;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
declare const PiPictureInPictureToggle: React.FC<PiPictureInPictureToggleProps>;
|
|
8
|
+
export default PiPictureInPictureToggle;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
|
|
2
|
+
interface PopoverProps {
|
|
3
3
|
button: React.ReactNode;
|
|
4
4
|
children: React.ReactNode;
|
|
5
|
-
|
|
5
|
+
closeOnButtonClick?: boolean;
|
|
6
|
+
}
|
|
7
|
+
declare const Popover: React.FC<PopoverProps>;
|
|
6
8
|
export default Popover;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface VideoActionButtonProps {
|
|
3
|
+
text: string;
|
|
4
|
+
onClick: () => void;
|
|
5
|
+
icon?: React.ReactNode;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
position?: "left" | "right";
|
|
8
|
+
}
|
|
9
|
+
declare const VideoActionButton: React.FC<VideoActionButtonProps>;
|
|
10
|
+
export default VideoActionButton;
|