本文详解在裸 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 = useState<string | 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 }} resizeMode="cover" shouldPlay isMuted={false} useNativeControls style={{ width: '100%', height: 300 }} /> ) : ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text>Loading cached video...</Text> </View> )} </View> );};export default App;? 关键注意事项与最佳实践: 稿定AI 拥有线稿上色优化、图片重绘、人物姿势检测、涂鸦完善等功能
相关推荐
Elastic 中国社区官方博客4 分钟前
Elastic 线下 Meetup 将于 2026 年 7 月 26 号下午在深圳举行独隅9 分钟前
PyTorch自动微分模块:从原理到实战一YL2004042615 分钟前
【Redis实战篇】秒杀实现方案(以优惠券秒杀为例)DIY源码阁21 分钟前
JavaSwing宿舍管理系统 - MySQL版cfm_291426 分钟前
MySQL8.0 InnoDB ClusterkTR2hD1qb37 分钟前
Claude Code Skill的介绍与使用汤米粥1 小时前
python学习——核心语法三一 乐1 小时前
汽车租赁|基于SprinBoot+vue的汽车租赁管理系统(源码+数据库+文档)zandy10111 小时前
衡石科技 NL2Metrics 技术深度解析(2026):ChatBI 准确度破局的关键路径