mishig HF Staff commited on
Commit
e52c9fe
·
verified ·
1 Parent(s): 975bf06

Sync from GitHub via hub-sync

Browse files
src/components/simple-videos-player.tsx CHANGED
@@ -85,6 +85,25 @@ export const SimpleVideosPlayer = ({
85
 
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];
@@ -100,9 +119,13 @@ export const SimpleVideosPlayer = ({
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
  }
@@ -141,9 +164,13 @@ export const SimpleVideosPlayer = ({
141
  const handleEnded = info.isSegmented
142
  ? null
143
  : () => {
144
- video.currentTime = 0;
 
 
145
  if (index === firstVisibleIdxRef.current) {
146
- setCurrentTime(0);
 
 
147
  }
148
  };
149
 
 
85
 
86
  const timeout = setTimeout(markReady, VIDEO_READY_TIMEOUT_MS);
87
 
88
+ // Coordinated loop reset — when the primary video hits its segment end
89
+ // (or natural end), seek every camera to its own segmentStart in a
90
+ // single synchronous burst. The previous design seeked the primary,
91
+ // then bumped externalSeekVersion which scheduled the other seeks via
92
+ // a React render — leaving an 80ms (throttled) gap where the primary
93
+ // played fresh frames while the others still showed the segment-end
94
+ // frame. Now the gap is microseconds.
95
+ const loopAllVideos = () => {
96
+ videoRefs.current.forEach((other, otherIdx) => {
97
+ if (!other) return;
98
+ const otherInfo = videosInfo[otherIdx];
99
+ if (!otherInfo) return;
100
+ other.currentTime = otherInfo.segmentStart || 0;
101
+ });
102
+ // Update the slider as a status report — don't bump externalSeekVersion
103
+ // since we already drove every video to its target.
104
+ setCurrentTime(0, "video");
105
+ };
106
+
107
  videoRefs.current.forEach((video, index) => {
108
  if (!video) return;
109
  const info = videosInfo[index];
 
119
  video.currentTime >=
120
  segmentEnd - THRESHOLDS.VIDEO_SEGMENT_BOUNDARY
121
  ) {
122
+ // Primary drives the coordinated loop. Non-primary cameras
123
+ // that race ahead just snap to segmentStart and wait — the
124
+ // primary's next loop will re-align everyone.
125
  if (index === firstVisibleIdxRef.current) {
126
+ loopAllVideos();
127
+ } else {
128
+ video.currentTime = segmentStart;
129
  }
130
  return;
131
  }
 
164
  const handleEnded = info.isSegmented
165
  ? null
166
  : () => {
167
+ // Same coordinated loop strategy for non-segmented videos at
168
+ // their natural end — primary drives, others wait for primary
169
+ // to align them.
170
  if (index === firstVisibleIdxRef.current) {
171
+ loopAllVideos();
172
+ } else {
173
+ video.currentTime = 0;
174
  }
175
  };
176