React Native Expo Go大视频分片上传至Cloudinary的问题
React Native Expo Go 上传大视频到 Cloudinary 问题解决指南
先搞定Blob/FormData上传问题
Expo Go里的Blob和Web标准Blob不兼容,直接用axios/fetch传Blob会被Cloudinary识别成无效参数,导致“Missing required parameter - file”错误。换用FormData+Expo FileSystem来处理,这是最靠谱的方式:
核心实现代码
import * as FileSystem from 'expo-file-system'; import axios from 'axios'; async function uploadVideo(videoUri) { // 先校验文件存在性 const fileInfo = await FileSystem.getInfoAsync(videoUri); if (!fileInfo.exists) throw new Error('视频文件不存在'); // 构造Cloudinary要求的FormData const formData = new FormData(); formData.append('file', { uri: videoUri, type: 'video/mp4', // 按需替换成对应视频MIME类型,比如MOV用video/quicktime name: 'upload-video.mp4' }); formData.append('upload_preset', '你的上传预设名称'); // 替换成自己Cloudinary的上传预设 formData.append('resource_type', 'video'); // 明确指定资源类型为视频 try { const res = await axios.post( 'https://api.cloudinary.com/v1_1/你的云名称/upload', // 替换成自己的Cloudinary云名 formData, { headers: { 'Content-Type': 'multipart/form-data' }, maxContentLength: Infinity, maxBodyLength: Infinity, timeout: 0 // 大视频上传取消超时限制 } ); console.log('上传成功', res.data); return res.data; } catch (err) { console.error('上传失败', err.response?.data || err.message); throw err; } }
排查“Missing required parameter - file”的关键点
- 确认FormData里的文件字段名是
file,Cloudinary只认这个键,别写错 - 检查
uri是否是Expo合法的本地路径(比如file:///开头,或MediaLibrary返回的URI) - MIME类型要和视频格式匹配,传错会导致Cloudinary无法识别文件
- 重启Expo Go,有时候缓存会导致FormData解析异常
大视频上传的前置优化
处理100MB+视频前,先做这些优化避免上传中断:
- 在app.json里开启
useProxy: true,绕过本地代理可能导致的连接问题 - 先用50MB左右的视频测试上传流程,确认没问题再放大到100MB+
- 确保设备网络稳定,大文件上传对网络要求高
后续分片上传的实现思路
等基础上传没问题后,用Cloudinary的分片上传接口处理超大视频:
- 调用
create_upload_session接口创建上传会话,获取会话ID - 用Expo FileSystem的
readAsStringAsync按固定大小(比如10MB)读取视频分片 - 逐个上传分片,带上会话ID、分片索引、总分片数
- 所有分片传完后,调用
finalize_upload_session完成上传
分片上传核心代码片段
// 创建上传会话 async function createUploadSession() { const res = await axios.post('https://api.cloudinary.com/v1_1/你的云名称/video/upload', { upload_preset: '你的上传预设名称', resource_type: 'video', chunk_size: 10485760 // 10MB每片,可调整 }); return res.data.upload_session_id; } // 上传单个分片 async function uploadChunk(sessionId, chunkBlob, chunkIndex, totalChunks) { const formData = new FormData(); formData.append('file', chunkBlob); formData.append('upload_session_id', sessionId); formData.append('chunk_index', chunkIndex); formData.append('total_chunks', totalChunks); await axios.post('https://api.cloudinary.com/v1_1/你的云名称/video/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } }); }
内容的提问来源于stack exchange,提问作者OssenCoder
相关产品推荐
相关产品推荐

