Vue项目中wavesurfer.js录制音频上传至AWS S3的问题
Vue中使用wavesurfer.js Record插件录制音频并上传Amazon S3的解决方案
问题描述
在Vue项目中使用wavesurfer.js及其Record插件录制语音消息,需要获取音频文件的Blob并上传至Amazon S3服务器,但尝试以下方法均失败:
- 直接传入录制URL:生成的webm文件不含音频流,仅为Blob文本格式URL
- 转换为二进制字符串:上传后的音频文件无法播放
用户初始代码
import WaveSurfer from 'wavesurfer.js'; import RecordPlugin from 'wavesurfer.js/dist/plugins/record'; import AWS from 'aws-sdk'; export default { data() { return { audioUrl: '', isRecording: false // 补充缺失的data属性 }; }, mounted() { this.initializeWaveSurfer() }, methods: { initializeWaveSurfer() { this.wavesurfer = WaveSurfer.create({ container: '#visualizer', barWidth: 3, barHeight: 1.5, cursorWidth: 0, height: 46, responsive: true, waveColor: 'rgba(108,115,202,0.3)', cursorColor: 'transparent', }) this.record = this.wavesurfer.registerPlugin(RecordPlugin.create()); }, startRecording() { this.isRecording = true this.record.startRecording(); }, stopRecording() { this.isRecording = false this.record.stopRecording(); this.uploadAudio(*blob*) // 此处需要正确的Blob }, uploadAudio(blob) { const s3 = new AWS.S3({ accessKeyId: 'xxxx', secretAccessKey: 'xxxx', region: 'xxxx' }) const params = { Bucket: 'xxxx', Key: 'test.webm', Body: blob, ACL: 'public-read', ContentType: 'audio/webm' } s3.upload(params, (err, data) => { if (err) { console.error('Error uploading audio:', err) } else { console.log('Audio uploaded successfully:', data) } }) } } };
用户尝试的错误方案
方案1:传入录制URL
stopRecording() { this.isRecording = false this.record.stopRecording(); this.record.on('stopRecording', () => { this.uploadAudio(this.record.getRecordedUrl()); }); },
问题:getRecordedUrl()返回的是Blob的URL字符串,不是Blob文件本身,直接传给S3会导致文件内容为URL文本,而非音频流。
方案2:转换为二进制字符串
stopRecording() { this.isRecording = false this.record.stopRecording(); this.record.on('stopRecording', () => { var xhr = new XMLHttpRequest(); xhr.open('GET', this.record.getRecordedUrl(), true); xhr.responseType = 'blob'; xhr.onload = function (e) { if (this.status === 200) { var blob = this.response; var reader = new FileReader(); reader.onloadend = function () { var fileData = reader.result; this.uploadAudio(fileData); // 无法播放 }; reader.readAsBinaryString(blob); } }; xhr.send(); }); }
问题:readAsBinaryString读取的二进制字符串不符合S3的上传要求,会导致文件损坏无法播放。
正确解决方案
核心是直接获取Record插件生成的Blob对象,无需额外转换,同时确保this指向正确:
stopRecording() { this.isRecording = false this.record.stopRecording(); // 监听stopRecording事件,确保录制完成后获取Blob this.record.on('stopRecording', () => { // 直接获取录制的Blob对象 const recordedBlob = this.record.getRecordedBlob(); if (recordedBlob) { this.uploadAudio(recordedBlob); } else { console.error('Failed to get recorded Blob'); } }); }
修改说明
- 使用
getRecordedBlob()方法直接获取录制生成的Blob文件,这是插件提供的原生方法,无需通过URL转换 - 确保在
stopRecording事件回调中操作,保证录制完全结束后再获取Blob - 无需转换为二进制字符串,直接将Blob传给S3的
upload方法,AWS SDK会正确处理Blob类型的Body
补充注意事项
- 确认浏览器支持webm格式的音频录制(大部分现代浏览器都支持)
- 确保AWS S3的权限配置正确,允许上传audio/webm类型的文件
- 如果需要支持更多格式,可以在录制完成后用MediaRecorder API转换格式,但webm是默认且兼容性较好的选择
内容的提问来源于stack exchange,提问作者Raphael M
相关产品推荐
相关产品推荐

