stream-mp3-discord-bot

# 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>

    /*Foranexamplewewillhardcodeapathtosomeawesomemusichere*/
    #defineMUSIC_FILE"/media/music/RickAstley/WheneverYouNeedSomebody/NeverGonnaGiveYouUp.mp3"

    intmain(){
    /*ThiswillholdthedecodedMP3.
    *TheD++libraryexpectsPCMformat,whicharerawsound
    *data,2channelstereo,16bitsigned48000Hz.
    */
    std::vector<uint8_t>pcmdata;

    mpg123_init();

    interr=0;
    unsignedchar*buffer;
    size_tbuffer_size,done;
    intchannels,encoding;
    longrate;

    /*Noteitisimportanttoforcethefrequencyto48000forDiscordcompatibility*/
    mpg123_handle*mh=mpg123_new(NULL,&err);
    mpg123_param(mh,MPG123_FORCE_RATE,48000,48000.0);

    /*Decodeentirefileintoavector.Youcoulddothisonthefly,butifyoudothat
    *youmaygettimingissuesifyourCPUisbusyatthetimeandyouarestreamingto
    *alotofchannels/guilds.
    */
    buffer_size=mpg123_outblock(mh);
    buffer=newunsignedchar[buffer_size];

    /*Note:Inarealworldbot,thisshouldhavesomeerrorlogging*/
    mpg123_open(mh,MUSIC_FILE);
    mpg123_getformat(mh,&rate,&channels,&encoding);

    while(mpg123_read(mh,buffer,buffer_size,&done)==MPG123_OK){
    for(size_ti=0;i<buffer_size;i++){
    pcmdata.push_back(buffer[i]);
    }
    }
    delete[]buffer;
    mpg123_close(mh);
    mpg123_delete(mh);

    /*Setupthebot*/
    dpp::clusterbot("token");

    bot.on_log(dpp::utility::cout_logger());

    /*Theeventisfiredwhensomeoneissuesyourcommands*/
    bot.on_slashcommand([&pcmdata](constdpp::slashcommand_t&event){
    /*Checkwhichcommandtheyran*/
    if(event.command.get_command_name()=="join"){
    /*Gettheguild*/
    dpp::guild*g=dpp::find_guild(event.command.guild_id);

    /*Attempttoconnecttoavoicechannel,returnsfalseifwefailtoconnect.*/
    if(!g->connect_member_voice(*event.owner,event.command.get_issuing_user().id)){
    event.reply("Youdon'tseemtobeinavoicechannel!");
    return;
    }

    /*Telltheuserwejoinedtheirchannel.*/
    event.reply("Joinedyourchannel!");
    }elseif(event.command.get_command_name()=="mp3"){
    /*Getthevoicechannelthebotisin,inthiscurrentguild.*/
    dpp::voiceconn*v=event.from()->get_voice(event.command.guild_id);

    /*Ifthevoicechannelwasinvalid,orthereisanissuewithit,thentelltheuser.*/
    if(!v||!v->voiceclient||!v->voiceclient->is_ready()){
    event.reply("Therewasanissuewithgettingthevoicechannel.MakesureI'minavoicechannel!");
    return;
    }

    /*StreamthealreadydecodedMP3file.ThispassesthePCMdatatothelibrarytobeencodedtoOPUS*/
    v->voiceclient->send_audio_raw((uint16_t*)pcmdata.data(),pcmdata.size());

    event.reply("Playedthemp3file.");
    }
    });

    bot.on_ready([&bot](constdpp::ready_t&event){
    if(dpp::run_once<struct register_bot_commands>()){
    /*Createanewcommand.*/
    dpp::slashcommandjoincommand("join","Joinsyourvoicechannel.",bot.me.id);
    dpp::slashcommandmp3command("mp3","Playsanmp3file.",bot.me.id);

    bot.global_bulk_command_create({joincommand,mp3command});
    }
    });

    /*Startbot*/
    bot.start(dpp::st_wait);

    /*Cleanup*/
    mpg123_exit();

    return0;
    }

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

    g++-std=c++20-omusictestmusictest.cpp-lmpg123-ldpp

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.