#include "Server.hpp" #include #include #include #include #include #include #include #include #include #include "packets/AudioPacket.hpp" Server::Server() { // create a new mpg123 handle int error; this->mpgHandle = mpg123_new(nullptr, &error); if (this->mpgHandle == nullptr) throw std::runtime_error("[Server] Could not create a mpg123 handle."); // open the mp3 file if (mpg123_open( this->mpgHandle, "./assets/Caravan Palace - Wonderland.mp3" )) throw std::runtime_error("[Server] Could not open file."); // get the format of the file if (mpg123_getformat( this->mpgHandle, &this->rate, &this->channels, &this->encoding ) != MPG123_OK) throw std::runtime_error("[Server] Could not get the format of the file."); } Server::~Server() { // delete the mpg123 handle mpg123_close(this->mpgHandle); mpg123_delete(this->mpgHandle); } void Server::loop() { // get the broadcast address addrinfo broadcastHints {}; broadcastHints.ai_family = AF_INET6; broadcastHints.ai_socktype = SOCK_DGRAM; broadcastHints.ai_protocol = IPPROTO_UDP; // TODO(Faraphel): ip / port as argument addrinfo *broadcastInfo; if(const int error = getaddrinfo( "::1", "5650", &broadcastHints, &broadcastInfo ) != 0) throw std::runtime_error("[Server] Could not get the address: " + std::string(gai_strerror(error))); const int broadcastSocket = socket( broadcastInfo->ai_family, broadcastInfo->ai_socktype, broadcastInfo->ai_protocol ); if (broadcastSocket == -1) throw std::runtime_error("[Server] Could not create the socket: " + std::string(gai_strerror(errno))); // read the file AudioPacket audioPacket; std::size_t done; while (mpg123_read( this->mpgHandle, &audioPacket.content, std::size(audioPacket.content), &done ) == MPG123_OK) { // set the target time audioPacket.timePlay = std::chrono::high_resolution_clock::now() + std::chrono::milliseconds(5000); // set the size of the content audioPacket.contentSize = done; if (sendto( broadcastSocket, &audioPacket, sizeof(audioPacket), 0, broadcastInfo->ai_addr, broadcastInfo->ai_addrlen ) == -1) { std::cerr << "[Server] Could not send audio packet: " << strerror(errno) << std::endl; continue; } std::cout << "[Server] Sent: " << done << " bytes" << std::endl; // wait 10ms to simulate lag // TODO(Faraphel): should be extended to simulate live music streaming std::this_thread::sleep_for(std::chrono::milliseconds(static_cast( (1 / static_cast(this->rate * this->channels * mpg123_encsize(this->encoding))) * 1000 * static_cast(done) ))); } // free the server address freeaddrinfo(broadcastInfo); } long Server::getRate() const { return this->rate; } int Server::getChannels() const { return this->channels; } int Server::getEncoding() const { return this->encoding; }