softbuilders-react-video-player 1.2.4 → 1.2.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/dist/components/ControlBar/index.js +1 -0
- package/dist/components/ControlBar/index.js.map +1 -1
- package/dist/components/ControlBar/index.tsx +2 -0
- package/dist/components/NoteTooltip/index.js +1 -1
- package/dist/components/NoteTooltip/index.js.map +1 -1
- package/dist/components/NoteTooltip/index.tsx +2 -2
- package/dist/components/QualityMenu/index.js +8 -6
- package/dist/components/QualityMenu/index.js.map +1 -1
- package/dist/components/QualityMenu/index.tsx +8 -7
- package/dist/components/SoftBuildersVideoPlayer/index.d.ts +1 -0
- package/dist/components/SoftBuildersVideoPlayer/index.js +34 -58
- package/dist/components/SoftBuildersVideoPlayer/index.js.map +1 -1
- package/dist/components/SoftBuildersVideoPlayer/index.tsx +58 -101
- package/dist/components/SubtitleMenu/index.js +1 -1
- package/dist/components/SubtitleMenu/index.js.map +1 -1
- package/dist/components/SubtitleMenu/index.tsx +1 -1
- package/dist/components/TimeSlider/index.js +8 -2
- package/dist/components/TimeSlider/index.js.map +1 -1
- package/dist/components/TimeSlider/index.tsx +102 -93
- package/dist/components/VideoPlayerComponent/index.d.ts +1 -0
- package/dist/components/VideoPlayerComponent/index.js +91 -82
- package/dist/components/VideoPlayerComponent/index.js.map +1 -1
- package/dist/components/VideoPlayerComponent/index.tsx +135 -128
- package/dist/index.d.mts +1 -0
- package/dist/index.mjs +137 -148
- package/package.json +1 -1
@@ -4,6 +4,8 @@ import videojs from "video.js";
|
|
4
4
|
import Player from "video.js/dist/types/player";
|
5
5
|
import "video.js/dist/video-js.css";
|
6
6
|
import ControlBar from "../ControlBar";
|
7
|
+
import { isEqual } from "lodash";
|
8
|
+
|
7
9
|
import {
|
8
10
|
SoftBuildersVideoPlayerChapter,
|
9
11
|
SoftBuildersVideoPlayerNote,
|
@@ -13,8 +15,7 @@ import "./style/style.css";
|
|
13
15
|
import "../../styles/tailwind.css";
|
14
16
|
import { SoftBuildersVideoPlayerProvider } from "./provider";
|
15
17
|
import BigPlayButton from "../BigPlayButton";
|
16
|
-
import {
|
17
|
-
|
18
|
+
import { use } from "video.js/dist/types/tech/middleware";
|
18
19
|
let bigPlayButtonRoot: {
|
19
20
|
[key: string]: ReactDOM.Root | undefined;
|
20
21
|
} = {};
|
@@ -69,27 +70,21 @@ const renderControlBar = <T,>(
|
|
69
70
|
noteButtonClick?: (e: any) => void
|
70
71
|
) => {
|
71
72
|
const container = document.getElementById(`video-container-${id}`);
|
72
|
-
console.log("container: ", container);
|
73
|
-
|
74
73
|
if (container) {
|
75
|
-
console.log("container1: ");
|
76
|
-
|
77
74
|
container.style.height = "100%";
|
78
75
|
container.style.aspectRatio = "16 / 9";
|
79
76
|
const element: any = container.querySelector(".vjs-control-bar");
|
80
77
|
if (element) {
|
81
|
-
console.log("container2: ");
|
82
|
-
|
83
78
|
if (!controlBarRoot[id]) {
|
79
|
+
console.log("pooklo");
|
80
|
+
|
84
81
|
controlBarRoot[id] = ReactDOM.createRoot(element as HTMLElement);
|
85
|
-
element.style.display = "flex";
|
86
|
-
element.style.height = "100%";
|
87
|
-
element.style.alignItems = "flex-end";
|
88
82
|
}
|
89
|
-
|
83
|
+
element.style.display = "flex";
|
90
84
|
element.style.opacity = opacity;
|
91
85
|
element.style.backgroundColor = `${bgColor} !important`;
|
92
|
-
|
86
|
+
element.style.height = "100%";
|
87
|
+
element.style.alignItems = "flex-end";
|
93
88
|
controlBarRoot[id].render(
|
94
89
|
<SoftBuildersVideoPlayerProvider>
|
95
90
|
<ControlBar
|
@@ -128,29 +123,29 @@ export type Props<T = any> = {
|
|
128
123
|
bottomRedBar?: boolean;
|
129
124
|
childRef?: React.Ref<HTMLDivElement>;
|
130
125
|
noteButtonClick?: (e: any) => void;
|
126
|
+
videoID?: string;
|
131
127
|
};
|
132
|
-
|
133
128
|
const VideoPlayerComponent = forwardRef<HTMLDivElement, Props<any>>(
|
134
|
-
(
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
ref?: any
|
151
|
-
) => {
|
129
|
+
({
|
130
|
+
id,
|
131
|
+
options,
|
132
|
+
notes,
|
133
|
+
chapters,
|
134
|
+
startTime = 0,
|
135
|
+
handleSaveNoteAction,
|
136
|
+
poster,
|
137
|
+
onPlay,
|
138
|
+
onPause,
|
139
|
+
disableNote,
|
140
|
+
childRef,
|
141
|
+
bottomRedBar = true,
|
142
|
+
noteButtonClick,
|
143
|
+
videoID,
|
144
|
+
}: Props) => {
|
152
145
|
const videoRef = useRef<any>(undefined);
|
153
146
|
const playerRef = useRef<Player | undefined>(undefined);
|
147
|
+
const idRef = useRef<any | undefined>(undefined);
|
148
|
+
|
154
149
|
const [isReady, setIsReady] = useState(false);
|
155
150
|
const [isPaused, setIsPaused] = useState(!options.autoplay);
|
156
151
|
const [duration, setDuration] = useState(1);
|
@@ -159,15 +154,15 @@ const VideoPlayerComponent = forwardRef<HTMLDivElement, Props<any>>(
|
|
159
154
|
const [bgColor, setBgColor] = useState("transparent");
|
160
155
|
const [isQualityMenuOpen, setIsQualityMenuOpen] = useState(false);
|
161
156
|
const [isSubtitleMenuOpen, setIsSubtitleMenuOpen] = useState(false);
|
157
|
+
const [isHovered, setIsHovered] = useState(false);
|
162
158
|
const [isNoteOpen, setNoteOpen] = useState(false);
|
163
|
-
console.log("notes", notes);
|
164
|
-
|
165
159
|
const onReady = (player: Player) => {
|
166
|
-
console.log("onReady: ", onReady);
|
167
160
|
if (playerRef) {
|
168
161
|
playerRef.current = player;
|
169
162
|
setIsReady(true);
|
163
|
+
|
170
164
|
player?.currentTime(startTime);
|
165
|
+
console.log("startTime: ", startTime);
|
171
166
|
|
172
167
|
player.on("waiting", () => {});
|
173
168
|
player.on("dispose", () => {
|
@@ -180,42 +175,32 @@ const VideoPlayerComponent = forwardRef<HTMLDivElement, Props<any>>(
|
|
180
175
|
});
|
181
176
|
}
|
182
177
|
};
|
178
|
+
useEffect(() => {
|
179
|
+
if (!playerRef.current) {
|
180
|
+
const videoElement = document.createElement("video-js");
|
183
181
|
|
184
|
-
|
185
|
-
const videoElement = document.createElement("video-js");
|
186
|
-
videoElement.setAttribute("playsinline", "true");
|
187
|
-
videoElement.classList.add("vjs-big-play-centered");
|
188
|
-
if (poster) {
|
189
|
-
videoElement.setAttribute("poster", poster);
|
190
|
-
}
|
191
|
-
videoRef.current.appendChild(videoElement);
|
192
|
-
videoElement.style.width = "100%";
|
193
|
-
videoElement.style.height = "100%";
|
182
|
+
videoElement.setAttribute("playsinline", "true");
|
194
183
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
};
|
200
|
-
useEffect(() => {
|
201
|
-
if (playerRef.current) {
|
202
|
-
if (!isEqual(playerRef.current.poster_, poster)) {
|
203
|
-
playerRef.current.dispose();
|
204
|
-
console.log("dispose: ");
|
205
|
-
playerRef.current = undefined;
|
184
|
+
videoElement.classList.add("vjs-big-play-centered");
|
185
|
+
// Set the poster attribute here
|
186
|
+
if (poster) {
|
187
|
+
videoElement.setAttribute("poster", poster);
|
206
188
|
}
|
189
|
+
videoRef.current.appendChild(videoElement);
|
190
|
+
videoElement.style.width = "100%";
|
191
|
+
videoElement.style.height = "100%";
|
192
|
+
videoElement.style.objectFit = "cover";
|
193
|
+
playerRef.current = videojs(videoElement, options, () => {
|
194
|
+
onReady(playerRef.current as Player);
|
195
|
+
});
|
207
196
|
}
|
208
|
-
initializePlayer();
|
209
|
-
console.log("initializePlayer: ghhh");
|
210
|
-
}, [options]);
|
211
|
-
useEffect(() => {
|
212
197
|
return () => {
|
213
198
|
if (playerRef.current) {
|
214
|
-
|
215
|
-
|
199
|
+
if (!isEqual(idRef?.current?.sources ?? "", options.sources)) {
|
200
|
+
idRef.current = options;
|
216
201
|
playerRef.current.dispose();
|
217
|
-
console.log("dispose7: ");
|
218
202
|
playerRef.current = undefined;
|
203
|
+
console.log("dispose8: ");
|
219
204
|
setTimeout(() => {
|
220
205
|
if (bigPlayButtonRoot[id]) {
|
221
206
|
bigPlayButtonRoot[id].unmount();
|
@@ -227,60 +212,74 @@ const VideoPlayerComponent = forwardRef<HTMLDivElement, Props<any>>(
|
|
227
212
|
}
|
228
213
|
}, 0);
|
229
214
|
}
|
215
|
+
|
216
|
+
// setTimeout(() => {
|
217
|
+
// if (bigPlayButtonRoot[id]) {
|
218
|
+
// bigPlayButtonRoot[id].unmount();
|
219
|
+
// bigPlayButtonRoot[id] = undefined;
|
220
|
+
// }
|
221
|
+
// if (controlBarRoot[id]) {
|
222
|
+
// controlBarRoot[id].unmount();
|
223
|
+
// controlBarRoot[id] = undefined;
|
224
|
+
// }
|
225
|
+
// }, 0);
|
230
226
|
}
|
231
227
|
};
|
232
228
|
}, [options]);
|
229
|
+
// Added poster to dependency array
|
230
|
+
|
231
|
+
useEffect(() => {
|
232
|
+
if (playerRef.current) {
|
233
|
+
console.log("time");
|
234
|
+
|
235
|
+
playerRef.current.currentTime(startTime);
|
236
|
+
}
|
237
|
+
}, [startTime]);
|
233
238
|
useEffect(() => {
|
234
239
|
if (playerRef.current && isReady) {
|
235
240
|
const currentTime = playerRef.current.currentTime() || 0;
|
241
|
+
console.log("currentTime: ", currentTime);
|
236
242
|
if (isPaused) {
|
237
243
|
if (onPause) onPause(currentTime);
|
238
244
|
} else {
|
239
245
|
if (onPlay) onPlay(currentTime);
|
240
246
|
}
|
241
247
|
}
|
242
|
-
}, [isPaused
|
248
|
+
}, [isPaused]);
|
243
249
|
|
244
250
|
useEffect(() => {
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
);
|
270
|
-
}, 0);
|
271
|
-
return () => clearTimeout(controlBarTimeout);
|
272
|
-
}
|
251
|
+
const controlBarTimeout = setTimeout(() => {
|
252
|
+
renderControlBar(
|
253
|
+
id,
|
254
|
+
playerRef.current,
|
255
|
+
isPaused,
|
256
|
+
setIsPaused,
|
257
|
+
duration,
|
258
|
+
notes,
|
259
|
+
chapters,
|
260
|
+
5,
|
261
|
+
handleSaveNoteAction,
|
262
|
+
opacity,
|
263
|
+
(e: any) => {
|
264
|
+
handlePlayerClick(e, true);
|
265
|
+
},
|
266
|
+
bgColor,
|
267
|
+
setIsQualityMenuOpen,
|
268
|
+
setIsSubtitleMenuOpen,
|
269
|
+
disableNote,
|
270
|
+
setNoteOpen,
|
271
|
+
noteButtonClick
|
272
|
+
);
|
273
|
+
}, 0);
|
274
|
+
return () => clearTimeout(controlBarTimeout);
|
273
275
|
}, [
|
274
|
-
id,
|
275
|
-
playerRef,
|
276
276
|
isPaused,
|
277
277
|
setIsPaused,
|
278
278
|
notes,
|
279
|
-
chapters,
|
280
|
-
isReady,
|
281
279
|
handleSaveNoteAction,
|
282
280
|
duration,
|
283
281
|
opacity,
|
282
|
+
isReady,
|
284
283
|
]);
|
285
284
|
useEffect(() => {
|
286
285
|
if (isReady) {
|
@@ -295,36 +294,32 @@ const VideoPlayerComponent = forwardRef<HTMLDivElement, Props<any>>(
|
|
295
294
|
}, 500);
|
296
295
|
return () => clearTimeout(playButtonTimeout);
|
297
296
|
}
|
298
|
-
}, [
|
297
|
+
}, [isPaused, opacity, isReady, options]);
|
299
298
|
useEffect(() => {
|
300
299
|
if (playerRef.current) {
|
301
|
-
playerRef.current.dispose();
|
302
|
-
console.log("dispose7: ");
|
303
|
-
playerRef.current = undefined;
|
304
|
-
setTimeout(() => {
|
305
|
-
if (bigPlayButtonRoot[id]) {
|
306
|
-
bigPlayButtonRoot[id].unmount();
|
307
|
-
bigPlayButtonRoot[id] = undefined;
|
308
|
-
}
|
309
|
-
if (controlBarRoot[id]) {
|
310
|
-
controlBarRoot[id].unmount();
|
311
|
-
controlBarRoot[id] = undefined;
|
312
|
-
}
|
313
|
-
}, 0);
|
314
300
|
const intervalId = setInterval(() => {
|
315
301
|
if (playerRef.current) setIsPaused(playerRef.current.paused());
|
316
302
|
}, 500);
|
317
303
|
return () => clearInterval(intervalId);
|
318
304
|
}
|
319
305
|
}, []);
|
320
|
-
useEffect(() => {
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
306
|
+
// useEffect(() => {
|
307
|
+
// return () => {
|
308
|
+
// if (playerRef.current) {
|
309
|
+
// playerRef.current.dispose();
|
310
|
+
// playerRef.current = undefined;
|
311
|
+
// // Cleanup play button and control bar renders
|
312
|
+
// if (bigPlayButtonRoot[id]) {
|
313
|
+
// bigPlayButtonRoot[id].unmount();
|
314
|
+
// bigPlayButtonRoot[id] = undefined;
|
315
|
+
// }
|
316
|
+
// if (controlBarRoot[id]) {
|
317
|
+
// controlBarRoot[id].unmount();
|
318
|
+
// controlBarRoot[id] = undefined;
|
319
|
+
// }
|
320
|
+
// }
|
321
|
+
// };
|
322
|
+
// }, []);
|
328
323
|
const timeoutRef = useRef<any>(null);
|
329
324
|
useEffect(() => {
|
330
325
|
if (isQualityMenuOpen || isSubtitleMenuOpen) {
|
@@ -343,14 +338,26 @@ const VideoPlayerComponent = forwardRef<HTMLDivElement, Props<any>>(
|
|
343
338
|
}, 3000);
|
344
339
|
}
|
345
340
|
}, [isQualityMenuOpen, isSubtitleMenuOpen]);
|
346
|
-
|
347
341
|
useEffect(() => {
|
348
|
-
console.log("
|
349
|
-
|
342
|
+
console.log("isNoteOpen: ", isNoteOpen);
|
343
|
+
|
344
|
+
if (isNoteOpen) {
|
345
|
+
if (timeoutRef.current) {
|
346
|
+
clearTimeout(timeoutRef.current);
|
347
|
+
}
|
348
|
+
} else {
|
349
|
+
if (timeoutRef.current) {
|
350
|
+
clearTimeout(timeoutRef.current);
|
351
|
+
}
|
352
|
+
|
353
|
+
timeoutRef.current = setTimeout(() => {
|
354
|
+
setIsControlBarPresent(false);
|
355
|
+
}, 3000);
|
356
|
+
}
|
357
|
+
}, [isNoteOpen]);
|
350
358
|
|
351
359
|
const handlePlayerClick = async (e: any, isTimerOnly = false) => {
|
352
360
|
e.preventDefault();
|
353
|
-
|
354
361
|
if (timeoutRef.current) {
|
355
362
|
clearTimeout(timeoutRef.current);
|
356
363
|
}
|
@@ -372,8 +379,6 @@ const VideoPlayerComponent = forwardRef<HTMLDivElement, Props<any>>(
|
|
372
379
|
if (playerRef.current) {
|
373
380
|
if (playerRef.current.paused()) {
|
374
381
|
try {
|
375
|
-
// startTime && playerRef.current.currentTime(startTime);
|
376
|
-
console.log("startTime: ", startTime);
|
377
382
|
await playerRef.current.play();
|
378
383
|
setIsPaused(false);
|
379
384
|
} catch (error) {
|
@@ -421,12 +426,12 @@ const VideoPlayerComponent = forwardRef<HTMLDivElement, Props<any>>(
|
|
421
426
|
}, []);
|
422
427
|
|
423
428
|
const [timeSeeker, setTimeSeeker] = useState<string>("0");
|
424
|
-
|
425
429
|
useEffect(() => {
|
426
430
|
const updateTimeSeeker = () => {
|
427
|
-
if (playerRef.current) {
|
431
|
+
if (playerRef.current && isReady) {
|
428
432
|
const currentTime = playerRef.current.currentTime();
|
429
433
|
const duration = playerRef.current.duration();
|
434
|
+
console.log("duration: ", duration, currentTime);
|
430
435
|
|
431
436
|
if (duration && currentTime !== undefined) {
|
432
437
|
setTimeSeeker(`${(currentTime / duration) * 100}%`);
|
@@ -445,10 +450,12 @@ const VideoPlayerComponent = forwardRef<HTMLDivElement, Props<any>>(
|
|
445
450
|
<div
|
446
451
|
ref={videoRefs}
|
447
452
|
id={`video-container-${id}`}
|
448
|
-
onMouseMove={(
|
449
|
-
handlePlayerClick(
|
453
|
+
onMouseMove={() => {
|
454
|
+
!isNoteOpen ? handlePlayerClick(event, true) : "";
|
450
455
|
}}
|
451
456
|
className="sb-relative sb-rounded-md sb-overflow-hidden sb-w-full sb-h-full sb-bottom-2 "
|
457
|
+
onMouseEnter={() => setIsHovered(true)}
|
458
|
+
onMouseLeave={() => setIsHovered(false)}
|
452
459
|
>
|
453
460
|
{bottomRedBar && (
|
454
461
|
<div
|
package/dist/index.d.mts
CHANGED
@@ -52,6 +52,7 @@ type Props<T = any> = {
|
|
52
52
|
bottomRedBar?: boolean;
|
53
53
|
childRef?: React$1.Ref<HTMLDivElement>;
|
54
54
|
noteButtonClick?: (e: any) => void;
|
55
|
+
videoId?: string;
|
55
56
|
};
|
56
57
|
declare const SoftBuildersVideoPlayer: React$1.MemoExoticComponent<React$1.ForwardRefExoticComponent<Props<any> & React$1.RefAttributes<HTMLDivElement>>>;
|
57
58
|
|