簡體   English   中英

Stream 音頻從客戶端到服務器到客戶端使用 WebSocket

[英]Stream audio from client to server to client using WebSocket

I am trying to capture microphone audio from a client web browser, live stream the captured audio to a Node.js server using WebSocket and then again stream the audio back to a different web browser client.

到目前為止,在客戶端,我在 JavaScript 中打開了一個 WebSocket 連接

const webSocket = new WebSocket('ws://127.0.0.1:8080');
webSocket.binaryType = 'blob';

在連接到服務器時,我從用戶的麥克風捕獲音頻 stream,並在每 1 秒可用的每個可用數據塊上,通過 WebSocket 將其發送到服務器

webSocket.onopen = event => {
console.log('info: connected to server');

navigator.mediaDevices
  .getUserMedia({ audio: true, video: false })
  .then(stream => {
    const mediaRecorder = new MediaRecorder(stream, {
      mimeType: 'audio/webm',
    });

    mediaRecorder.addEventListener('dataavailable', event => {
      if (event.data.size > 0) {
        webSocket.send(event.data);
      }
    });

    mediaRecorder.start(1000);
  });
};

現在,在服務器端,使用ws模塊,我接收每個 blob 並將其發送到另一個客戶端

wss.on('connection', ws => {
  console.log('info: client connected');

  ws.on('message', message => {
    wss.clients.forEach(client => {
      if (client !== ws && client.readyState === webSocket.OPEN) {
        client.send(message);
      }
    });
  });
});

回到客戶端,我嘗試使用帶有參考audioElaudio標簽播放音頻

  webSocket.onmessage = event => {
    audioEl.src = window.URL.createObjectURL(event.data);
    audioEl.play();
  };

現在,我知道這僅適用於第一塊數據(並且確實有效),因為audioEl.play(); 是異步的。 在這種情況下,我正在嘗試更改audio元素的 blob URL,每秒通過 WebSocket 接收到一個新 blob。

經過一周的研究,我發現解決方案僅涉及如何將 stream 服務器連接到客戶端音頻,開始錄制音頻,停止錄制,然后將整個塊作為 blob 發送。

我也嘗試發送AudioBuffer ,但不知道如何處理它來播放音頻。

const context = new AudioContext();
    const source = context.createMediaStreamSource(stream);
    const processor = context.createScriptProcessor(1024, 1, 1);

    source.connect(processor);
    processor.connect(context.destination);

    processor.onaudioprocess = function(e) {
      webSocket.send(e.inputBuffer);
    }

我想要實現的是用戶對着他/她的麥克風說話,音頻直播流到服務器,然后流向另一個用戶並同時播放。

如果我每秒發送一個 blob 的方法是正確的,我怎樣才能使代碼工作以連續播放音頻? 也許我需要創建一些我不知道的緩沖區。 或者,如果該方法完全不正確,請指導我使用正確的方法。

使用 WebRTC 技術進行點對點通信對我來說不是一個選項,因為我不想要 STUN 或 TURN 服務器的開銷。

MediaRecorder將數據塊傳遞給您的dataavailable事件處理程序。 為了使這些塊有用,它們必須按順序播放。 它們是媒體文件的塊,通常為.webm 格式,也稱為Matroska 格式 他們並不孤單。 (除了第一個)。

因此,如果您通過 websocket 有效載荷將它們傳遞給另一個瀏覽器,它們真的無法單獨播放。

您可以嘗試在接收瀏覽器上解析 webm 文件,並設法從 websocket 的消息事件中播放它。 有一個名為 ebml 的 npm package可以幫助解決這個問題。 如果您為該解決方案 go 尋找“如何在瀏覽器中解碼作品音頻”。 我已經為視頻做了這個。 開發和調試是 xxx 脖子上的痛。 (我這樣做只是因為一些用戶需要使用 Redmond Middle School Science Project(即 Microsoft Internet Explorer)來渲染低延遲視頻。我本可以為所有這些用戶購買新計算機,而開發它的成本是.)

奇怪的是,WebRTC 通信堆棧對音頻進行打包的方式與 MediaRecorder 的方式截然不同。

(值得一提的是,有一家名為 xirsys.com 的供應商提供 STUN/TURN 服務器。他們為開發和小批量工作提供了慷慨的免費層。值得考慮。我在開發階段取得了很大的成功,跟他們。)

也許可能對你有用。 它有關於如何收集音頻並將其轉換為.wav 並一個接一個地播放的信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM