node.js - 如何设置虚拟麦克风并将音频从 node.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');
最后一部分,创建并流式传输到虚拟麦克风,已被证明相当复杂。我已经阅读了大量关于高级 Linux 声音架构(ALSA) 和 JACK 音频连接套件的 SO 帖子和文档,但我根本不知道如何设置一个虚拟麦克风,它将在我的浏览器,或者如何将音频传输到它。
任何帮助或解决方案的指针将不胜感激!
附录
在过去的几天里,我一直在研究这个问题。我现在已经了解了 ALSA 环回设备,并且觉得必须有解决方案。
我几乎关注了一篇关于环回设备的帖子,旨在实现以下目标:
简单想象一下,您在同一设备的一个 OUT 和一个 IN 之间有一条物理链路。
我已经按照帖子中的描述设置了设备,现在在 Firefox 中选择麦克风时会出现两个新的音频设备。我希望有一个,但我可能是因为我不完全了解环回设备(还)。
环回设备已创建,我认为它们已链接(如果我正确理解上述文章)。假设是这种情况,我必须解决的唯一问题是从 node.js 中通过 FFMPEG 流式传输音频。
解决方案
那里回答了这个问题:Linux pipe audio file tomic input
创建一个虚拟麦克风:
pactl load-module module-pipe-source source_name=virtmic file=/tmp/virtmic format=s16le rate=16000 channels=1
将 ffmpeg 输出通过管道传输到virtmic
文件,它应该可以工作:
ffmpeg -re \
-i input.mp3 \
-f s16le -ar 16000 -ac 1 - > /tmp/virtmic
注意:我注意到如果管道没有读者,ffmpeg
就挂起。这可以通过简单地打开 Pulse Audio VU 表来修复,命令pavucontrol
推荐阅读
- python-3.x - Ping 操作在 pycharm 中运行良好,但在 jupyter notebook 中无法运行
- vue.js - 为什么单击按钮时不触发 Vue.js @input 事件?
- python-3.x - 包含 Selenium Python 中的文本
- python - tkinter askopenfilename 和 askdirectory 的组合
- javascript - 适用于 Internet Explorer 11 的 IntelliJ IDEA JavaScript 语言版本
- python - 在前端html页面的Jinja2/flask中分配一个会话变量
- r - 如何创建要传递给公式的用户定义样条实现
- python - 将数据从 jquery 成功填充到模态时出现问题
- swift - 所有按钮(圆形、三角形)都有一个矩形框作为点击区域
- macos - 如何在 shift + tab 上的终端中向后启用自动完成功能?