React-Native上传视频至S3后AWS控制台无法播放求助
问题根源
你遇到的核心问题是读取视频文件时的编码错误:RNFetchBlob.fs.readFile默认以UTF-8文本格式读取文件,而视频是二进制文件,直接读取会破坏原始数据结构,导致上传到S3后的文件损坏,无法被识别播放。
解决方案
方案1:修正文件读取与上传的编码处理
修改读取文件的方式,以Base64格式读取二进制内容,再转换为AWS SDK可识别的二进制Buffer上传:
const s3 = new AWS.S3() const uploadFileToS3 = (dat) => { const params = { Bucket: bucket, Key: keyName, Body: Buffer.from(dat, 'base64'), // 将Base64字符串转为二进制Buffer ContentType: 'video/mp4', } return s3.upload(params).promise(); } try{ console.log("Here! " + filename) // 以Base64格式读取视频文件(保留二进制结构) const file = await RNFetchBlob.fs.readFile(filename, 'base64'); console.log("Starting upload! ") await uploadFileToS3(file); console.log("Finished upload! ") } catch (err) { console.error(err); }
方案2:直接用RNFetchBlob流式上传(更高效)
避免将整个视频读入内存,直接通过文件路径流式上传,同时使用S3预签名URL提升安全性:
const s3 = new AWS.S3() // 生成S3预签名PUT URL const getPresignedUploadUrl = async () => { const params = { Bucket: bucket, Key: keyName, Expires: 3600, ContentType: 'video/mp4' }; return s3.getSignedUrlPromise('putObject', params); } try { const presignedUrl = await getPresignedUploadUrl(); // 直接包装文件路径,流式上传 const response = await RNFetchBlob.fetch('PUT', presignedUrl, { 'Content-Type': 'video/mp4' }, RNFetchBlob.wrap(filename)); if (response.info().status === 200) { console.log("Upload success!"); } else { console.error("Upload failed:", response); } } catch (err) { console.error(err); }
额外检查项
- 确认原生录制的视频格式:安卓端
MediaRecorder必须配置正确的输出格式与编码,确保生成标准MP4文件:mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); - S3文件元数据验证:上传完成后,在AWS控制台检查文件的
ContentType是否为video/mp4,若之前上传过损坏文件,需删除后重新上传(元数据不会自动覆盖)。
内容的提问来源于stack exchange,提问作者Ryan Law
相关产品推荐
相关产品推荐

