如何在 React Native 中高效缓存视频并使用 expo-av 播放

张开发
2026/4/17 12:55:43 15 分钟阅读

分享文章

如何在 React Native 中高效缓存视频并使用 expo-av 播放
本文详解在裸 React Native 项目中结合 react-native-fs 与 expo-av 实现视频本地缓存与播放的完整方案重点解决路径格式错误、URI 协议兼容性及缓存策略优化问题并提供可直接运行的代码示例。 本文详解在裸 react native 项目中结合 react-native-fs 与 expo-av 实现视频本地缓存与播放的完整方案重点解决路径格式错误、uri 协议兼容性及缓存策略优化问题并提供可直接运行的代码示例。在 React Native 中缓存视频并非简单“下载 播放”尤其当使用 expo-av而非 react-native-video时文件路径协议、权限配置和 URI 格式要求更为严格。你遇到的“路径不工作”问题根本原因在于expo-av 要求传入 source.uri 的必须是 合法的 file:// 协议 URI而你当前拼接的 ${cachePath}/${filename} 仅是原生文件系统路径如 /Users/.../video.mp4缺少 file:// 前缀且未做平台适配处理。? 正确做法是使用 react-native-fs 下载视频后通过 RNFS.fileURL()iOS或 RNFS.pathToUrl()Android生成标准 file URI再传给 expo-av/Video 组件。以下是经过验证的完整实现import React, { useState, useEffect } from react;import { View } from react-native;import * as RNFS from react-native-fs;import { Video } from expo-av;const App ({ videoUrl }: { videoUrl: string }) { const [cachedUri, setCachedUri] useStatestring | null(null); useEffect(() { downloadAndCacheVideo(); }, []); const downloadAndCacheVideo async () { try { const filename videoUrl.substring(videoUrl.lastIndexOf(/) 1); const cachePath RNFS.DocumentDirectoryPath; const localPath ${cachePath}/${filename}; // ? 检查文件是否存在推荐用 stat 替代 exists更可靠 const stat await RNFS.stat(localPath).catch(() null); if (stat stat.isFile()) { console.log(? Video already cached:, localPath); // ? 生成跨平台 file:// URI const fileUri Platform.OS ios ? file://${localPath} : RNFS.pathToUrl(localPath); // Android requires pathToUrl setCachedUri(fileUri); return; } // ? 下载视频注意fetch blob 在某些 RN 版本存在兼容性问题推荐用 RNFS.downloadFile console.log(?? Downloading video...); const downloadRes await RNFS.downloadFile({ fromUrl: videoUrl, toFile: localPath, progress: (data) { console.log(Download progress: ${Math.round(data.bytesWritten / data.contentLength * 100)}%); } }).promise; if (downloadRes.statusCode 200) { const fileUri Platform.OS ios ? file://${localPath} : RNFS.pathToUrl(localPath); setCachedUri(fileUri); console.log(? Cached video URI:, fileUri); } else { throw new Error(Download failed: ${downloadRes.statusCode}); } } catch (err) { console.error(? Cache failed:, err); } }; return ( View style{{ flex: 1 }} {cachedUri ? ( Video source{{ uri: cachedUri }} resizeModecover shouldPlay isMuted{false} useNativeControls style{{ width: 100%, height: 300 }} / ) : ( View style{{ flex: 1, justifyContent: center, alignItems: center }} TextLoading cached video.../Text /View )} /View );};export default App;? 关键注意事项与最佳实践 稿定AI 拥有线稿上色优化、图片重绘、人物姿势检测、涂鸦完善等功能

更多文章