首页 > 解决方案 > 如何与录音同步播放多个音频

问题描述

我正在开发一个允许同时播放多个音轨(例如鼓、萨克斯管、贝斯、人声)的应用程序,我设法通过在未来与 AudioSourceNode.start(timeInFuture) 进行调度来同步播放。现在我需要在播放其他歌曲时录制用户的麦克风,保存录音,然后与其他曲目同步播放。对于录制我使用 MediaRecorder API,我可以从流开始录制并创建一个新的 AudioSourceNode。

if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
      console.log('getUserMedia supported.');
      navigator.mediaDevices.getUserMedia({ audio: { channelCount: { ideal: 2 }, latency: 0.05, echoCancellation: { ideal: true } } })
        .then(stream => {
          this.mediaRecorder = new MediaRecorder(stream);
          this.mediaRecorder.ondataavailable = (e: any) => {
            this.recordedChunks.push(e.data);
          }
          this.mediaRecorder.onstart = (e: any) => {
            this.timestamp = Date.now() - this.timestamp;
          }
          this.mediaRecorder.onstop = (e: any) => {
            console.log("recorder stopped", e);
            stream.getTracks().forEach(t => t.stop())
            const blob = new Blob(this.recordedChunks); //, { type: 'audio/ogg; codecs=opus' });
            this.recordedChunks = [];
            console.log(blob);

            let fileReader = new FileReader();

            fileReader.onloadend = () => {
              if (fileReader.result instanceof ArrayBuffer)
                this.audioCtx.decodeAudioData(fileReader.result,
                  (audioBuffer) => {

                      this.currentTrack.details.push({
                        name: "Record",
                        url: "assets/record/record",
                        gain: 100,
                        gainNode: null,
                        source: null,
                        enabled: true,
                        audioByte: audioBuffer
                      })
                      this.weAreRecord = true;
                  },
                  (error) => { console.log("decode error: ", error) }
                )
            }
            fileReader.readAsArrayBuffer(blob);
          }
          source.start(); //Here i'm starting playback
          this.mediaRecorder.start(); //Here i'm starting recording
          this.timestamp = Date.now();
          console.log(this.timestamp);
        })

        // Error callback
        .catch(function (err) {
          console.log('The following getUserMedia error occurred: ' + err);
        });
    } else {
      console.log('getUserMedia not supported on your browser!');
    }

问题出现在这里:如果我尝试使用 AudioSourceNode.start(timeInFuture) 播放所有曲目(包括录音),则录音不同步。

for (let i = 0; i < this.currentTrack.details.length; i++) {
    this.currentTrack.details[i].source.start(now + delay, timeA);
}

有没有办法在播放前同步所有曲目?谢谢大家

标签: synchronizationweb-audio-apiweb-mediarecorder

解决方案


推荐阅读