如何在 Node JS 中将原始 PCM 流转换为 Discord 机器人的 opus 或 wav 流?

Posted

技术标签:

【中文标题】如何在 Node JS 中将原始 PCM 流转换为 Discord 机器人的 opus 或 wav 流?【英文标题】:How can I convert a raw PCM stream to an opus or wav stream in Node JS for a Discord bot? 【发布时间】:2021-09-24 02:55:43 【问题描述】:

​​背景:

我正在为Discord 创建一个个人音乐机器人,主要使用discord.js,我想添加的功能之一是让机器人直接从Voicemeeter 播放音频。这个解决方案是最佳的,因为机器人能够以比 Discord 用户更好的质量进行流式传输,并且它们能够播放立体声而不是单声道,而且我可以选择使用 Voicemeeter 流式传输的源。

Voicemeeter 带有一项称为 VBAN 的功能,可让您使用 VBAN protocol 通过网络将音频数据发送到另一台运行 VBAN 接收器的计算机。

Jacob Bower 在 Node JS 中创建了一个 VBAN receiver script,它获取原始 PCM 音频数据并使用 node-speaker 通过扬声器播放。

问题:

使用 Jacob 的脚本,如果您尝试将 PCM 音频直接通过管道传输到 Discord 机器人,则会出现错误“错误 [VOICE_PLAY_INTERFACE_BAD_TYPE]:未知流类型。”我相信这是因为从脚本接收到的 PCM 音频包含在缓冲区中,discord bot 无法在本地播放。我需要找到一种方法以可读格式获取该 PCM 音频,以便不和谐机器人播放。 (我认为可读格式包括 opus 和 wav,(可能还有其他不是 PCM 的流媒体格式))

我尝试过的:

如上所述,我直接将 PCM 音频缓冲区通过管道传输到机器人中,但它给出了该错误。 我尝试将缓冲区放入 PassThrough Stream,并将该流通过管道传输到机器人中。 这在控制台中没有遇到任何错误,机器人按照应有的方式加入语音通道,并且不发出任何声音。我认为这是因为 discord.js 不支持播放我事后学到的原始 PCM 音频。 The Discord.js guide 提到 PCM 需要使用 opus 进行编码才能播放不和谐。所以我尝试使用 opus encoder built into discord.js。首先,我尝试对每个 PCM 缓冲区进行编码并将其写入 PassThrough 流。
const  OpusEncoder  = require('@discordjs/opus');
const  PassThrough  = require('stream');
const EncodedStream = new PassThrough();
const encoder = new OpusEncoder(48000, 2); //48000 hz, 2 channels

. . .

if (data.header.sp == 0)  //This code executes each time there is a new frame sent from VBAN
     EncodedStream.write(encoder.encode(data.audio));


. . .

connection.play(EncodedStream); //Connection is just the Bot being inside a voice channel.

遇到了错误"Cannot create a Buffer larger than 0xffffffff bytes." 我不确定为什么会出现这个错误,因为在每个缓冲区上运行 Buffer.byteLength 会产生 1024。

然后我继续尝试使用prism-media 对流进行编码,发现更多错误并且机器人保持沉默。 我安装了一些声称可以将流转换为 AudioBuffers 的 npm 模块,以及将 PCM AudioBuffer 转换为可用 wav 格式的另一个模块,但我也发现了更多错误。

我现在正在努力解决这个问题,如果有任何帮助指出我正确的方向,我将不胜感激。

【问题讨论】:

【参考方案1】:

你可能需要prism-media

它可以对作品流进行编码和解码

【讨论】:

虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。

以上是关于如何在 Node JS 中将原始 PCM 流转换为 Discord 机器人的 opus 或 wav 流?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 PCM 音频样本流转换为音量?

在 Node.js 上从 Web Audio API 播放 PCM 流

如何将 PCM 音频流转换为在线播放

如何在 Node.js 中将字符串转换为字节数组?

如何在node js中将promise转换为回调?

如何在 Node.js 中将 NTLM 凭据转换为 Kerberos 令牌