使用Cordova插件捕获视频后通过AWS JS SDK上传至S3的异常问题
解决Cordova视频上传S3的15字节异常与内存崩溃问题
首先咱们拆解下你遇到的两个核心问题:
- 直接传
mediaFile到S3只上传15字节:这是因为Cordova的MediaFile对象并不是AWS SDK.upload()方法能正确识别的二进制数据流类型——SDK误读了对象的元数据或属性,导致只上传了一点点无效数据。 - Base64转换上传的内存崩溃:Base64会把文件体积放大约33%,移动端WebView内存本就有限,大视频转换时会瞬间占用大量内存,触发系统OOM(内存不足)崩溃,还要后端额外处理,确实麻烦。
最优解决方案:将MediaFile转为Blob后直接上传
这个方法既不用Base64转换,又能让AWS SDK正确读取完整的视频数据流,完美规避两个问题。步骤如下:
1. 确保安装必要插件
除了你已有的cordova-plugin-media-capture/cordova-plugin-camera,还需要安装cordova-plugin-file来读取本地文件:
cordova plugin add cordova-plugin-file
2. 完整代码示例
以捕获视频为例,选取相册视频的逻辑类似,只需把captureVideo换成相机插件的获取逻辑即可:
navigator.device.capture.captureVideo(function(mediaFiles) { const targetFile = mediaFiles[0]; // 解析视频的本地文件路径 window.resolveLocalFileSystemURL(targetFile.fullPath, function(fileEntry) { fileEntry.file(function(file) { const reader = new FileReader(); reader.onloadend = function() { // 将读取到的ArrayBuffer转为Blob(AWS SDK可直接识别的二进制类型) const videoBlob = new Blob([this.result], { type: file.type }); // 配置S3上传参数 const uploadParams = { Bucket: '你的S3桶名称', Key: `videos/${Date.now()}-${targetFile.name}`, // 自定义存储路径和文件名 Body: videoBlob, ContentType: file.type // 必须正确设置视频MIME类型,否则S3上的文件无法播放 }; // 执行上传 const uploadTask = new AWS.S3.ManagedUpload({ params: uploadParams }); uploadTask.send(function(err, data) { if (err) { console.error('上传失败:', err); alert('视频上传失败,请重试'); } else { console.log('上传成功,文件地址:', data.Location); // 这里可以做上传成功后的逻辑,比如保存地址到数据库 } }); }; // 以ArrayBuffer格式读取文件(避免Base64的内存问题) reader.readAsArrayBuffer(file); }, function(fileErr) { console.error('读取文件失败:', fileErr); }); }, function(pathErr) { console.error('解析本地路径失败:', pathErr); }); }, function(captureErr) { console.error('捕获视频失败:', captureErr); }, { limit: 1, mediaType: 'video/*' // 可指定具体类型如video/mp4、video/mov });
针对超大视频的优化:自动分块上传
AWS SDK的ManagedUpload默认会自动处理分块上传——当文件大小超过5MB时,会自动把文件分成多个小块上传,每次只加载一部分数据到内存,进一步降低内存占用,避免大视频上传时的内存压力。你不需要额外写分块逻辑,SDK会自动处理。
关键注意点
- ContentType必须正确设置:如果S3上的文件ContentType不对,会导致无法在线播放,所以一定要用
file.type或者手动指定对应视频类型(比如video/mp4)。 - S3桶的CORS配置:确保你的S3桶允许移动端所在域名的PUT请求,否则会出现跨域错误。
- 权限配置:AWS SDK的凭证要拥有S3上传的权限(比如
s3:PutObject)。
内容的提问来源于stack exchange,提问作者GeeDee
相关产品推荐
相关产品推荐

