Discord.js 将 mpeg 音频流流式传输到语音通道

Posted

技术标签:

【中文标题】Discord.js 将 mpeg 音频流流式传输到语音通道【英文标题】:Discord.js stream mpeg audio stream into voice channel 【发布时间】:2020-02-19 14:45:22 【问题描述】:

我想使用机器人将来自 URL(特别是 https://s1-sjc.liveatc.net/kjfk_atis)的 mpeg 音频流(MIME 类型:audio/mpeg)不断地流式传输到我的 Discord 服务器上的一个语音通道中。

我正在使用discord.js nodejs 模块,它以面向对象的方式处理discord API。我已经创建了一个机器人帐户并完成了基本的“乒乓!”测试以确保我的代码正常工作。

我不知道 mpeg 音频流或 Discord 语音通道 API 是如何工作的,也没有找到有这方面经验的人。

我正在寻找一种廉价的方法,它只需在文本通道中以纯文本形式将 URL 回复给用户。但我觉得这是不可接受的。

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

client.on('ready', () => 
  console.log(`Logged in as $client.user.tag!`);
);

client.on('message', msg => 
  if (msg.content === 'ping') 
    msg.reply('Pong!');
  
);

client.login('heregoesmybottoken');

完成后的结果应连接到语音通道,并在启动后从 URL https://s1-sjc.liveatc.net/kjfk_atis 开始播放/流式传输音频。


编辑

对我来说,截断音频流,将其写入磁盘,然后从磁盘读取的解决方案是不可接受的,因为这会导致巨大的 I/O 压力。

由于还没有人给出答案,我自己做了一些调查,发现https://s1-sjc.liveatc.net/kjfk_atis 用于流式传输音频的技术与视频流式传输的技术不同:它没有分块,而是一个恒定的 HTTPS 请求,其中包含大概是原始 PCM 数据。

const request = require('request');
const fs = require("fs");
request('https://s1-sjc.liveatc.net/kjfk_atis').pipe(fs.createWriteStream('atis.mp3'));

我编写了这段代码来下载流,并且确实 NodeJS 开始持续写入atis.mp3,直到我按下Ctrl+C。该文件确实包含音频并且可以通过 Windows Media Player 打开。

所以现在我只需要找到一种方法将此流重定向到 discord.js,并希望 node-opus 会自动将流转换为正确的格式。

【问题讨论】:

【参考方案1】:

仍然不知道到底发生了什么。但经过多次试验和错误后,发现这确实有效。

var voice, player;

// To join channel
client.channels.get("channelid").join()
    .then((connection) => voice = connection);

// To stream audio
player = voice.playArbitraryInput("https://s1-sjc.liveatc.net/kjfk_atis");

// To stop
player.end();

我将把它留在这里以供将来参考。欢迎发表一些解释。

【讨论】:

有连接方法的文档链接吗?找不到它。

以上是关于Discord.js 将 mpeg 音频流流式传输到语音通道的主要内容,如果未能解决你的问题,请参考以下文章

从python内存中的MPEG(.ts)文件中提取音频,而不将MPEG写入文件

使用 MPEG DASH 流式传输纯音频 (.mp3) 文件

如何在 iOS 应用程序中将传输流转换(重新包装)为 MPEG-4 容器?

资源被解释为文档,但在 Chrome 控制台中传输时出现 MIME 类型音频/mpeg 错误,导致无法播放声音

一、音视频基础知识

使用 ffmpeg 实时流式传输 MPEG-TS 和 windows 媒体服务