实时麦克风输入混音与音乐播放

Realtime microphone input mixing with music playback

我正在尝试构建一个 Internet Radio 平台,并且与标题中提到的问题进行了多次斗争。

进一步解释一下,我想要实现的是,1) 在录制来自广播公司麦克风的输入时,将其与音乐播放的音频混合,以及 2) 同时能够降低或提高音乐播放的音量(也通过 UI 实时播放),以便播音员的声音可以与音乐融为一体。

这是模仿普通广播员的行为,当他想说话时降低音乐音量,当他说完时又提高音量!第二个功能肯定是在第一个功能之后,但我想提到它有助于解释这两个功能。

总而言之,我已经设法编写了接收和再现麦克风输入的代码(尽管它不能完美地工作!)。在这一点上,我需要知道是否有代码或库可以帮助我准确地完成我想做的事情。所有这些都是希望我不需要使用 IceCast 等。

下面是我获取麦克风输入的代码:

// getting microphone input and sending it to our server

var recordedChunks = [];
var mediaRecorder = null;
let slice = 100;                        // how frequently we capture sound
const slices = 20;                      // 20 * => after 2 sec
let sendfreq = slice * slices;          // how frequently we send it

/* get microphone button handle */
var microphoneButton = document.getElementById('console-toggle-microphone');
microphoneButton.setAttribute('on', 'no');

/* initialise mic streaming capability */
navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(stream => {
    _stream = stream;
})
.catch(function(err) {
    show_error('Error: Microphone access has been denied probably!', err);
});

function toggle_mic() {
    if (microphoneButton.getAttribute('on') == 'yes')
    {
        clearInterval();
        microphoneButton.setAttribute('on', 'no');
        microphoneButton.innerHTML = 'start mic';
    }
    else if (microphoneButton.getAttribute('on') == 'no') 
    {
        microphoneButton.setAttribute('on', 'yes');
        microphoneButton.innerHTML = 'stop mic';

        function record_and_send() {
            const recorder = new MediaRecorder(_stream);
            const chunks = [];
            recorder.ondataavailable = e => chunks.push(e.data);
            recorder.onstop = e => socket.emit('console-mic-chunks', chunks);
            setTimeout(()=> recorder.stop(), sendfreq); // we'll have a 5s media file
            recorder.start();
        }
        // generate a new file every 5s
        setInterval(record_and_send, sendfreq); 
    }
}

非常感谢!

如果您的麦克风音轨不需要与音频播放同步(对我而言,我没有看到任何原因),那么您可以播放两个单独的音频实例并更改正在进行的音量(在您的情况下为音频播放)。

简而言之,您不必混合音轨和做复杂的事情来解决这个任务。

草稿示例:

<input type="range" id="myRange" value="20" oninput="changeVol(this.value)" onchange="changeVol(this.value)">
// Audio playback
const audioPlayback  = new Audio();
const audioPlaybackSrc  = document.createElement("source");
audioPlaybackSrc.type = "audio/mpeg";
audioPlaybackSrc.src  = "path/to/audio.mp3";
audioPlayback.appendChild(audioPlaybackSrc);
audioPlayback.play();

// Change volume for audio playback on the fly
function changeVol(newVolumeValue) {
   audioPlayback.volume = newVolumeValue;
}

// Dealing with the microphone
navigator.mediaDevices.getUserMedia({
      audio: true
   })
   .then(stream => {
      // Start recording the audio
      const mediaRecorder = new MediaRecorder(stream);
      mediaRecorder.start();

      // While recording, store the audio data chunks
      const audioChunks = [];
      mediaRecorder.addEventListener("dataavailable", event => {
         audioChunks.push(event.data);
      });

      // Play the audio after stop
      mediaRecorder.addEventListener("stop", () => {
         const audioBlob = new Blob(audioChunks);
         const audioUrl = URL.createObjectURL(audioBlob);
         const audio = new Audio(audioUrl);
         audio.play();
      });

      // Stop recording the audio
      setTimeout(() => {
         mediaRecorder.stop();
      }, 3000);
   });

Play multiple audio files simultaneously

Change audio volume with JS

How to record and play audio in JavaScript