Skip to content

Commit 26c4ca6

Browse files
committed
Pass and use fallback duration in players
1 parent d2a37be commit 26c4ca6

File tree

5 files changed

+44
-13
lines changed

5 files changed

+44
-13
lines changed

apps/web/app/embed/[videoId]/_components/EmbedVideo.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ export const EmbedVideo = forwardRef<
6868
useImperativeHandle(ref, () => videoRef.current as HTMLVideoElement);
6969

7070
const [transcriptData, setTranscriptData] = useState<TranscriptEntry[]>([]);
71-
const [longestDuration, setLongestDuration] = useState<number>(0);
71+
const [longestDuration, setLongestDuration] = useState<number>(
72+
data.duration ?? 0,
73+
);
7274
const [isPlaying, setIsPlaying] = useState(false);
7375
const [subtitleUrl, setSubtitleUrl] = useState<string | null>(null);
7476
const [chaptersUrl, setChaptersUrl] = useState<string | null>(null);
@@ -191,6 +193,7 @@ export const EmbedVideo = forwardRef<
191193
mediaPlayerClassName="w-full h-full"
192194
videoSrc={videoSrc}
193195
rawFallbackSrc={rawFallbackSrc}
196+
duration={data.duration}
194197
chaptersSrc={chaptersUrl || ""}
195198
captionsSrc={subtitleUrl || ""}
196199
videoRef={videoRef}
@@ -202,6 +205,7 @@ export const EmbedVideo = forwardRef<
202205
videoId={data.id}
203206
mediaPlayerClassName="w-full h-full"
204207
videoSrc={videoSrc}
208+
duration={data.duration}
205209
chaptersSrc={chaptersUrl || ""}
206210
captionsSrc={subtitleUrl || ""}
207211
videoRef={videoRef}

apps/web/app/s/[videoId]/_components/CapVideoPlayer.tsx

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ interface Props {
9797
isCaptionLoading?: boolean;
9898
hasCaptions?: boolean;
9999
canRetryProcessing?: boolean;
100+
duration?: number | null;
100101
}
101102

