react-native-compressor安卓视频压缩失败,寻求解决思路及替代方案
解决React Native Android端视频压缩后上传S3的文件找不到问题
问题核心
Android端使用react-native-compressor压缩视频后,上传S3时报错ERROR: android open failed: ENOENT (No such file or directory),但iOS正常、Android图片压缩正常,推测是压缩后的路径处理或权限适配问题。
解决思路与操作步骤
1. 排查压缩返回的路径格式
先打印compressedVideoPath确认路径类型:
- 如果是
content://开头的Uri而非真实文件路径,上传S3时无法直接访问。需将Uri转换为真实文件路径,可通过原生模块或第三方工具类实现转换逻辑。
2. 适配Android 10+存储权限规则
- 在
AndroidManifest.xml的<application>标签添加android:requestLegacyExternalStorage="true",临时兼容旧存储模型(针对API 29):
<application ... android:requestLegacyExternalStorage="true">
- Android 11+推荐使用应用私有目录存储压缩文件,无需外部存储权限,彻底规避分区存储限制。
3. 指定压缩输出到应用私有目录
使用react-native-fs获取应用私有目录,强制压缩文件输出到该路径:
先安装依赖:
npm install react-native-fs --save
再修改压缩代码:
import RNFS from 'react-native-fs'; const chooseVideoFromLibrary = async () => { const options: Options = { mediaType: 'video', }; try { setIsUploading(true); const response = await ImagePicker.openPicker(options); // 指定输出到应用私有目录,避免权限问题 const outputPath = `${RNFS.DocumentDirectoryPath}/compressed_${Date.now()}.mp4`; const compressedVideoPath = await Video.compress( response.path, { compressionMethod: 'manual', minimumFileSizeForCompress: 1, outputPath: outputPath // 自定义输出路径 }) console.log('压缩后路径: ', compressedVideoPath) const dataToSend = { ...response, path: compressedVideoPath } await handleS3Upload(dataToSend); } catch (error) { console.log('错误: ', error); } finally { setIsUploading(false); } };
4. 检查上传函数的文件读取逻辑
确保handleS3Upload能正确处理私有目录路径:
- 如果使用AWS SDK上传,需确保传入的是真实文件路径而非Uri;若为Uri,需通过ContentResolver读取文件流后再上传。
5. 替代压缩方案
若react-native-compressor仍存在兼容问题,可替换为更稳定的库:
- react-native-video-processing:支持更灵活的视频压缩配置,Android端路径处理更成熟;
- expo-video-compressor:Expo生态下的方案,适配Android/iOS存储规则更省心。
内容的提问来源于stack exchange,提问作者bilalo
相关产品推荐
相关产品推荐

