本文详解在裸 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 拥有线稿上色优化、图片重绘、人物姿势检测、涂鸦完善等功能
相关推荐
傻啦嘿哟1 小时前
某招聘平台爬虫:爬取招聘岗位数据,分析各城市薪资水平2501_933670791 小时前
2026秋招量化分析岗技能栈:Python、SQL、统计建模、回测项目怎么准备2601_962077601 小时前
python Dejavu库快速识别音频指纹实例探究科技苑1 小时前
如何用Python编程实现一个简单的Web爬虫?程序员清风2 小时前
Java 后端高并发设计:线程池、限流、熔断与降级天衍四九-2 小时前
MySQL中如何定位慢查询?如果SQL语句执行很慢,如何分析和优化?dayDayupbetter2 小时前
Visual C++ 2010安装与使用高手秘籍隐擎fox2 小时前
深入理解网络传输层安全:TLS 指纹识别(JA3/JA4)原理与 Python 协议层检测实战尚久龙2 小时前
mysql-5.7.26-winx64的安装步骤医疗信息化王工2 小时前
DataForge:基于 Python 的数据库批量导出 Excel 工具——从架构到部署的全流程实战