D++ (DPP)
C++ Discord API Bot Library
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 <dpp/nlohmann/json.hpp>
#include <dpp/fmt/format.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(int argc, char const *argv[])
{
/* 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);
unsigned int counter = 0;
for (int totalBtyes = 0; mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK; ) {
for (auto i = 0; i < buffer_size; i++) {
pcmdata.push_back(buffer[i]);
}
counter += buffer_size;
totalBtyes += done;
}
delete buffer;
mpg123_close(mh);
mpg123_delete(mh);
/* Setup the bot */
dpp::cluster bot("token");
/* Use the on_message_create event to look for commands */
bot.on_message_create([&bot, &pcmdata](const dpp::message_create_t & event) {
std::stringstream ss(event.msg->content);
std::string command;
ss >> command;
/* Tell the bot to join the discord voice channel the user is on. Syntax: .join */
if (command == ".join") {
if (!g->connect_member_voice(event.msg->author->id)) {
bot.message_create(dpp::message(event.msg->channel_id, "You don't seem to be on a voice channel! :("));
}
}
/* Tell the bot to play the mp3 file. Syntax: .mp3 */
if (command == ".mp3") {
dpp::voiceconn* v = event.from->get_voice(event.msg->guild_id);
if (v && v->voiceclient && v->voiceclient->is_ready()) {
/* 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());
}
}
});
/* A basic logger */
bot.on_log([](const dpp::log_t & event) {
if (event.severity > dpp::ll_trace) {
std::cout << event.message << "\n";
}
});
/* Start bot */
bot.start(false);
/* Clean up */
mpg123_exit();
return 0;
}
The cluster class represents a group of shards and a command queue for sending and receiving commands...
Definition: cluster.h:233
discord_voice_client & send_audio_raw(uint16_t *audio_data, const size_t length)
Send raw audio to the voice channel.
bool is_ready()
voice client is ready to stream audio. The voice client is considered ready if it has a secret key.
Represents a guild on Discord (AKA a server)
Definition: guild.h:203
bool connect_member_voice(snowflake user_id, bool self_mute=false, bool self_deaf=false)
Connect to a voice channel another guild member is in.
snowflake id
Definition: discord.h:44
Represents a connection to a voice channel. A client can only connect to one voice channel per guild ...
Definition: discordclient.h:60
class discord_voice_client * voiceclient
voice websocket client
Definition: discordclient.h:89
DPP_EXPORT guild * find_guild(snowflake id)
@ ll_trace
Trace.
Definition: discord.h:64
Log messages.
Definition: dispatcher.h:104
loglevel severity
Definition: dispatcher.h:112
Create message.
Definition: dispatcher.h:1017
message * msg
message that was created (sent). If you use any parts of this in another thread, take a copy!...
Definition: dispatcher.h:1027
Represents messages sent and received on Discord.
Definition: message.h:944
user * author
Definition: message.h:952
snowflake guild_id
Definition: message.h:950
std::string content
Definition: message.h:956
snowflake channel_id
Definition: message.h:948

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

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

D++ Library version 10.0.29D++ Library version 10.0.28D++ Library version 10.0.27D++ Library version 10.0.26D++ Library version 10.0.25D++ Library version 10.0.24D++ Library version 10.0.23D++ Library version 10.0.22D++ Library version 10.0.21D++ Library version 10.0.20D++ Library version 10.0.19D++ Library version 10.0.18D++ Library version 10.0.17D++ Library version 10.0.16D++ Library version 10.0.15D++ Library version 10.0.14D++ Library version 10.0.13D++ Library version 10.0.12D++ Library version 10.0.11D++ Library version 10.0.10D++ Library version 10.0.9D++ Library version 10.0.8D++ Library version 10.0.7D++ Library version 10.0.6D++ Library version 10.0.5D++ Library version 10.0.4D++ Library version 10.0.3D++ Library version 10.0.2D++ Library version 10.0.1D++ Library version 10.0.0D++ Library version 9.0.19D++ Library version 9.0.18D++ Library version 9.0.17D++ Library version 9.0.16D++ Library version 9.0.15D++ Library version 9.0.14D++ Library version 9.0.13D++ Library version 9.0.12D++ Library version 9.0.11D++ Library version 9.0.10D++ Library version 9.0.9D++ Library version 9.0.8D++ Library version 9.0.7D++ Library version 9.0.6D++ Library version 9.0.5D++ Library version 9.0.4D++ Library version 9.0.3D++ Library version 9.0.2D++ Library version 9.0.1D++ Library version 9.0.0D++ Library version 1.0.2D++ Library version 1.0.1D++ Library version 1.0.0