You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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');
    }
  });
}

修改说明

  1. 使用getRecordedBlob()方法直接获取录制生成的Blob文件,这是插件提供的原生方法,无需通过URL转换
  2. 确保在stopRecording事件回调中操作,保证录制完全结束后再获取Blob
  3. 无需转换为二进制字符串,直接将Blob传给S3的upload方法,AWS SDK会正确处理Blob类型的Body

补充注意事项

  • 确认浏览器支持webm格式的音频录制(大部分现代浏览器都支持)
  • 确保AWS S3的权限配置正确,允许上传audio/webm类型的文件
  • 如果需要支持更多格式,可以在录制完成后用MediaRecorder API转换格式,但webm是默认且兼容性较好的选择

内容的提问来源于stack exchange,提问作者Raphael M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 05:33:11