实时麦克风输入混音与音乐播放
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);
});
我正在尝试构建一个 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);
});