在Discord.js中播放node-webrtc MediaStreamTrack(音频)

时间:2020-07-25 20:17:29

标签: node.js webrtc discord.js mediastream simple-peer

我正在使用simple-peer将带有AudioTrack的MediaStream从浏览器窗口发送到本地托管的服务器(通过电子BrowserView与通过Puppeteer插入到主进程的代码隔离)

通过查看源代码并阅读文档,我能够成功地在两者之间建立连接并接收MediaStream。我发现,当您将node-webrtc (wrtc on NPM)用作webrtc实现时,ontrack事件还会为您提供该库的MediaTrack实现。然后,您可以使用非标准的RTCAudioSink获取RTCAudioData对象(记录在here中)。

这是我代码的相关部分:

/* ... */
// Requiring node-webrtc and simple-peer
const { RTCAudioSink } = require("wrtc").nonstandard;
const SimplePeer = require("simple-peer");
/* ... */
// A self-executing async function to wrap my code
(async () => {
    /* Variable initialization */
    const peer = new Peer({ wrtc: wrtc });

    /* ... */

    // This function is called when the BrowserView is created, but the events are fired later on
    function setPeerDataToMainPeerFunction() {
        // Page is a reference to a Puppeteer Page
        page.exposeFunction("sendDataToPeer", (data) => {
            peer.signal(data);
        });

        // Establishing the connection
        peer.on('signal', data => {
            page.evaluate((data) => {
                //@ts-ignore
                window.simplePeerPeer.signal(data)
            }, data);
        });

        // The important event handler where I try to play the newly added MediaTrack
        // There is always only one AudioTrack present in the MediaStream at one time.
        peer.on('track', (track, stream) => {
            /**
             * @type {MediaStreamTrack}
             */
            const audioTrack = stream.getAudioTracks()[0];
            const sink = new RTCAudioSink(audioTrack);
            sink.ondata = (rtcAudioData) => {
                console.log(rtcAudioData);
                // Here, I want to play the rtcAudioData.
                // Obviously, simply calling the play function on a VoiceConnection (Discord.js) with rtcAudioData won't work.
            }
            let streamtest = fs.createReadStream(buffer);
            bot.functions.playAudioStream(streamtest);
            // Stopping the sink, when the MediaStreamTrack ends
            audioTrack.addEventListener("ended", () => { sink.stop() });
        });
    }
    /* ... */
})();

运行脚本时,ondata事件处理程序的控制台输出将如下所示:

(请忽略,下面显示的AudioTrack的部分几乎没有声音。这不是我的问题。)

{
  samples: Int16Array [
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,
     1,  0,  0,  0,  0,  0,  1,  1,  1,  0,  0,  0,
     1,  2,  2,  2,  1,  1,  1,  1,  1,  2,  2,  2,
     2,  2,  2,  1,  1,  1,  1,  1,  1,  1,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1,  0,  0,  0,
    ... 380 more items
  ],
  bitsPerSample: 16,
  sampleRate: 48000,
  channelCount: 1,
  numberOfFrames: 480,
  type: 'data'
}
{
  samples: Int16Array [
    -1,  0,  0,  0, -1, -1,  0,  0,  0, 0, -1, -2,
    -2, -1, -1, -1, -1, -1, -1, -1, -1, 0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  1,  1, 1,  0,  0,
     0, -1, -1,  0,  0,  0, -1, -1, -1, 0,  0,  0,
    -1, -1, -1,  0,  1,  1,  0,  0,  0, 0,  0,  0,
     0,  0,  0,  0,  1,  1,  1,  0,  0, 0,  0,  0,
     1,  1,  1,  1,  1,  1,  1,  0,  0, 0,  0,  0,
     0,  1,  1,  1,  0,  0,  0,  0,  0, 0,  1,  1,
     1,  0,  0,  0,
    ... 380 more items
  ],
  bitsPerSample: 16,
  sampleRate: 48000,
  channelCount: 1,
  numberOfFrames: 480,
  type: 'data'
}
{
  samples: Int16Array [
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,
    0,  0,  0,  0, -1, -1, -1, -1, -1, -1, 0, 0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,
    0, -1, -1, -1, -1, -1, -1,  0,  0,  0, 0, 0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,
    0,  0,  0,  0,  0,  0,  0,  1,  1,  1, 0, 0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0,
    0,  0,  0,  0,
    ... 380 more items
  ],
  bitsPerSample: 16,
  sampleRate: 48000,
  channelCount: 1,
  numberOfFrames: 480,
  type: 'data'
}
{
  samples: Int16Array [
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0, -1, -1, -1,  0,  0,  0,  0,  0,
     0, -1, -1, -1,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1, -1,
    -1, -1, -1,  0,  0,  0, -1, -1, -1, -1,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     0,  0,  0,  0,
    ... 380 more items
  ],
  bitsPerSample: 16,
  sampleRate: 48000,
  channelCount: 1,
  numberOfFrames: 480,
  type: 'data'
}
{
  samples: Int16Array [
    -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0,
     0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0, 0,
     1,  1,  1,  1,  0,  0,  0,  0,  0, 0, 0, 0,
     0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0, 0,
     0,  0,  0,  0,  0,  1,  0,  0,  0, 0, 1, 1,
     1,  1,  1,  1,  1,  1,  0,  0,  0, 1, 1, 1,
     1,  1,  1,  1,  1,  1,  1,  1,  0, 0, 1, 1,
     1,  1,  1,  0,  0,  1,  1,  1,  1, 1, 1, 1,
     1,  1,  1,  1,
    ... 380 more items
  ],
  bitsPerSample: 16,
  sampleRate: 48000,
  channelCount: 1,
  numberOfFrames: 480,
  type: 'data'
}

我想知道是否可以播放Discord.js中来自MediaStream的音频数据。

0 个答案:

没有答案
相关问题