102103
export function CapVideoPlayer({
@@ -123,6 +124,7 @@ export function CapVideoPlayer({
123124
isCaptionLoading = false,
124125
hasCaptions = false,
125126
canRetryProcessing = false,
127+
duration: fallbackDuration,
126128
}: Props) {
127129
const [currentCue, setCurrentCue] = useState<string>("");
128130
const [controlsVisible, setControlsVisible] = useState(false);
@@ -134,7 +136,7 @@ export function CapVideoPlayer({
134136
const [isMobile, setIsMobile] = useState(false);
135137
const [hasError, setHasError] = useState(false);
136138
const [isRetryingProcessing, setIsRetryingProcessing] = useState(false);
137-
const [duration, setDuration] = useState(0);
139+
const [duration, setDuration] = useState(fallbackDuration ?? 0);
138140
const queryClient = useQueryClient();
139141

140142
useEffect(() => {
@@ -185,20 +187,30 @@ export function CapVideoPlayer({
185187
}, [videoSrc, rawFallbackSrc]);
186188

187189
// Track video duration for comment markers
190+
useEffect(() => {
191+
setDuration(fallbackDuration ?? 0);
192+
}, [fallbackDuration]);
193+
188194
useEffect(() => {
189195
const video = videoRef.current;
190196
if (!video) return;
191197

192198
const handleLoadedMetadata = () => {
193-
setDuration(video.duration);
199+
if (Number.isFinite(video.duration) && video.duration > 0) {
200+
setDuration(video.duration);
201+
}
194202
};
195203

204+
if (Number.isFinite(video.duration) && video.duration > 0) {
205+
setDuration(video.duration);
206+
}
207+
196208
video.addEventListener("loadedmetadata", handleLoadedMetadata);
197209

198210
return () => {
199211
video.removeEventListener("loadedmetadata", handleLoadedMetadata);
200212
};
201-
}, [videoRef.current]);
213+
}, [videoRef]);
202214

203215
// Track when all data is ready for comment markers
204216
const [markersReady, setMarkersReady] = useState(false);
@@ -695,7 +707,7 @@ export function CapVideoPlayer({
695707
// enhancedAudioMuted={enhancedAudioMuted}
696708
// setEnhancedAudioMuted={setEnhancedAudioMuted}
697709
/>
698-
<MediaPlayerTime />
710+
<MediaPlayerTime fallbackDuration={fallbackDuration} />
699711
</div>
700712
<div className="flex gap-2 items-center">
701713
{!disableCaptions && (

apps/web/app/s/[videoId]/_components/HLSVideoPlayer.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ interface Props {
8080
isCaptionLoading?: boolean;
8181
hasCaptions?: boolean;
8282
canRetryProcessing?: boolean;
83+
duration?: number | null;
8384
}
8485

8586
export function HLSVideoPlayer({
@@ -100,6 +101,7 @@ export function HLSVideoPlayer({
100101
isCaptionLoading = false,
101102
hasCaptions = false,
102103
canRetryProcessing = false,
104+
duration: fallbackDuration,
103105
}: Props) {
104106
const hlsInstance = useRef<Hls | null>(null);
105107
const [currentCue, setCurrentCue] = useState<string>("");
@@ -564,7 +566,7 @@ export function HLSVideoPlayer({
564566
// enhancedAudioMuted={enhancedAudioMuted}
565567
// setEnhancedAudioMuted={setEnhancedAudioMuted}
566568
/>
567-
<MediaPlayerTime />
569+
<MediaPlayerTime fallbackDuration={fallbackDuration} />
568570
</div>
569571
<div className="flex gap-2 items-center">
570572
{!disableCaptions && (

apps/web/app/s/[videoId]/_components/ShareVideo.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ export const ShareVideo = forwardRef<
216216
mediaPlayerClassName="w-full h-full max-w-full max-h-full rounded-xl overflow-visible"
217217
videoSrc={videoSrc}
218218
rawFallbackSrc={rawFallbackSrc}
219+
duration={data.duration}
219220
disableCaptions={areCaptionsDisabled ?? false}
220221
disableCommentStamps={areCommentStampsDisabled ?? false}
221222
disableReactionStamps={areReactionStampsDisabled ?? false}
@@ -247,6 +248,7 @@ export const ShareVideo = forwardRef<
247248
videoId={data.id}
248249
mediaPlayerClassName="w-full h-full max-w-full max-h-full rounded-xl"
249250
videoSrc={videoSrc}
251+
duration={data.duration}
250252
disableCaptions={areCaptionsDisabled ?? false}
251253
chaptersSrc={areChaptersDisabled ? "" : chaptersUrl || ""}
252254
captionsSrc={areCaptionsDisabled ? "" : subtitleUrl || ""}

apps/web/app/s/[videoId]/_components/video/media-player.tsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2401,10 +2401,17 @@ function MediaPlayerVolume(props: MediaPlayerVolumeProps) {
24012401
interface MediaPlayerTimeProps extends React.ComponentProps<"div"> {
24022402
variant?: "progress" | "remaining" | "duration";
24032403
asChild?: boolean;
2404+
fallbackDuration?: number | null;
24042405
}
24052406

24062407
function MediaPlayerTime(props: MediaPlayerTimeProps) {
2407-
const { variant = "progress", asChild, className, ...timeProps } = props;
2408+
const {
2409+
variant = "progress",
2410+
asChild,
2411+
className,
2412+
fallbackDuration,
2413+
...timeProps
2414+
} = props;
24082415

24092416
const context = useMediaPlayerContext("MediaPlayerTime");
24102417
const mediaCurrentTime = useMediaSelector(
@@ -2413,28 +2420,32 @@ function MediaPlayerTime(props: MediaPlayerTimeProps) {
24132420
const [, seekableEnd = 0] = useMediaSelector(
24142421
(state) => state.mediaSeekable ?? [0, 0],
24152422
);
2423+
const effectiveDuration =
2424+
Number.isFinite(fallbackDuration) && (fallbackDuration ?? 0) > 0
2425+
? Math.max(seekableEnd, fallbackDuration ?? 0)
2426+
: seekableEnd;
24162427

24172428
const times = React.useMemo(() => {
24182429
if (variant === "remaining") {
24192430
return {
24202431
remaining: timeUtils.formatTime(
2421-
seekableEnd - mediaCurrentTime,
2422-
seekableEnd,
2432+
effectiveDuration - mediaCurrentTime,
2433+
effectiveDuration,
24232434
),
24242435
};
24252436
}
24262437

24272438
if (variant === "duration") {
24282439
return {
2429-
duration: timeUtils.formatTime(seekableEnd, seekableEnd),
2440+
duration: timeUtils.formatTime(effectiveDuration, effectiveDuration),
24302441
};
24312442
}
24322443

24332444
return {
2434-
current: timeUtils.formatTime(mediaCurrentTime, seekableEnd),
2435-
duration: timeUtils.formatTime(seekableEnd, seekableEnd),
2445+
current: timeUtils.formatTime(mediaCurrentTime, effectiveDuration),
2446+
duration: timeUtils.formatTime(effectiveDuration, effectiveDuration),
24362447
};
2437-
}, [variant, mediaCurrentTime, seekableEnd]);
2448+
}, [variant, mediaCurrentTime, effectiveDuration]);
24382449

24392450
const TimePrimitive = asChild ? Slot : "div";
24402451

0 commit comments

Comments
 (0)