softbuilders-react-video-player 1.3.2 → 1.3.3
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/SoftBuildersVideoPlayer/index.d.ts +1 -1
- package/dist/components/SoftBuildersVideoPlayer/index.js +5 -4
- package/dist/components/SoftBuildersVideoPlayer/index.js.map +1 -1
- package/dist/components/SoftBuildersVideoPlayer/index.tsx +90 -87
- package/dist/components/VideoPlayerComponent/index.d.ts +1 -1
- package/dist/components/VideoPlayerComponent/index.js +3 -3
- package/dist/components/VideoPlayerComponent/index.js.map +1 -1
- package/dist/components/VideoPlayerComponent/index.tsx +407 -411
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +432 -436
- package/package.json +1 -1
@@ -140,88 +140,141 @@ export type Props<T = any> = {
|
|
140
140
|
isTrailer?: boolean;
|
141
141
|
height?: number;
|
142
142
|
};
|
143
|
-
const VideoPlayerComponent =
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
player
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
143
|
+
const VideoPlayerComponent = ({
|
144
|
+
id,
|
145
|
+
options,
|
146
|
+
notes,
|
147
|
+
chapters,
|
148
|
+
startTime = 0,
|
149
|
+
handleSaveNoteAction,
|
150
|
+
poster,
|
151
|
+
onPlay,
|
152
|
+
onPause,
|
153
|
+
disableNote,
|
154
|
+
childRef,
|
155
|
+
bottomRedBar = true,
|
156
|
+
noteButtonClick,
|
157
|
+
videoID,
|
158
|
+
isTrailer,
|
159
|
+
height,
|
160
|
+
}: Props) => {
|
161
|
+
const videoRef = useRef<any>(undefined);
|
162
|
+
const playerRef = useRef<Player | undefined>(undefined);
|
163
|
+
const idRef = useRef<any | undefined>(undefined);
|
164
|
+
|
165
|
+
const [isReady, setIsReady] = useState(false);
|
166
|
+
const [isPaused, setIsPaused] = useState(!options.autoplay);
|
167
|
+
const [duration, setDuration] = useState(1);
|
168
|
+
const [opacity, setOpacity] = useState("0");
|
169
|
+
const [isControlBarPresent, setIsControlBarPresent] = useState(true);
|
170
|
+
const [bgColor, setBgColor] = useState("transparent");
|
171
|
+
const [isQualityMenuOpen, setIsQualityMenuOpen] = useState(false);
|
172
|
+
const [isSubtitleMenuOpen, setIsSubtitleMenuOpen] = useState(false);
|
173
|
+
const [isHovered, setIsHovered] = useState(false);
|
174
|
+
const [isNoteOpen, setNoteOpen] = useState(false);
|
175
|
+
const [heightValue, setHeightValue] = useState<number>(0);
|
176
|
+
const [isLoading, setIsloading] = useState<boolean>(false);
|
177
|
+
|
178
|
+
const onReady = (player: Player) => {
|
179
|
+
if (playerRef) {
|
180
|
+
playerRef.current = player;
|
181
|
+
setIsReady(true);
|
182
|
+
|
183
|
+
player?.currentTime(startTime);
|
184
|
+
|
185
|
+
player.on("waiting", () => {});
|
186
|
+
player.on("dispose", () => {
|
187
|
+
videojs.log("player will dispose");
|
188
|
+
setIsReady(false);
|
189
|
+
});
|
190
|
+
player.on("loadedmetadata", () => {
|
191
|
+
const d = player.duration() || 0;
|
192
|
+
setDuration(d);
|
193
|
+
});
|
194
|
+
}
|
195
|
+
};
|
196
|
+
useEffect(() => {
|
197
|
+
if (!playerRef.current) {
|
198
|
+
const videoElement = document.createElement("video-js");
|
199
|
+
|
200
|
+
videoElement.setAttribute("playsinline", "true");
|
201
|
+
|
202
|
+
videoElement.classList.add("vjs-big-play-centered");
|
203
|
+
// Set the poster attribute here
|
204
|
+
if (poster) {
|
205
|
+
videoElement.setAttribute("poster", poster);
|
206
|
+
}
|
207
|
+
videoRef.current.appendChild(videoElement);
|
208
|
+
videoElement.style.width = "100%";
|
209
|
+
videoElement.style.height = "100%";
|
210
|
+
videoElement.style.objectFit = "cover";
|
211
|
+
playerRef.current = videojs(videoElement, options, () => {
|
212
|
+
onReady(playerRef.current as Player);
|
213
|
+
});
|
214
|
+
}
|
215
|
+
return () => {
|
216
|
+
if (playerRef.current) {
|
217
|
+
idRef.current = options;
|
218
|
+
playerRef.current.dispose();
|
219
|
+
playerRef.current = undefined;
|
220
|
+
|
221
|
+
setTimeout(() => {
|
222
|
+
if (bigPlayButtonRoot[id]) {
|
223
|
+
bigPlayButtonRoot[id].unmount();
|
224
|
+
bigPlayButtonRoot[id] = undefined;
|
225
|
+
}
|
226
|
+
if (controlBarRoot[id]) {
|
227
|
+
controlBarRoot[id].unmount();
|
228
|
+
controlBarRoot[id] = undefined;
|
229
|
+
}
|
230
|
+
}, 0);
|
231
|
+
|
232
|
+
// setTimeout(() => {
|
233
|
+
// if (bigPlayButtonRoot[id]) {
|
234
|
+
// bigPlayButtonRoot[id].unmount();
|
235
|
+
// bigPlayButtonRoot[id] = undefined;
|
236
|
+
// }
|
237
|
+
// if (controlBarRoot[id]) {
|
238
|
+
// controlBarRoot[id].unmount();
|
239
|
+
// controlBarRoot[id] = undefined;
|
240
|
+
// }
|
241
|
+
// }, 0);
|
198
242
|
}
|
199
243
|
};
|
200
|
-
|
201
|
-
if (!playerRef.current) {
|
202
|
-
const videoElement = document.createElement("video-js");
|
244
|
+
}, [id]);
|
203
245
|
|
204
|
-
|
246
|
+
useEffect(() => {
|
247
|
+
if (playerRef.current) {
|
248
|
+
const myPlayer = playerRef.current.currentSources();
|
249
|
+
playerRef.current.src(options.sources);
|
250
|
+
playerRef.current.load();
|
251
|
+
}
|
252
|
+
}, [options.sources[0].type]);
|
253
|
+
useEffect(() => {
|
254
|
+
if (!playerRef.current) {
|
255
|
+
const videoElement = document.createElement("video-js");
|
205
256
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
videoElement.style.width = "100%";
|
213
|
-
videoElement.style.height = "100%";
|
214
|
-
videoElement.style.objectFit = "cover";
|
215
|
-
playerRef.current = videojs(videoElement, options, () => {
|
216
|
-
onReady(playerRef.current as Player);
|
217
|
-
});
|
257
|
+
videoElement.setAttribute("playsinline", "true");
|
258
|
+
|
259
|
+
videoElement.classList.add("vjs-big-play-centered");
|
260
|
+
// Set the poster attribute here
|
261
|
+
if (poster) {
|
262
|
+
videoElement.setAttribute("poster", poster);
|
218
263
|
}
|
219
|
-
|
220
|
-
|
264
|
+
videoRef.current.appendChild(videoElement);
|
265
|
+
videoElement.style.width = "100%";
|
266
|
+
videoElement.style.height = "100%";
|
267
|
+
videoElement.style.objectFit = "cover";
|
268
|
+
playerRef.current = videojs(videoElement, options, () => {
|
269
|
+
onReady(playerRef.current as Player);
|
270
|
+
});
|
271
|
+
}
|
272
|
+
return () => {
|
273
|
+
if (playerRef.current) {
|
274
|
+
if (!isEqual(idRef?.current?.sources ?? "", options.sources)) {
|
221
275
|
idRef.current = options;
|
222
276
|
playerRef.current.dispose();
|
223
277
|
playerRef.current = undefined;
|
224
|
-
|
225
278
|
setTimeout(() => {
|
226
279
|
if (bigPlayButtonRoot[id]) {
|
227
280
|
bigPlayButtonRoot[id].unmount();
|
@@ -232,386 +285,329 @@ const VideoPlayerComponent = forwardRef<HTMLDivElement, Props<any>>(
|
|
232
285
|
controlBarRoot[id] = undefined;
|
233
286
|
}
|
234
287
|
}, 0);
|
235
|
-
|
236
|
-
// setTimeout(() => {
|
237
|
-
// if (bigPlayButtonRoot[id]) {
|
238
|
-
// bigPlayButtonRoot[id].unmount();
|
239
|
-
// bigPlayButtonRoot[id] = undefined;
|
240
|
-
// }
|
241
|
-
// if (controlBarRoot[id]) {
|
242
|
-
// controlBarRoot[id].unmount();
|
243
|
-
// controlBarRoot[id] = undefined;
|
244
|
-
// }
|
245
|
-
// }, 0);
|
246
288
|
}
|
247
|
-
};
|
248
|
-
}, [id]);
|
249
|
-
|
250
|
-
useEffect(() => {
|
251
|
-
if (playerRef.current) {
|
252
|
-
const myPlayer = playerRef.current.currentSources();
|
253
|
-
playerRef.current.src(options.sources);
|
254
|
-
playerRef.current.load();
|
255
|
-
}
|
256
|
-
}, [options.sources[0].type]);
|
257
|
-
useEffect(() => {
|
258
|
-
if (!playerRef.current) {
|
259
|
-
const videoElement = document.createElement("video-js");
|
260
|
-
|
261
|
-
videoElement.setAttribute("playsinline", "true");
|
262
289
|
|
263
|
-
|
264
|
-
//
|
265
|
-
|
266
|
-
|
267
|
-
}
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
onReady(playerRef.current as Player);
|
274
|
-
});
|
290
|
+
// setTimeout(() => {
|
291
|
+
// if (bigPlayButtonRoot[id]) {
|
292
|
+
// bigPlayButtonRoot[id].unmount();
|
293
|
+
// bigPlayButtonRoot[id] = undefined;
|
294
|
+
// }
|
295
|
+
// if (controlBarRoot[id]) {
|
296
|
+
// controlBarRoot[id].unmount();
|
297
|
+
// controlBarRoot[id] = undefined;
|
298
|
+
// }
|
299
|
+
// }, 0);
|
275
300
|
}
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
idRef.current = options;
|
280
|
-
playerRef.current.dispose();
|
281
|
-
playerRef.current = undefined;
|
282
|
-
setTimeout(() => {
|
283
|
-
if (bigPlayButtonRoot[id]) {
|
284
|
-
bigPlayButtonRoot[id].unmount();
|
285
|
-
bigPlayButtonRoot[id] = undefined;
|
286
|
-
}
|
287
|
-
if (controlBarRoot[id]) {
|
288
|
-
controlBarRoot[id].unmount();
|
289
|
-
controlBarRoot[id] = undefined;
|
290
|
-
}
|
291
|
-
}, 0);
|
292
|
-
}
|
293
|
-
|
294
|
-
// setTimeout(() => {
|
295
|
-
// if (bigPlayButtonRoot[id]) {
|
296
|
-
// bigPlayButtonRoot[id].unmount();
|
297
|
-
// bigPlayButtonRoot[id] = undefined;
|
298
|
-
// }
|
299
|
-
// if (controlBarRoot[id]) {
|
300
|
-
// controlBarRoot[id].unmount();
|
301
|
-
// controlBarRoot[id] = undefined;
|
302
|
-
// }
|
303
|
-
// }, 0);
|
304
|
-
}
|
305
|
-
};
|
306
|
-
}, [options]);
|
307
|
-
// Added poster to dependency array
|
301
|
+
};
|
302
|
+
}, [options]);
|
303
|
+
// Added poster to dependency array
|
308
304
|
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
}
|
305
|
+
useEffect(() => {
|
306
|
+
if (playerRef.current) {
|
307
|
+
playerRef.current.currentTime(startTime);
|
308
|
+
}
|
309
|
+
}, [startTime]);
|
310
|
+
useEffect(() => {
|
311
|
+
if (playerRef.current && isReady) {
|
312
|
+
const currentTime = playerRef.current.currentTime() || 0;
|
313
|
+
if (isPaused) {
|
314
|
+
if (onPause) onPause(currentTime);
|
315
|
+
} else {
|
316
|
+
if (onPlay) onPlay(currentTime);
|
322
317
|
}
|
323
|
-
}
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
318
|
+
}
|
319
|
+
}, [isPaused]);
|
320
|
+
|
321
|
+
useEffect(() => {
|
322
|
+
const controlBarTimeout = setTimeout(() => {
|
323
|
+
renderControlBar(
|
324
|
+
id,
|
325
|
+
playerRef.current,
|
326
|
+
isPaused,
|
327
|
+
setIsPaused,
|
328
|
+
duration,
|
329
|
+
notes,
|
330
|
+
chapters,
|
331
|
+
5,
|
332
|
+
handleSaveNoteAction,
|
333
|
+
opacity,
|
334
|
+
(e: any) => {
|
335
|
+
handlePlayerClick(e, true);
|
336
|
+
},
|
337
|
+
bgColor,
|
338
|
+
setIsQualityMenuOpen,
|
339
|
+
setIsSubtitleMenuOpen,
|
340
|
+
disableNote,
|
341
|
+
setNoteOpen,
|
342
|
+
noteButtonClick,
|
343
|
+
isTrailer
|
344
|
+
);
|
345
|
+
}, 0);
|
346
|
+
return () => clearTimeout(controlBarTimeout);
|
347
|
+
}, [
|
348
|
+
isPaused,
|
349
|
+
setIsPaused,
|
350
|
+
notes,
|
351
|
+
handleSaveNoteAction,
|
352
|
+
duration,
|
353
|
+
opacity,
|
354
|
+
isReady,
|
355
|
+
id,
|
356
|
+
playerRef?.current?.isFullscreen_,
|
357
|
+
]);
|
358
|
+
useEffect(() => {
|
359
|
+
if (isReady) {
|
360
|
+
const playButtonTimeout = setTimeout(() => {
|
361
|
+
renderBigPlayButton(
|
328
362
|
id,
|
329
363
|
playerRef.current,
|
330
364
|
isPaused,
|
331
365
|
setIsPaused,
|
332
|
-
duration,
|
333
|
-
notes,
|
334
|
-
chapters,
|
335
|
-
5,
|
336
|
-
handleSaveNoteAction,
|
337
366
|
opacity,
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
bgColor,
|
342
|
-
setIsQualityMenuOpen,
|
343
|
-
setIsSubtitleMenuOpen,
|
344
|
-
disableNote,
|
345
|
-
setNoteOpen,
|
346
|
-
noteButtonClick,
|
347
|
-
isTrailer
|
367
|
+
height,
|
368
|
+
heightValue,
|
369
|
+
isLoading
|
348
370
|
);
|
349
|
-
},
|
350
|
-
return () => clearTimeout(
|
351
|
-
}
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
}, 500);
|
384
|
-
return () => clearInterval(intervalId);
|
371
|
+
}, 500);
|
372
|
+
return () => clearTimeout(playButtonTimeout);
|
373
|
+
}
|
374
|
+
}, [isPaused, opacity, isReady, id, height, heightValue, isLoading]);
|
375
|
+
useEffect(() => {
|
376
|
+
if (playerRef.current) {
|
377
|
+
const intervalId = setInterval(() => {
|
378
|
+
if (playerRef.current) setIsPaused(playerRef.current.paused());
|
379
|
+
}, 500);
|
380
|
+
return () => clearInterval(intervalId);
|
381
|
+
}
|
382
|
+
}, []);
|
383
|
+
// useEffect(() => {
|
384
|
+
// return () => {
|
385
|
+
// if (playerRef.current) {
|
386
|
+
// playerRef.current.dispose();
|
387
|
+
// playerRef.current = undefined;
|
388
|
+
// // Cleanup play button and control bar renders
|
389
|
+
// if (bigPlayButtonRoot[id]) {
|
390
|
+
// bigPlayButtonRoot[id].unmount();
|
391
|
+
// bigPlayButtonRoot[id] = undefined;
|
392
|
+
// }
|
393
|
+
// if (controlBarRoot[id]) {
|
394
|
+
// controlBarRoot[id].unmount();
|
395
|
+
// controlBarRoot[id] = undefined;
|
396
|
+
// }
|
397
|
+
// }
|
398
|
+
// };
|
399
|
+
// }, []);
|
400
|
+
const timeoutRef = useRef<any>(null);
|
401
|
+
useEffect(() => {
|
402
|
+
if (isQualityMenuOpen || isSubtitleMenuOpen) {
|
403
|
+
if (timeoutRef.current) {
|
404
|
+
clearTimeout(timeoutRef.current);
|
385
405
|
}
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
// playerRef.current.dispose();
|
391
|
-
// playerRef.current = undefined;
|
392
|
-
// // Cleanup play button and control bar renders
|
393
|
-
// if (bigPlayButtonRoot[id]) {
|
394
|
-
// bigPlayButtonRoot[id].unmount();
|
395
|
-
// bigPlayButtonRoot[id] = undefined;
|
396
|
-
// }
|
397
|
-
// if (controlBarRoot[id]) {
|
398
|
-
// controlBarRoot[id].unmount();
|
399
|
-
// controlBarRoot[id] = undefined;
|
400
|
-
// }
|
401
|
-
// }
|
402
|
-
// };
|
403
|
-
// }, []);
|
404
|
-
const timeoutRef = useRef<any>(null);
|
405
|
-
useEffect(() => {
|
406
|
-
if (isQualityMenuOpen || isSubtitleMenuOpen) {
|
407
|
-
if (timeoutRef.current) {
|
408
|
-
clearTimeout(timeoutRef.current);
|
409
|
-
}
|
410
|
-
setOpacity("100");
|
411
|
-
} else {
|
412
|
-
if (timeoutRef.current) {
|
413
|
-
clearTimeout(timeoutRef.current);
|
414
|
-
}
|
415
|
-
setOpacity("0");
|
416
|
-
|
417
|
-
timeoutRef.current = setTimeout(() => {
|
418
|
-
setIsControlBarPresent(false);
|
419
|
-
}, 3000);
|
406
|
+
setOpacity("100");
|
407
|
+
} else {
|
408
|
+
if (timeoutRef.current) {
|
409
|
+
clearTimeout(timeoutRef.current);
|
420
410
|
}
|
421
|
-
|
422
|
-
useEffect(() => {
|
423
|
-
if (isNoteOpen) {
|
424
|
-
if (timeoutRef.current) {
|
425
|
-
clearTimeout(timeoutRef.current);
|
426
|
-
}
|
427
|
-
} else {
|
428
|
-
if (timeoutRef.current) {
|
429
|
-
clearTimeout(timeoutRef.current);
|
430
|
-
}
|
411
|
+
setOpacity("0");
|
431
412
|
|
432
|
-
|
433
|
-
|
434
|
-
|
413
|
+
timeoutRef.current = setTimeout(() => {
|
414
|
+
setIsControlBarPresent(false);
|
415
|
+
}, 3000);
|
416
|
+
}
|
417
|
+
}, [isQualityMenuOpen, isSubtitleMenuOpen]);
|
418
|
+
useEffect(() => {
|
419
|
+
if (isNoteOpen) {
|
420
|
+
if (timeoutRef.current) {
|
421
|
+
clearTimeout(timeoutRef.current);
|
435
422
|
}
|
436
|
-
}
|
437
|
-
|
438
|
-
const handlePlayerClick = async (e: any, isTimerOnly = false) => {
|
439
|
-
e.preventDefault();
|
423
|
+
} else {
|
440
424
|
if (timeoutRef.current) {
|
441
425
|
clearTimeout(timeoutRef.current);
|
442
426
|
}
|
443
|
-
|
444
|
-
setIsControlBarPresent(true);
|
445
|
-
// setBgColor("rgba(200, 200, 200, 0.5)");
|
446
|
-
// not using now
|
427
|
+
|
447
428
|
timeoutRef.current = setTimeout(() => {
|
448
|
-
setOpacity("0");
|
449
|
-
setBgColor("transparent");
|
450
429
|
setIsControlBarPresent(false);
|
451
430
|
}, 3000);
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
431
|
+
}
|
432
|
+
}, [isNoteOpen]);
|
433
|
+
|
434
|
+
const handlePlayerClick = async (e: any, isTimerOnly = false) => {
|
435
|
+
e.preventDefault();
|
436
|
+
if (timeoutRef.current) {
|
437
|
+
clearTimeout(timeoutRef.current);
|
438
|
+
}
|
439
|
+
setOpacity("100");
|
440
|
+
setIsControlBarPresent(true);
|
441
|
+
// setBgColor("rgba(200, 200, 200, 0.5)");
|
442
|
+
// not using now
|
443
|
+
timeoutRef.current = setTimeout(() => {
|
444
|
+
setOpacity("0");
|
445
|
+
setBgColor("transparent");
|
446
|
+
setIsControlBarPresent(false);
|
447
|
+
}, 3000);
|
448
|
+
if (isTimerOnly) {
|
449
|
+
return;
|
450
|
+
}
|
451
|
+
if (!isControlBarPresent) {
|
452
|
+
return;
|
453
|
+
}
|
454
|
+
if (playerRef.current) {
|
455
|
+
if (playerRef.current.paused()) {
|
456
|
+
try {
|
457
|
+
await playerRef.current.play();
|
458
|
+
setIsPaused(false);
|
459
|
+
} catch (error) {
|
460
|
+
console.error("Failed to play video:", error);
|
470
461
|
}
|
462
|
+
} else {
|
463
|
+
playerRef.current.pause();
|
464
|
+
setIsPaused(true);
|
465
|
+
if (onPause) onPause(playerRef.current.currentTime() || 0);
|
471
466
|
}
|
472
|
-
}
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
467
|
+
}
|
468
|
+
};
|
469
|
+
const videoRefs = useRef<HTMLDivElement>(null); // Create a reference for the element
|
470
|
+
|
471
|
+
useEffect(() => {
|
472
|
+
const observer = new IntersectionObserver(
|
473
|
+
(entries) => {
|
474
|
+
entries.forEach((entry) => {
|
475
|
+
if (entry.isIntersecting === false) {
|
476
|
+
if (playerRef?.current?.paused() === false) {
|
477
|
+
try {
|
478
|
+
playerRef?.current?.pause();
|
479
|
+
setIsPaused(true);
|
480
|
+
} catch (error) {
|
481
|
+
console.error("Failed to play video:", error);
|
487
482
|
}
|
488
483
|
}
|
489
|
-
}
|
490
|
-
}
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
484
|
+
}
|
485
|
+
});
|
486
|
+
},
|
487
|
+
{
|
488
|
+
threshold: 0.1, // The amount of the component that must be visible (0.1 means 10% visible)
|
489
|
+
}
|
490
|
+
);
|
491
|
+
|
492
|
+
if (videoRefs.current) {
|
493
|
+
observer.observe(videoRefs.current); // Start observing the component
|
494
|
+
}
|
495
495
|
|
496
|
+
return () => {
|
496
497
|
if (videoRefs.current) {
|
497
|
-
observer.
|
498
|
+
observer.unobserve(videoRef.current); // Clean up the observer when the component unmounts
|
498
499
|
}
|
500
|
+
};
|
501
|
+
}, []);
|
499
502
|
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
const currentTime = playerRef.current.currentTime();
|
512
|
-
const duration = playerRef.current.duration();
|
513
|
-
|
514
|
-
if (duration && currentTime !== undefined) {
|
515
|
-
setTimeSeeker(`${(currentTime / duration) * 100}%`);
|
516
|
-
} else {
|
517
|
-
setTimeSeeker("0");
|
518
|
-
}
|
503
|
+
const [timeSeeker, setTimeSeeker] = useState<string>("0");
|
504
|
+
useEffect(() => {
|
505
|
+
const updateTimeSeeker = () => {
|
506
|
+
if (playerRef.current && isReady) {
|
507
|
+
const currentTime = playerRef.current.currentTime();
|
508
|
+
const duration = playerRef.current.duration();
|
509
|
+
|
510
|
+
if (duration && currentTime !== undefined) {
|
511
|
+
setTimeSeeker(`${(currentTime / duration) * 100}%`);
|
512
|
+
} else {
|
513
|
+
setTimeSeeker("0");
|
519
514
|
}
|
520
|
-
}
|
515
|
+
}
|
516
|
+
};
|
517
|
+
|
518
|
+
const interval = setInterval(updateTimeSeeker, 500); // Update every 500ms
|
521
519
|
|
522
|
-
|
520
|
+
return () => clearInterval(interval); // Cleanup interval on unmount
|
521
|
+
}, [playerRef]);
|
523
522
|
|
524
|
-
|
525
|
-
}, [playerRef]);
|
523
|
+
const container = document.getElementById(`video-container-${id}`);
|
526
524
|
|
527
|
-
|
525
|
+
function handleWidthChange(height: any) {
|
526
|
+
setHeightValue(height);
|
527
|
+
}
|
528
528
|
|
529
|
-
|
530
|
-
|
529
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
530
|
+
for (let entry of entries) {
|
531
|
+
const currentHeight = entry.contentRect.height;
|
532
|
+
handleWidthChange(currentHeight); // Call the action when width changes
|
531
533
|
}
|
534
|
+
});
|
532
535
|
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
536
|
+
// Start observing the element
|
537
|
+
const controlBar = container?.querySelector(".vjs-control-bar");
|
538
|
+
if (controlBar) {
|
539
|
+
resizeObserver.observe(controlBar);
|
540
|
+
}
|
541
|
+
function debounce(
|
542
|
+
func: (arg: boolean) => void, // The function type should accept a boolean argument
|
543
|
+
delay: number
|
544
|
+
) {
|
545
|
+
let timeoutId: any;
|
546
|
+
|
547
|
+
return function (arg: boolean) {
|
548
|
+
if (timeoutId) {
|
549
|
+
clearTimeout(timeoutId);
|
537
550
|
}
|
538
|
-
});
|
539
551
|
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
function debounce(
|
546
|
-
func: (arg: boolean) => void, // The function type should accept a boolean argument
|
547
|
-
delay: number
|
548
|
-
) {
|
549
|
-
let timeoutId: any;
|
550
|
-
|
551
|
-
return function (arg: boolean) {
|
552
|
-
if (timeoutId) {
|
553
|
-
clearTimeout(timeoutId);
|
554
|
-
}
|
555
|
-
|
556
|
-
timeoutId = setTimeout(() => {
|
557
|
-
func(arg);
|
558
|
-
}, delay);
|
559
|
-
};
|
560
|
-
}
|
552
|
+
timeoutId = setTimeout(() => {
|
553
|
+
func(arg);
|
554
|
+
}, delay);
|
555
|
+
};
|
556
|
+
}
|
561
557
|
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
558
|
+
if (playerRef.current) {
|
559
|
+
playerRef.current.on("waiting", function () {
|
560
|
+
debounce((arg) => setIsloading(arg), 300)(true);
|
561
|
+
});
|
566
562
|
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
563
|
+
playerRef.current.on("playing", function () {
|
564
|
+
debounce((arg) => setIsloading(arg), 300)(false);
|
565
|
+
});
|
566
|
+
}
|
567
|
+
return (
|
568
|
+
<>
|
569
|
+
<Suspense
|
570
|
+
fallback={
|
571
|
+
<SvgSkillamiIcon className=" sb-w-16 sb-h-16 sb-animate-spin sb-absolute -sb-top-2 -sb-right-2 "></SvgSkillamiIcon>
|
572
|
+
}
|
573
|
+
>
|
574
|
+
<div
|
575
|
+
ref={videoRefs}
|
576
|
+
id={`video-container-${id}`}
|
577
|
+
onMouseMove={() => {
|
578
|
+
!isNoteOpen ? handlePlayerClick(event, true) : "";
|
579
|
+
}}
|
580
|
+
className="sb-relative sb-rounded-md sb-overflow-hidden sb-w-full sb-h-full sb-bottom-2 "
|
581
|
+
onMouseEnter={() => setIsHovered(true)}
|
582
|
+
onMouseLeave={() => setIsHovered(false)}
|
577
583
|
>
|
584
|
+
{bottomRedBar && (
|
585
|
+
<div
|
586
|
+
ref={childRef}
|
587
|
+
onClick={handlePlayerClick}
|
588
|
+
className={`sb-h-[3px] sb-transition-opacity sb-duration-500 sb-delay-400 sb-z-10 ease-in-out sb-border-spacing-x-2 sb-absolute sb-bg-[red] sb-bottom-0 ${
|
589
|
+
opacity == "100" ? "sb-opacity-0" : "sb-opacity-100"
|
590
|
+
}`}
|
591
|
+
style={{
|
592
|
+
width: timeSeeker,
|
593
|
+
}}
|
594
|
+
></div>
|
595
|
+
)}
|
578
596
|
<div
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
!isNoteOpen ? handlePlayerClick(event, true) : "";
|
583
|
-
}}
|
584
|
-
className="sb-relative sb-rounded-md sb-overflow-hidden sb-w-full sb-h-full sb-bottom-2 "
|
585
|
-
onMouseEnter={() => setIsHovered(true)}
|
586
|
-
onMouseLeave={() => setIsHovered(false)}
|
597
|
+
className="hover:sb-cursor-pointer sb-w-full sb-h-full"
|
598
|
+
// Attach click event
|
599
|
+
data-vjs-player
|
587
600
|
>
|
588
|
-
{bottomRedBar && (
|
589
|
-
<div
|
590
|
-
ref={childRef}
|
591
|
-
onClick={handlePlayerClick}
|
592
|
-
className={`sb-h-[3px] sb-transition-opacity sb-duration-500 sb-delay-400 sb-z-10 ease-in-out sb-border-spacing-x-2 sb-absolute sb-bg-[red] sb-bottom-0 ${
|
593
|
-
opacity == "100" ? "sb-opacity-0" : "sb-opacity-100"
|
594
|
-
}`}
|
595
|
-
style={{
|
596
|
-
width: timeSeeker,
|
597
|
-
}}
|
598
|
-
></div>
|
599
|
-
)}
|
600
601
|
<div
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
>
|
605
|
-
<div
|
606
|
-
onClick={handlePlayerClick}
|
607
|
-
ref={videoRef}
|
608
|
-
className="sb-h-full sb-w-full sb-relative"
|
609
|
-
></div>
|
610
|
-
</div>
|
602
|
+
onClick={handlePlayerClick}
|
603
|
+
ref={videoRef}
|
604
|
+
className="sb-h-full sb-w-full sb-relative"
|
605
|
+
></div>
|
611
606
|
</div>
|
612
|
-
</
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
607
|
+
</div>
|
608
|
+
</Suspense>
|
609
|
+
</>
|
610
|
+
);
|
611
|
+
};
|
612
|
+
|
617
613
|
export default VideoPlayerComponent;
|