| D++ (DPP) C++ Discord API Bot Library

Search
Loading...
Searching...
No Matches
Streaming MP3 Files

To stream MP3 files via D++ you need to link an additional dependency to your bot, namely libmpg123. It is relatively simple when linking this library to your bot to then decode audio to PCM and send it to the dpp::discord_voice_client::send_audio_raw function as shown below:

#include <dpp/dpp.h>
#include <iomanip>
#include <sstream>
#include <vector>
#include <fstream>
#include <iostream>
#include <mpg123.h>
#include <out123.h>
/* For an example we will hardcode a path to some awesome music here */
#define MUSIC_FILE "/media/music/Rick Astley/Whenever You Need Somebody/Never Gonna Give You Up.mp3"
int main() {
/* This will hold the decoded MP3.
* The D++ library expects PCM format, which are raw sound
* data, 2 channel stereo, 16 bit signed 48000Hz.
*/
std::vector<uint8_t> pcmdata;
mpg123_init();
int err = 0;
unsigned char* buffer;
size_t buffer_size, done;
int channels, encoding;
long rate;
/* Note it is important to force the frequency to 48000 for Discord compatibility */
mpg123_handle *mh = mpg123_new(NULL, &err);
mpg123_param(mh, MPG123_FORCE_RATE, 48000, 48000.0);
/* Decode entire file into a vector. You could do this on the fly, but if you do that
* you may get timing issues if your CPU is busy at the time and you are streaming to
* a lot of channels/guilds.
*/
buffer_size = mpg123_outblock(mh);
buffer = new unsigned char[buffer_size];
/* Note: In a real world bot, this should have some error logging */
mpg123_open(mh, MUSIC_FILE);
mpg123_getformat(mh, &rate, &channels, &encoding);
while (mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK) {
for (size_t i = 0; i < buffer_size; i++) {
pcmdata.push_back(buffer[i]);
}
}
delete[] buffer;
mpg123_close(mh);
mpg123_delete(mh);
/* Setup the bot */
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&pcmdata](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "join") {
/* Get the guild */
dpp::guild* g = dpp::find_guild(event.command.guild_id);
/* Attempt to connect to a voice channel, returns false if we fail to connect. */
if (!g->connect_member_voice(*event.owner, event.command.get_issuing_user().id)) {
event.reply("You don't seem to be in a voice channel!");
return;
}
/* Tell the user we joined their channel. */
event.reply("Joined your channel!");
} else if (event.command.get_command_name() == "mp3") {
/* Get the voice channel the bot is in, in this current guild. */
dpp::voiceconn* v = event.from()->get_voice(event.command.guild_id);
/* If the voice channel was invalid, or there is an issue with it, then tell the user. */
if (!v || !v->voiceclient || !v->voiceclient->is_ready()) {
event.reply("There was an issue with getting the voice channel. Make sure I'm in a voice channel!");
return;
}
/* Stream the already decoded MP3 file. This passes the PCM data to the library to be encoded to OPUS */
v->voiceclient->send_audio_raw((uint16_t*)pcmdata.data(), pcmdata.size());
event.reply("Played the mp3 file.");
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create a new command. */
dpp::slashcommand joincommand("join", "Joins your voice channel.", bot.me.id);
dpp::slashcommand mp3command("mp3", "Plays an mp3 file.", bot.me.id);
bot.global_bulk_command_create({ joincommand, mp3command });
}
});
/* Start bot */
bot.start(dpp::st_wait);
/* Clean up */
mpg123_exit();
return 0;
}
dpp::cluster
The cluster class represents a group of shards and a command queue for sending and receiving commands...
Definition cluster.h:89
dpp::guild
Represents a guild on Discord (AKA a server).
Definition guild.h:999
dpp::guild::connect_member_voice
bool connect_member_voice(const cluster &owner, snowflake user_id, bool self_mute=false, bool self_deaf=false, bool dave=true)
Connect to a voice channel another guild member is in.
dpp::interaction::guild_id
snowflake guild_id
Optional: the guild it was sent from.
Definition appcommand.h:1051
dpp::interaction::get_issuing_user
const dpp::user & get_issuing_user() const
Get the user who issued this command.
dpp::interaction::get_command_name
std::string get_command_name() const
Get the command name for a command interaction.
dpp::managed::id
snowflake id
Unique ID of object set by Discord. This value contains a timestamp, worker ID, internal server ID,...
Definition managed.h:39
dpp::slashcommand
Represents an application command, created by your bot either globally, or on a guild.
Definition appcommand.h:1449
dpp::voiceconn
Represents a connection to a voice channel. A client can only connect to one voice channel per guild ...
Definition discordclient.h:152
dpp::unicode_emoji::v
constexpr const char v[]
Definition unicode_emoji.h:1982
dpp::utility::cout_logger
std::function< void(const dpp::log_t &)> DPP_EXPORT cout_logger()
Get a default logger that outputs to std::cout. e.g.
dpp::run_once
auto run_once()
Run some code within an if() statement only once.
Definition once.h:41
dpp::find_guild
DPP_EXPORT class guild * find_guild(snowflake id)
dpp::st_wait
@ st_wait
Wait forever on a condition variable. The cluster will spawn threads for each shard and start() will ...
Definition cluster.h:72
dpp::event_dispatch_t::owner
dpp::cluster * owner
Cluster owning the event dispatch.
Definition dispatcher.h:102
dpp::interaction_create_t::command
interaction command
command interaction
Definition dispatcher.h:789
dpp::ready_t
Session ready.
Definition dispatcher.h:1072
dpp::slashcommand_t
User has issued a slash command.
Definition dispatcher.h:806

To compile this program you must remember to specify libmpg123 alongside libdpp in the build command, for example:

g++ -std=c++20 -o musictest musictest.cpp -lmpg123 -ldpp

Note
  Compiling your bot with a raw g++ command is not advised in any real project, and the example above should be used only as a test. From here, you should learn to create a bot in D++ by moving on to Building a Discord Bot Using CMake (UNIX) or if you have not yet created a token for your bot, Creating a Bot Token - If you are having trouble setting up CMake, you can try our template cmake bot project.

D++ Library version 9.0.13 D++ Library version 9.0.12 D++ Library version 9.0.11 D++ Library version 9.0.10 D++ Library version 9.0.9 D++ Library version 9.0.8 D++ Library version 9.0.7 D++ Library version 9.0.6 D++ Library version 9.0.5 D++ Library version 9.0.4 D++ Library version 9.0.3 D++ Library version 9.0.2 D++ Library version 9.0.1 D++ Library version 9.0.0 D++ Library version 1.0.2 D++ Library version 1.0.1 D++ Library version 1.0.0