如何从node.js设置虚拟麦克风和管道音频

Nie*_*les 9 ffmpeg alsa node.js jack discord.js

我想要实现的总结:

我正在做一些关于Discord机器人的工作.我正在尝试加入语音通道,这是一个简单的部分,然后使用该语音通道中扬声器的组合音频作为Web浏览器中网页的输入.只要它可以通过Selenium控制,它对哪个浏览器来说并不重要.


到目前为止我尝试/研究过的内容

到目前为止,我的机器人使用discord.py API包装器在Python中编写.不幸的是,听取而不是放入音频并没有完全实现 - 更不用说记录 - 与discord.py.这让我决定切换到node.js(即discord.js)以获取我的机器人的语音通道内容.

切换到discord.js之后,很容易确定谁在说话并为该用户创建音频流(PCM流).对于下一部分,我只是将音频流传输到虚拟麦克风并选择它作为浏览器上的音频输入.您甚至可以在node.js 1中使用FFMPEG ,以获得如下所示的内容:

const Discord = require("discord.js");
const client = new Discord.Client();

client.on('ready', () => {
  voiceChannel = client.channels.get('SOME_CHANNEL_ID');
  voiceChannel.join()
    .then(conn => {
      console.log('Connected')

      const receiver = conn.createReceiver();

      conn.on('speaking', (user, speaking) => {
        if (speaking) {
          const audioStream = receiver.createPCMStream(user);

          ffmpeg(stream)
              .inputFormat('s32le')
              .audioFrequency(16000)
              .audioChannels(1)
              .audioCodec('pcm_s16le')
              .format('s16le')
              .pipe(someVirtualMic);          
        }
      });
    })
    .catch(console.log);
  }); 

client.login('SOME_TOKEN');
Run Code Online (Sandbox Code Playgroud)

最后一部分,创建和流式传输到虚拟麦克风,已被证明是相当复杂的.我已经阅读了关于高级Linux声音架构(ALSA)和JACK音频连接套件的大量SO帖子和文档,但我根本无法弄清楚如何设置将显示为麦克风的虚拟麦克风我的浏览器,或如何管道音频到它.

任何帮助或指向解决方案的指针将不胜感激!


附录

在过去的几天里,我一直在研究这个问题.我现在已经了解了ALSA环回设备,并认为解决方案必须存在.

我已经差不多跟着谈到有关环回设备,旨在实现以下目标:

简单地假设您在同一设备的一个OUT和一个IN之间有物理链接.

我按照帖子中的描述设置了设备,现在在Firefox中选择麦克风时会出现两个新的音频设备.我期待一个,但我可能是因为我还没有完全理解环回设备(还).

循环设备已创建,我认为它们已链接(如果我正确理解上述文章).假设是这种情况,我必须解决的唯一问题是从node.js中通过FFMPEG流式传输音频.

音频设备

seb*_*piq 7

这是在那里回答的:Linux pipe audio file tomic input

创建一个虚拟麦克风:

pactl load-module module-pipe-source source_name=virtmic file=/tmp/virtmic format=s16le rate=16000 channels=1
Run Code Online (Sandbox Code Playgroud)

管道 ffmpeg 输出到virtmic文件,它应该工作:

ffmpeg -re \
    -i input.mp3 \
    -f s16le -ar 16000 -ac 1 - > /tmp/virtmic
Run Code Online (Sandbox Code Playgroud)

注意:我注意到如果管道没有读者,就会ffmpeg挂起。这可以通过简单地打开脉冲音频 VU 表来解决,命令pavucontrol