javascript - 提高 socket io 中的音质,将音频数据从客户端发送到服务器返回客户端

标签 javascript node.js audio socket.io getusermedia

这段代码确实有效。每隔 300 毫秒,一个音频数据 block 就会发送到服务器,然后返回到 socket 房间中的客户端进行播放。只有一个问题。这是极其糟糕的音频质量。每隔 300 秒就会出现一个短暂的小静电噪音,几乎立即消失。我相信这是因为音频 block 被发送到服务器和返回到房间中的 socket 之间的时间。我没有使用像 socket io p2p 或 peerjs 这样的 webRTC,因为它们真的很复杂而且我是初学者,所以这段代码中有什么我可以做的来更流畅地播放音频吗?我尝试了不同的方法,例如将 setInterval 函数中的毫秒更改为 60 并将其提高到 5000。间隔越短,播放越快,但质量越高,但延迟 5 秒。

客户:

var constraints = { audio: true };
    navigator.mediaDevices.getUserMedia(constraints).then(function(mediaStream) {
        var mediaRecorder = new MediaRecorder(mediaStream);
        mediaRecorder.onstart = function(e) {
            this.chunks = [];
        };

        mediaRecorder.ondataavailable = function(e) {
            this.chunks.push(e.data);
        };
        mediaRecorder.onstop = function(e) {
            var blob = new Blob(this.chunks);
            var url = <%- JSON.stringify(url) %>;
            socket.emit('radio', {blob : blob, url : url});
        };

        mediaRecorder.start();

        setInterval(function() {
            mediaRecorder.stop()
            mediaRecorder.start();
        }, 300);
    });

    socket.on('voice', function(arrayBuffer) {
        var blob = new Blob([arrayBuffer], { 'type' : 'audio/webm;codecs=opus' });
        var audio = document.createElement('audio');
        audio.src = window.URL.createObjectURL(blob);
        audio.play();
    });

服务器:

socket.on('radio', function(data) {
    socket.broadcast.to(data.url).emit('voice', data.blob);
    socket.join(data.url);
});

最佳答案

您的音频质量很好。您的问题是音频 block 之间的播放间隙。好的音频看起来像这样。每个音频样本都是一个*。你可能每秒有 44K 个样本或类似的东西。

 ***********************************************

您提供给音频元素的样本如下所示

 ******* ******* ******* *******   ******** *******   ****

注意差距。那些是持久性有机污染物。请注意,播放音频的时间比捕获音频的时间长。那是因为差距。

如果您决定接受它,您的任务是弄清楚如何将音频 block 放入队列中,以便您的音频播放器可以连续播放它们,并在上一个播放器停止播放时恰好开始播放下一个播放器。您需要某种“即发即弃”机制。

对于 Stack Overflow 问题来说,要完整地解释这一点需要很多,所以我会提供一些提示。

  1. 不要启动和停止您的 mediaRecorder。让它继续运行。
  2. mediaRecorder.start(nn) 中加入少量的毫秒数,比如 10
  3. ondataavailable 事件处理程序(而不是 onstop 处理程序)通过套接字将您的 blob(您的示例缓冲区)发送到您的服务器。这使得它们基本上流式传输到服务器。
  4. 使用网络音频 API 将您的示例缓冲区排队到用户的音频设备。大话题。查一下。

关于javascript - 提高 socket io 中的音质,将音频数据从客户端发送到服务器返回客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45047648/

相关文章:

javascript - SetTimeout + fs.writeFile 删除我的对象

audio - 在 QT 7 pro 中更改 Soundtrack 属性 - 使用 applescript 批处理

javascript - 如何正确选择 Canvas 宽度?

javascript - Redux-logger 导出已更改

javascript - 如何在页面加载中扩展我的 Div?

javascript - 使用 JSON 数据填充 Javascript 数组

javascript - 提取具有最高属性值的元素

node.js - 使用 Firebase Auth 和 Express 验证社交登录?

javascript - HTML5 Audio,获取钢琴音色

javascript - WebAudio API 数据数组大小?