mishig HF Staff commited on
Commit
0f1dfd5
·
verified ·
1 Parent(s): c753514

Sync from GitHub via hub-sync

Browse files
src/components/simple-videos-player.tsx CHANGED
@@ -1,6 +1,6 @@
1
  "use client";
2
 
3
- import React, { useEffect, useRef, useCallback } from "react";
4
  import { useTime } from "../context/time-context";
5
  import { FaExpand, FaCompress, FaTimes, FaEye } from "react-icons/fa";
6
  import type { VideoInfo } from "@/types";
@@ -86,53 +86,84 @@ export const SimpleVideosPlayer = ({
86
  const timeout = setTimeout(markReady, VIDEO_READY_TIMEOUT_MS);
87
 
88
  videoRefs.current.forEach((video, index) => {
89
- if (video) {
90
- const info = videosInfo[index];
91
 
 
 
 
 
92
  if (info.isSegmented) {
93
- const handleTimeUpdate = () => {
94
- const segmentEnd = info.segmentEnd || video.duration;
95
- const segmentStart = info.segmentStart || 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
 
 
 
 
 
 
97
  if (
98
- video.currentTime >=
99
- segmentEnd - THRESHOLDS.VIDEO_SEGMENT_BOUNDARY
100
  ) {
101
  video.currentTime = segmentStart;
102
- if (index === firstVisibleIdxRef.current) {
103
- setCurrentTime(0);
104
- }
105
  }
106
- };
 
107
 
108
- const handleLoadedData = () => {
 
109
  video.currentTime = info.segmentStart || 0;
110
  checkReady();
111
- };
112
-
113
- video.addEventListener("timeupdate", handleTimeUpdate);
114
- video.addEventListener("loadeddata", handleLoadedData);
115
 
116
- videoEventCleanup.set(video, () => {
117
- video.removeEventListener("timeupdate", handleTimeUpdate);
118
- video.removeEventListener("loadeddata", handleLoadedData);
119
- });
120
- } else {
121
- const handleEnded = () => {
122
  video.currentTime = 0;
123
  if (index === firstVisibleIdxRef.current) {
124
  setCurrentTime(0);
125
  }
126
  };
127
 
128
- video.addEventListener("ended", handleEnded);
129
- video.addEventListener("canplaythrough", checkReady, { once: true });
130
-
131
- videoEventCleanup.set(video, () => {
132
- video.removeEventListener("ended", handleEnded);
133
- });
134
- }
135
  }
 
 
 
 
 
 
 
 
 
136
  });
137
 
138
  return () => {
@@ -198,43 +229,6 @@ export const SimpleVideosPlayer = ({
198
  });
199
  }, [externalSeekVersion, currentTime, videosInfo, videosReady, hiddenSet]);
200
 
201
- // Stable per-index timeupdate handlers avoid findIndex scan on every event.
202
- // Tagged "video" so the context doesn't bump externalSeekVersion — the
203
- // sync effect treats this as a status report, not a seek command.
204
- const makeTimeUpdateHandler = useCallback(
205
- (index: number) => {
206
- return () => {
207
- const video = videoRefs.current[index];
208
- const info = videosInfo[index];
209
- if (!video || !info) return;
210
-
211
- let globalTime = video.currentTime;
212
- if (info.isSegmented) {
213
- globalTime = video.currentTime - (info.segmentStart || 0);
214
- }
215
- setCurrentTime(globalTime, "video");
216
- };
217
- },
218
- [videosInfo, setCurrentTime],
219
- );
220
-
221
- // Handle play click for segmented videos
222
- const handlePlay = (video: HTMLVideoElement, info: VideoInfo) => {
223
- if (info.isSegmented) {
224
- const segmentStart = info.segmentStart || 0;
225
- const segmentEnd = info.segmentEnd || video.duration;
226
-
227
- if (video.currentTime < segmentStart || video.currentTime >= segmentEnd) {
228
- video.currentTime = segmentStart;
229
- }
230
- }
231
- video.play().catch((e: unknown) => {
232
- if ((e as Error)?.name !== "AbortError") {
233
- console.error("Error playing video", e);
234
- }
235
- });
236
- };
237
-
238
  return (
239
  <>
240
  {/* Hidden videos menu */}
@@ -275,7 +269,6 @@ export const SimpleVideosPlayer = ({
275
  if (hiddenVideos.includes(info.filename)) return null;
276
 
277
  const isEnlarged = enlargedVideo === info.filename;
278
- const isFirstVisible = idx === firstVisibleIdx;
279
 
280
  return (
281
  <div
@@ -328,10 +321,6 @@ export const SimpleVideosPlayer = ({
328
  muted
329
  preload="auto"
330
  crossOrigin="anonymous"
331
- onPlay={(e) => handlePlay(e.currentTarget, info)}
332
- onTimeUpdate={
333
- isFirstVisible ? makeTimeUpdateHandler(idx) : undefined
334
- }
335
  >
336
  <source src={proxyHfUrl(info.url)} type="video/mp4" />
337
  Your browser does not support the video tag.
 
1
  "use client";
2
 
3
+ import React, { useEffect, useRef } from "react";
4
  import { useTime } from "../context/time-context";
5
  import { FaExpand, FaCompress, FaTimes, FaEye } from "react-icons/fa";
6
  import type { VideoInfo } from "@/types";
 
86
  const timeout = setTimeout(markReady, VIDEO_READY_TIMEOUT_MS);
87
 
88
  videoRefs.current.forEach((video, index) => {
89
+ if (!video) return;
90
+ const info = videosInfo[index];
91
 
92
+ // One timeupdate handler per video covers both jobs:
93
+ // (a) loop-reset on segmented videos at segment-end
94
+ // (b) reporting the primary video's currentTime back to the context
95
+ const handleTimeUpdate = () => {
96
  if (info.isSegmented) {
97
+ const segmentEnd = info.segmentEnd || video.duration;
98
+ const segmentStart = info.segmentStart || 0;
99
+ if (
100
+ video.currentTime >=
101
+ segmentEnd - THRESHOLDS.VIDEO_SEGMENT_BOUNDARY
102
+ ) {
103
+ video.currentTime = segmentStart;
104
+ if (index === firstVisibleIdxRef.current) {
105
+ setCurrentTime(0);
106
+ }
107
+ return;
108
+ }
109
+ }
110
+ if (index === firstVisibleIdxRef.current) {
111
+ let globalTime = video.currentTime;
112
+ if (info.isSegmented) {
113
+ globalTime = video.currentTime - (info.segmentStart || 0);
114
+ }
115
+ setCurrentTime(globalTime, "video");
116
+ }
117
+ };
118
 
119
+ // For segmented videos, snap into the segment when play() is called
120
+ // — covers the case where the user paused outside the segment range.
121
+ const handlePlay = info.isSegmented
122
+ ? () => {
123
+ const segmentStart = info.segmentStart || 0;
124
+ const segmentEnd = info.segmentEnd || video.duration;
125
  if (
126
+ video.currentTime < segmentStart ||
127
+ video.currentTime >= segmentEnd
128
  ) {
129
  video.currentTime = segmentStart;
 
 
 
130
  }
131
+ }
132
+ : null;
133
 
134
+ const handleLoadedData = info.isSegmented
135
+ ? () => {
136
  video.currentTime = info.segmentStart || 0;
137
  checkReady();
138
+ }
139
+ : null;
 
 
140
 
141
+ const handleEnded = info.isSegmented
142
+ ? null
143
+ : () => {
 
 
 
144
  video.currentTime = 0;
145
  if (index === firstVisibleIdxRef.current) {
146
  setCurrentTime(0);
147
  }
148
  };
149
 
150
+ video.addEventListener("timeupdate", handleTimeUpdate);
151
+ if (handlePlay) video.addEventListener("play", handlePlay);
152
+ if (handleLoadedData)
153
+ video.addEventListener("loadeddata", handleLoadedData);
154
+ if (handleEnded) video.addEventListener("ended", handleEnded);
155
+ if (!info.isSegmented) {
156
+ video.addEventListener("canplaythrough", checkReady, { once: true });
157
  }
158
+
159
+ videoEventCleanup.set(video, () => {
160
+ video.removeEventListener("timeupdate", handleTimeUpdate);
161
+ if (handlePlay) video.removeEventListener("play", handlePlay);
162
+ if (handleLoadedData)
163
+ video.removeEventListener("loadeddata", handleLoadedData);
164
+ if (handleEnded) video.removeEventListener("ended", handleEnded);
165
+ video.removeEventListener("canplaythrough", checkReady);
166
+ });
167
  });
168
 
169
  return () => {
 
229
  });
230
  }, [externalSeekVersion, currentTime, videosInfo, videosReady, hiddenSet]);
231
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  return (
233
  <>
234
  {/* Hidden videos menu */}
 
269
  if (hiddenVideos.includes(info.filename)) return null;
270
 
271
  const isEnlarged = enlargedVideo === info.filename;
 
272
 
273
  return (
274
  <div
 
321
  muted
322
  preload="auto"
323
  crossOrigin="anonymous"
 
 
 
 
324
  >
325
  <source src={proxyHfUrl(info.url)} type="video/mp4" />
326
  Your browser does not support the video tag.