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.
@@ -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 { isEqual } from "lodash";
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
- id,
137
- options,
138
- notes,
139
- chapters,
140
- startTime = 0,
141
- handleSaveNoteAction,
142
- poster,
143
- onPlay,
144
- onPause,
145
- disableNote,
146
- childRef,
147
- bottomRedBar = true,
148
- noteButtonClick,
149
- }: Props,
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
- const initializePlayer = () => {
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
- playerRef.current = videojs(videoElement, options, () => {
196
- playerRef.current?.currentTime(startTime);
197
- });
198
- onReady(playerRef.current);
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
- console.log(playerRef.current, options, "jk");
215
- if (!isEqual(playerRef.current.poster_, poster)) {
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, isReady]);
248
+ }, [isPaused]);
243
249
 
244
250
  useEffect(() => {
245
- if (isReady) {
246
- const controlBarTimeout = setTimeout(() => {
247
- console.log("isReady: ", isReady);
248
-
249
- renderControlBar(
250
- id,
251
- playerRef.current,
252
- isPaused,
253
- setIsPaused,
254
- duration,
255
- notes,
256
- chapters,
257
- 5,
258
- handleSaveNoteAction,
259
- opacity,
260
- (e: any) => {
261
- handlePlayerClick(e, true);
262
- },
263
- bgColor,
264
- setIsQualityMenuOpen,
265
- setIsSubtitleMenuOpen,
266
- disableNote,
267
- setNoteOpen,
268
- noteButtonClick
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
- }, [id, isPaused, isReady, opacity, options, notes]);
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
- if (playerRef.current) {
322
- playerRef.current?.currentTime(startTime);
323
- console.log("startTimenotes: ", startTime);
324
- playerRef.current?.play();
325
- }
326
- }, [startTime]);
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("notes: ", notes);
349
- }, [notes]);
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={(e) => {
449
- handlePlayerClick(e, true);
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