【问题标题】:Issue using Reader.onloadend: read previous data使用 Reader.onloadend 的问题:读取以前的数据
【发布时间】:2018-11-28 09:50:19
【问题描述】:

我试图理解另一个人开发的代码。简而言之,我需要从麦克风录制音频流并将其发送到 Google API Speech Recongition 系统。

我们正在使用recordrtc。

我有一个按钮,如果按下它会录制音频,然后再次按下会停止录制。

问题在于停止录制功能。使用 reader.onloadend,当我尝试阅读音频时,我总是阅读以前的音频而不是新的音频,就像我在一个循环中并且我阅读了第 i 个插入的 i-1 数据。

这里是stopRecording的代码:

stopRecording() {
    if (this.isRecording) {
      this.audioRecordingService.stopRecording();
      this.isRecording = false;
    }

    var reader = new FileReader();
    reader.readAsDataURL(this.ccc.blob); 
    reader.onloadend = function() {
        console.log("onloadend")
            var base64data = reader.result;
            localStorage.setItem("audioData", base64data.toString());                   
    }
    var data = localStorage.getItem("audioData");
    var clean_data =  data.substr(data.indexOf(',')+1);
    var post_obj = JSON.stringify({
        "name":"audio",
        "base64": clean_data
    })
    this.commandList.postBlob(post_obj).subscribe((res) => {
       console.log("Google API translation: "+ res["res"]);
    });
 }

如有遗漏,请见谅。

谢谢


为了清楚起见,我还添加了录音服务中的功能。希望这有帮助。我也查了,可以确认他用的是recordRTC

 getRecordedBlob(): Observable<RecordedAudioOutput> {
   return this._recorded.asObservable();
 }

 getRecordedTime(): Observable<string> {
   return this._recordingTime.asObservable();
 }

 recordingFailed(): Observable<string> {
   return this._recordingFailed.asObservable();
 }

 startRecording() {
   if (this.recorder) {
     return;
   }

   this._recordingTime.next('00:00');
   navigator.mediaDevices.getUserMedia({ audio: true }).then(s => {
   this.stream = s;
   this.record();
 }).catch(error => {
  this._recordingFailed.next();
 });
}

abortRecording() {
  this.stopMedia();
}

private record() {
  this.recorder = new RecordRTC.StereoAudioRecorder(this.stream, {
  type: 'audio',
  numberOfAudioChannels: 1, // or leftChannel:true
  mimeType: 'audio/webm'
});

this.recorder.record();
this.startTime = moment();
this.interval = setInterval(
  () => {
    const currentTime = moment();
    const diffTime = moment.duration(currentTime.diff(this.startTime));
    const time = this.toString(diffTime.minutes()) + ':' + this.toString(diffTime.seconds());
    this._recordingTime.next(time);
  },
  1000
 );
}

 private toString(value) {
   let val = value;
   if (!value) {
   val = '00';
 }
 if (value < 10) {
   val = '0' + value;
 }
 return val;
}

stopRecording() {
  if (this.recorder) {
    this.recorder.stop((blob) => {
      if (this.startTime) {
        const mp3Name = encodeURIComponent('audio_' + new Date().getTime() + '.mp3');
        this.stopMedia();
        this._recorded.next({ blob: blob, title: mp3Name });
      }
     }, () => {
       this.stopMedia();
       this._recordingFailed.next();
     });
  }
} 

 private stopMedia() {
   if (this.recorder) {
     this.recorder = null;
     clearInterval(this.interval);
     this.startTime = null;
     if (this.stream) {
       this.stream.getAudioTracks().forEach(track => track.stop());
       this.stream = null;
     }
   }
 }

【问题讨论】:

  • 你试过了吗? var blob = recorder.getBlob(); reader.readAsDataURL(blob); 即使用“getBlob”访问 blob 对象。
  • 嗨@MuazKhan 感谢您的回答。问题一:什么是“录音机”?我在这部分代码中没有这个变量
  • recorder=RecordRTC(stream,options) 和 stopRecording 必须如下所示:recorder.stopRecording(function() {}) 并且您的代码必须驻留在 stopRecording 回调中。我可以看到您正在访问 stopRecording 回调之外的 blob。请在“recorder.stopRecording”中移动代码。参考:recordrtc.org/RecordRTC.html#blob

标签: angular recordrtc


【解决方案1】:

请试试这个:

stopRecording() {
    if (this.isRecording) {
        var that = this;
        this.audioRecordingService.stopRecording(function() {
            that.ccc.blob = that.audioRecordingService.getBlob();
            stopRecording(); // this line is tricky; maybe "that.stopRecording()"?
        });
        this.isRecording = false;
        return;
    }

    var reader = new FileReader();
    reader.readAsDataURL(this.ccc.blob);
    reader.onloadend = function() {
        console.log("onloadend")
        var base64data = reader.result;
        localStorage.setItem("audioData", base64data.toString());
    }
    var data = localStorage.getItem("audioData");
    var clean_data = data.substr(data.indexOf(',') + 1);
    var post_obj = JSON.stringify({
        "name": "audio",
        "base64": clean_data
    })
    this.commandList.postBlob(post_obj).subscribe((res) => {
        console.log("Google API translation: " + res["res"]);
    });
}

即我在你的代码中改变了这个:

audioRecordingService.stopRecording(function() {
    var blob = audioRecordingServices.getBlob();
});

【讨论】:

  • 首先感谢您的宝贵时间。不幸的是,代码是由另一个人编写的,可能他修改了 audioRecordingService。事实上,我在 audioRecordingService.stopRecording 中得到一个错误“Expected 0 arguments got 1”
  • 请确认他是否在使用 RecordRTC。如果他正在使用 RecordRTC,那么他必须在内部某处使用类似“recorder.stopRecording”的东西。你可以告诉他把代码放在 stopRecording 回调中。还请他使用“getBlob”。希望这可以帮助。问候
  • 我添加了另一部分关于音频服务的代码。希望这会有所帮助
  • 您想获取基于间隔的音频 blob,然后使用 FileReader 读取它们吗?例如。获取每一秒的音频块并转换为 DataURI 并上传到谷歌翻译服务?如果是,那么here is the demo。它也支持 StereoAudioRecorder 但是我会推荐主要的“RecordRTC”对象,如果可用,它将选择 MediaRecorder API,否则会回退到 WebAudio 解决方案。
猜你喜欢
  • 1970-01-01
  • 2020-06-11
  • 2021-01-22
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
相关资源
最近更新 更多