feat: Proxy video sources to resolve CORS/IP issues and adjust fetch retry/timeout for Vercel.

This commit is contained in:
kuekhaoyang
2025-11-29 16:10:01 +08:00
parent f9cf4fdfb2
commit a5c76b6f32
3 changed files with 22 additions and 9 deletions
+10 -4
View File
@@ -30,8 +30,14 @@ export function MobileVideoPlayer({
const { refs, state } = useMobilePlayerState();
const { currentTime } = state;
// Ensure src goes through proxy to avoid CORS/IP issues on Vercel
// But don't double-proxy if already proxied
const proxySrc = src.includes('/api/proxy')
? src
: `${typeof window !== 'undefined' ? window.location.origin : ''}/api/proxy?url=${encodeURIComponent(src)}`;
// Preload HLS segments
useHLSPreloader({ src, currentTime, videoRef: refs.videoRef, isLoading: state.isLoading });
useHLSPreloader({ src: proxySrc, currentTime, videoRef: refs.videoRef, isLoading: state.isLoading });
const {
videoRef,
@@ -54,7 +60,7 @@ export function MobileVideoPlayer({
} = state;
const logic = useMobilePlayerLogic({
src,
src: proxySrc,
initialTime,
shouldAutoPlay,
onError,
@@ -98,7 +104,7 @@ export function MobileVideoPlayer({
<video
ref={videoRef}
className="w-full h-full object-contain touch-none"
src={src}
src={proxySrc}
poster={poster}
onPlay={handlePlay}
onPause={handlePause}
@@ -127,7 +133,7 @@ export function MobileVideoPlayer({
/>
<MobileControlsWrapper
src={src}
src={proxySrc}
state={state}
logic={logic}
refs={refs}
+8 -3
View File
@@ -20,6 +20,11 @@ export function useHlsPlayer({
const video = videoRef.current;
if (!video || !src) return;
// Ensure src goes through proxy to avoid CORS/IP issues on Vercel
const proxySrc = src.includes('/api/proxy')
? src
: `${window.location.origin}/api/proxy?url=${encodeURIComponent(src)}`;
// Cleanup previous HLS instance
if (hlsRef.current) {
hlsRef.current.destroy();
@@ -49,7 +54,7 @@ export function useHlsPlayer({
});
hlsRef.current = hls;
hls.loadSource(src);
hls.loadSource(proxySrc);
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, () => {
@@ -117,12 +122,12 @@ export function useHlsPlayer({
} else {
console.log('[HLS] Using native HLS support');
// Native HLS support
video.src = src;
video.src = proxySrc;
}
} else if (isNativeHlsSupported) {
// Fallback for environments where Hls.js is not supported but native is (e.g. iOS without MSE?)
console.log('[HLS] Using native HLS support (Hls.js not supported)');
video.src = src;
video.src = proxySrc;
} else {
console.error('[HLS] HLS not supported in this browser');
}
+4 -2
View File
@@ -20,8 +20,10 @@ export async function fetchWithRetry({ url, request }: FetchWithRetryOptions): P
// Optional IP forwarding (default: Beijing IP)
const forwardedIP = request.nextUrl.searchParams.get('ip') || '202.108.22.5';
const MAX_RETRIES = 5;
const TIMEOUT_MS = 30000; // 30 seconds
// Vercel serverless functions have a 10s default timeout
const isVercel = process.env.VERCEL === '1';
const MAX_RETRIES = isVercel ? 2 : 5;
const TIMEOUT_MS = isVercel ? 8000 : 30000; // 8s for Vercel, 30s for others
let lastError: unknown = null;
let response: Response | null = null;