当前位置: 首页 > 知识库问答 >
问题:

将实时音频流到节点。js服务器

阚元白
2023-03-14

我正在做一个项目,我需要发送一个音频流到一个节点。js服务器。我可以使用此功能捕获麦克风声音:

function micCapture(){
    'use strict';

    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

    var constraints = {
        audio: true,
        video: false
    };

    var video = document.querySelector('video');

    function successCallback(stream) {
        window.stream = stream; // stream available to console
        if (window.URL) {
            video.src = window.webkitURL.createObjectURL(stream);
        } else {
            video.src = stream;
        }
        //Send audio stream
        //server.send(stream);
    }

    function errorCallback(error) {
        console.log('navigator.getUserMedia error: ', error);
    }

    navigator.getUserMedia(constraints, successCallback, errorCallback);
}

如你所见,我能够捕捉音频并在网站上播放。

现在我想把那个音频流发送到一个节点。js服务器,并将其发送回其他客户端。像语音聊天,但我不想使用WebRTC,因为我需要服务器中的流。我怎样才能做到这一点?我可以用插座吗。我想这样做?在我看到的示例中,他们录制了音频,并发送了一个文件,但我需要“实时”音频。

共有2个答案

段干玺
2023-03-14

我明白了,这是一个古老的问题。我正在做同样的事情(除了我的服务器不运行node.js用C#编写),并偶然发现了这一点。

不知道是否还有人感兴趣,但我已经详细说明了一点。目前不建议使用的createScript处理器的替代方案是AudioWorklet接口。

来自:https://webaudio.github.io/web-audio-api/#audioworklet

1.32.1。概念

AudioWorklet对象允许开发人员提供脚本(如JavaScript或

据我所知,你不能在Javascript中实现接口,但你可以扩展从它派生的类。

我们需要的是:https://developer.mozilla.org/en-US/docs/Web/API/AudioWorkletProcessor

所以我写了一个处理器,它只是用输入值反映输出并显示它们。

class CustomAudioProcessor extends AudioWorkletProcessor {
    process (inputs, outputs, parameters) {
        const input = inputs[0];
        const output = output[0];
        for (let channel = 0; channel < input.length; ++channel) {   
            for (let i = 0; i < input[channel].length; ++i) {
            // Just copying all the data from input to output
            output[channel][i] = input[channel][i];
            // The next one will make the app crash but yeah, the values are there
            // console.log(output[channel][i]);
            }
        }
    }
}

然后,处理器必须放置到音频管道中,在麦克风之后和扬声器之前。

function record() {

constraints = { audio: true };
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
   audioCtx = new AudioContext();
    var source = audioCtx.createMediaStreamSource(stream);
    audioCtx.audioWorklet.addModule("custom-audio-processor.js").then(() => {
        customAudioProcessor = new AudioWorkletNode(audioCtx, "custom-audio-processor");
        source.connect(customAudioProcessor);
        customAudioProcessor.connect(audioCtx.destination);
    }) 

    audioCtx.destination.play();

作品祝你好运!:)

姜卜霸
2023-03-14

我最近做了现场音频上传使用插座。从浏览器到服务器的io。我将在这里回答,以防其他人需要它。

    var stream;
    var socket = io();
    var bufferSize = 1024 * 16;
    var audioContext = new AudioContext();
    // createScriptProcessor is deprecated. Let me know if anyone find alternative
    var processor = audioContext.createScriptProcessor(bufferSize, 1, 1);
    processor.connect(audioContext.destination);

    navigator.mediaDevices.getUserMedia({ video: false, audio: true }).then(handleMicStream).catch(err => {
      console.log('error from getUserMedia', err);
    });

handleMicStream将在用户接受使用麦克风的权限时运行。

  function handleMicStream(streamObj) {
    // keep the context in a global variable
    stream = streamObj;

    input = audioContext.createMediaStreamSource(stream);

    input.connect(processor);

    processor.onaudioprocess = e => {
      microphoneProcess(e); // receives data from microphone
    };
  }


  function microphoneProcess(e) {
    const left = e.inputBuffer.getChannelData(0); // get only one audio channel
    const left16 = convertFloat32ToInt16(left); // skip if you don't need this
    socket.emit('micBinaryStream', left16); // send to server via web socket
  }

// Converts data to BINARY16
function convertFloat32ToInt16(buffer) {
    let l = buffer.length;
    const buf = new Int16Array(l / 3);

    while (l--) {
      if (l % 3 === 0) {
        buf[l / 3] = buffer[l] * 0xFFFF;
      }
    }
    return buf.buffer;
  }



拿着你的插座。io服务器侦听micBinaryStream,您应该可以获得数据。我需要google api的BINARY16格式的数据如果不需要,可以跳过对convertFloat32ToInt16()的函数调用。

当需要停止侦听时,必须断开处理器的连接并结束流。运行下面的函数closeAll()

function closeAll() {
    const tracks = stream ? stream.getTracks() : null;
    const track = tracks ? tracks[0] : null;

    if (track) {
      track.stop();
    }

    if (processor) {
      if (input) {
        try {
          input.disconnect(processor);
        } catch (error) {
          console.warn('Attempt to disconnect input failed.');
        }
      }
      processor.disconnect(audioContext.destination);
    }

    if (audioContext) {
      audioContext.close().then(() => {
        input = null;
        processor = null;
        audioContext = null;
      });
    }
  }

 类似资料:
  • 问题内容: 我目前正在尝试将直播麦克风音频从Android设备流式传输到Java程序。我首先在两个Android设备之间发送实时音频,以确认我的方法正确。在接收设备上几乎没有任何延迟地可以完美地听到音频。接下来,我将相同的音频流发送到一个小型Java程序,并验证了数据也已正确发送到此处。现在,我想要做的是对这些数据进行编码,并以某种方式在运行Java程序的服务器上对其进行回放。我宁愿在使用HTML

  • 问题内容: 我创建了一个简单的服务器,该服务器使用fs模块将mp3文件流式传输到浏览器,并以html5音频元素播放该文件。实际上,音频流非常好,但是,即使我要搜索的部分已经被缓冲,我也无法在音频流中进行搜索。 其他类似的问答也建议添加Content-Range标头,但我找不到如何做到这一点的简单示例。其他人则说使用206 Partial-Content标头,但是当我这样做时,音频将根本无法播放。

  • 我需要有一个实时直播音频流从一个客户端到一个服务器到多个侦听器客户端。 目前,我已经从客户端录制工作和流通过套接字的音频。将io发送到服务器。服务器接收此数据,并且必须流式传输音频(也通过socket.io?)发送给希望侦听此流的客户端。它必须尽可能实时(尽量减少延迟)。 我正在使用GetUserMedia录制麦克风(浏览器兼容性在这里并不重要)。我希望客户端使用HTML5音频标签来收听流。在服务

  • 问题内容: 我正在另一台PC上实现从MIC到Java服务器的实时流传输。但是我只听到白噪声。 我已经附上了客户端程序和服务器程序 并且服务器端没有问题。它与android客户端AudioRecord完美运行。 问题答案: 因此,我用正弦波(或某种在某种意义上类似正弦波的东西)填充了麦克风,并且您的程序运行正常。 因此,我的具体更改是: 显然,我将其误解为一个512字节长的片段,并破坏了正弦波,但事

  • 问题内容: 我一直在使用Node.js中的二进制流进行实验,但令我惊讶的是,确实有一个工作演示,它使用节点无线电流获取Shoutcast流,并使用分块编码将其推入HTML5元素。但这仅适用于Safari! 这是我的服务器代码: 我的客户代码很简单: 这在Mac上的Safari 5中可以正常运行,但在Chrome或Firefox中似乎无法执行任何操作。有任何想法吗? 可能的候选对象包括编码问题,或者

  • 问题内容: 我想将录制的音频从浏览器实时流传输到服务器并播放。该服务器最终将成为播放这些音频流的嵌入式设备。 到目前为止,我已经成功地录制了音频并将其编码为WAVE文件,并使用网络音频API并按照本教程在浏览器上播放。 现在,我有了.WAV编码的Blob流。我试图找到通过Web套接字连接将其流式传输到Node.js后端并使用npm模块播放它们的方法。但是我没有运气。 有人知道我应该遵循的任何资源或