From 35371cebff892f7dbc6aa66670980b138bf56399 Mon Sep 17 00:00:00 2001 From: Developer Date: Tue, 10 Mar 2026 20:16:01 +0800 Subject: [PATCH] fix: switch DASH delivery from data: URI to local MPD file via expo-file-system data: URI scheme for DASH manifests is unreliable in ExoPlayer. Write MPD XML to FileSystem.cacheDirectory/bili_dash.mpd and pass file:// URI to react-native-video instead. URL resolution is now async via useEffect+state in NativeVideoPlayer. --- components/NativeVideoPlayer.tsx | 23 ++++++++++++++++------- package-lock.json | 21 +++++++++++---------- package.json | 1 + utils/dash.ts | 22 +++++++++++++--------- 4 files changed, 41 insertions(+), 26 deletions(-) diff --git a/components/NativeVideoPlayer.tsx b/components/NativeVideoPlayer.tsx index 01d8220..30e9b92 100644 --- a/components/NativeVideoPlayer.tsx +++ b/components/NativeVideoPlayer.tsx @@ -6,7 +6,7 @@ import { import Video, { VideoRef } from 'react-native-video'; import { Ionicons } from '@expo/vector-icons'; import type { PlayUrlResponse } from '../services/types'; -import { buildDashDataUri } from '../utils/dash'; +import { buildDashMpdUri } from '../utils/dash'; const { width } = Dimensions.get('window'); const VIDEO_HEIGHT = width * 0.5625; @@ -33,12 +33,21 @@ export function NativeVideoPlayer({ onProgress, seekTo, }: Props) { const [showQuality, setShowQuality] = useState(false); + const [resolvedUrl, setResolvedUrl] = useState(); const videoRef = useRef(null); const currentDesc = qualities.find(q => q.qn === currentQn)?.desc ?? (currentQn ? String(currentQn) : 'HD'); const isDash = !!playData?.dash; - const url = isDash - ? buildDashDataUri(playData!, currentQn) - : playData?.durl?.[0]?.url; + + useEffect(() => { + if (!playData) { setResolvedUrl(undefined); return; } + if (isDash) { + buildDashMpdUri(playData, currentQn).then(setResolvedUrl).catch(() => { + setResolvedUrl(playData.dash!.video[0]?.baseUrl); + }); + } else { + setResolvedUrl(playData.durl?.[0]?.url); + } + }, [playData, currentQn]); useEffect(() => { if (seekTo !== undefined) videoRef.current?.seek(seekTo.t); @@ -46,12 +55,12 @@ export function NativeVideoPlayer({ return ( - {url ? ( + {resolvedUrl ? (