使用 Reader.onloadend 的问题:读取以前的数据

Issue using Reader.onloadend: read previous data

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

我们正在使用 recordrtc。

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

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

这里是停止录音的代码:

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

请试试这个:

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