我需要一种解决方案,将<audio>
元素设置为解码后的流音频的目标。我希望用户可以单击“录制”按钮并录制音频,直到释放按钮为止,然后使用websockets将音频发送给同一房间中的其他用户,这些用户可以按“播放”按钮来收听接收到的音频。
我在SO上进行了一些搜索,发现已经实现了两种解决方案,用于解码从MediaRecorder()
发送的ArrayBuffer,但是它将自动播放,并且我无法将音频分配给一个html元素。
这是我的用于解码音频的JS代码:
// socket.io listening for audio event
socket.on('audio', function(audio){
console.log(audio);
// this part comes from a suggested solution to read the ArrayBuffer into an audio
console.log("now playing a sound, that starts with", new Uint8Array(audio.slice(0, 10)));
var dest;
audioCtx.decodeAudioData(audio, function (buffer){
if (!buffer) {
console.error("failed to decode:", "buffer null");
return;
}
var source = audioCtx.createBufferSource();
source.buffer = buffer;
source.connect(audioCtx.destination);
//source.start(0);
// here is where I'm trying to pass the audio to the <audio> element
dest = audioCtx.createMediaStreamDestination();
console.log(dest.stream);
var player = document.getElementById('audio-player');
player.src = URL.createObjectURL(dest.stream.id);
console.log("started...");
}, function (error) {
console.error("failed to decode:", error);
});
});
这是我正在使用的记录按钮代码,我想按照问题中的描述进行更改,直到用户释放它为止。
$('.audio-message').on("click",function(){
console.log('clicked');
navigator.mediaDevices.getUserMedia({
audio: true
})
.then(function(stream){
var mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start();
mediaRecorder.ondataavailable = function(e){
// chunks.push(e.data);
console.log(e.data);
socket.emit('audio', e.data);
}
setTimeout(function(){
mediaRecorder.stop();
}, 10000);
});
});
对我来说,理想的解决方案是当从用户那里收到文件时动态生成音频元素。任何帮助表示赞赏。
答案 0 :(得分:1)
由于Blob
返回MediaRecorder.ondataavailable
并且BlobEvent
已经接受URL.createObjectURL()
作为参数,所以发送方可以将数据作为Blob
发送。
通常,这已经是Websocket的默认binaryType
。您可以保留发送方代码不变,但是可以简化接收方。 (假设您只是从服务器转发数据而不更改它)
socket.on('audio', function(audio){
console.log(audio);
var player = document.getElementById('audio-player');
player.src = URL.createObjectURL(audio);
console.log("started...");
}, function (error) {
console.error("failed to decode:", error);
});
});