React Native Expo大视频快速上传至S3的最优方案咨询
解决方案:React Native Expo 大视频上传至 S3
核心结论
这不是 React Native Expo 的限制,而是移动端文件 IO 模型与 Web 存在差异,需要采用适配移动端的分片上传方案。
可行实现方案
1. 基于 Expo FileSystem 手动分片上传(适配预签名URL流程)
不要一次性读取整个文件,利用 FileSystem.readAsStringAsync 的 position 和 length 参数分片读取,避免内存溢出:
import * as FileSystem from 'expo-file-system'; const uploadLargeVideoToS3 = async (uri, uploadChunk) => { const chunkSize = 10 * 1024 * 1024; // 10MB 分片大小,可根据网络调整 const fileInfo = await FileSystem.getInfoAsync(uri); const totalSize = fileInfo.size; let offset = 0; while (offset < totalSize) { const currentChunkSize = Math.min(chunkSize, totalSize - offset); // 分片读取文件内容(Base64编码) const chunkBase64 = await FileSystem.readAsStringAsync(uri, { encoding: FileSystem.EncodingType.Base64, position: offset, length: currentChunkSize }); // 转换为 Uint8Array 用于上传 const chunkBuffer = Uint8Array.from(atob(chunkBase64), c => c.charCodeAt(0)); // 调用自定义上传函数(用预签名URL上传当前分片) await uploadChunk(chunkBuffer, offset, totalSize); offset += currentChunkSize; } }; // 示例:用预签名URL上传单个分片 const uploadChunk = async (chunk, offset, totalSize) => { // 从你的服务端获取对应分片的预签名URL const presignedUrl = await fetch('/api/get-presigned-url', { method: 'POST', body: JSON.stringify({ offset, totalSize }) }).then(res => res.json()); await fetch(presignedUrl, { method: 'PUT', body: chunk, headers: { 'Content-Type': 'video/mp4' } }); };
2. 用 AWS Amplify Storage 简化实现
AWS Amplify 的 Storage 模块已原生适配 React Native/Expo,自动处理分片、断点续传、预签名URL生成等逻辑,无需手动实现分片:
import { Storage } from 'aws-amplify'; // 初始化 Amplify 配置(提前在项目中配置 AWS 凭证) await Storage.put('user-videos/large-file.mp4', uri, { contentType: 'video/mp4', // 可选:监听上传进度 progressCallback: (progress) => { console.log(`上传进度:${Math.round((progress.loaded / progress.total) * 100)}%`); }, // 开启分片上传(默认已启用,大文件自动触发) partSize: 10 * 1024 * 1024 });
大厂(IG、TikTok)的上传逻辑参考
- 本地预处理:上传前在移动端完成视频压缩、转码(调整分辨率、码率、格式),大幅降低文件体积,这是减少上传压力的核心步骤。
- 分片+断点续传:用原生文件API分片读取视频,记录已上传分片的状态,断网后可从断点继续上传,避免重复传输。
- 多并发上传:同时上传多个分片(控制并发数,避免占用过多带宽),提升整体上传速度。
- 服务端生成预签名URL:移动端向自研服务端请求分片的预签名URL,而非在客户端生成,兼顾安全性和灵活性。
内容的提问来源于stack exchange,提问作者user2465134
相关产品推荐
相关产品推荐

