임시저장

This commit is contained in:
2025-01-30 01:11:26 +09:00
parent 30569f4472
commit 3186561818
9 changed files with 140 additions and 34 deletions

View File

@@ -76,6 +76,7 @@
"typeindex": "cpp",
"typeinfo": "cpp",
"valarray": "cpp",
"variant": "cpp"
"variant": "cpp",
"*.ipp": "cpp"
}
}

View File

@@ -20,7 +20,6 @@ set_target_properties(${BOT_NAME} PROPERTIES
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
find_package(DPP)
find_package(VLC)
if(APPLE)
if(CMAKE_APPLE_SILICON_PROCESSOR)
set(OPENSSL_ROOT_DIR "/opt/homebrew/opt/openssl")

View File

@@ -14,7 +14,7 @@
namespace bumbleBee {
class AsyncDownloadManager {
public:
static AsyncDownloadManager& getInstance(int worker_count, std::weak_ptr<dpp::cluster> bot, std::weak_ptr<bumbleBee::MusicQueue> musicQueue) {
static AsyncDownloadManager& getInstance(int worker_count, std::weak_ptr<dpp::cluster> bot, std::shared_ptr<bumbleBee::MusicQueue> musicQueue) {
static AsyncDownloadManager dl(worker_count);
dl.bot = bot;
dl.musicQueue = musicQueue;
@@ -24,6 +24,19 @@ public:
std::thread th(&bumbleBee::AsyncDownloadManager::enqueueAsyncDL, this, query);
th.detach();
}
~AsyncDownloadManager(){
auto cluster = bot.lock();
assert(cluster);
cluster->log(dpp::ll_info, "AsyncDownloadManager Destructor called.");
terminate = true;
dlQueueCondition.notify_all();
for (auto& t : worker_thread) {
t.join();
}
}
private:
AsyncDownloadManager(int worker_count){
worker_thread.reserve(worker_count);
@@ -32,14 +45,6 @@ private:
worker_thread.emplace_back([this](){this->downloadWorker();});
}
}
~AsyncDownloadManager(){
terminate = true;
dlQueueCondition.notify_all();
for (auto& t : worker_thread) {
t.join();
}
}
void enqueueAsyncDL(std::string query);
void downloadWorker();
@@ -48,7 +53,7 @@ private:
std::condition_variable dlQueueCondition;
std::mutex dlQueueMutex;
std::weak_ptr<dpp::cluster> bot;
std::weak_ptr<bumbleBee::MusicQueue> musicQueue;
std::shared_ptr<bumbleBee::MusicQueue> musicQueue;
std::vector<std::thread> worker_thread;
bool terminate;
};

View File

@@ -3,7 +3,6 @@
#define _BUMBLEBEE_HPP_
#include <dpp/dpp.h>
#include <dpp/nlohmann/json.hpp>
#include <boost/asio.hpp>
#include <memory>
#include <BumbleBeeCommand.hpp>
#include <MusicQueue.hpp>

View File

@@ -1,10 +1,39 @@
#pragma once
#ifndef _MUSICQUEUE_HPP_
#define _MUSICQUEUE_HPP_
#include <memory>
#include <functional>
#include <condition_variable>
#include <list>
namespace bumbleBee {
class MusicQueueElement {
public:
MusicQueueElement(std::string id, std::string url) : id(id), url(url) {}
std::string id;
std::string url;
};
class MusicQueue {
public:
MusicQueue() {
currentPlayingPosition = queue.begin();
repeat = false;
}
void enqueue(std::shared_ptr<MusicQueueElement> Element);
std::shared_ptr<MusicQueueElement> dequeue();
std::weak_ptr<MusicQueueElement> nowplaying();
std::weak_ptr<MusicQueueElement> next_music();
std::weak_ptr<MusicQueueElement> jump_to_index(int idx);
bool repeat;
std::function<void()> on_queue_added;
private:
std::condition_variable queueItemAdded;
std::mutex queueMutex;
std::list<std::shared_ptr<MusicQueueElement>> queue;
std::list<std::shared_ptr<MusicQueueElement>>::iterator currentPlayingPosition;
};
}

View File

@@ -9,8 +9,9 @@ void AsyncDownloadManager::enqueueAsyncDL(std::string query) {
dlQueueCondition.notify_one();
}
std::string getResultFromCommand(std::string cmd) {
std::string result;
std::queue<std::string> getResultFromCommand(std::string cmd) {
std::string result, token;
std::queue<std::string> tokens;
FILE* stream;
const int maxBuffer = 12; // 버퍼의 크기는 적당하게
char buffer[maxBuffer];
@@ -19,9 +20,15 @@ std::string getResultFromCommand(std::string cmd) {
stream = popen(cmd.c_str(), "r"); // 주어진 command를 shell로 실행하고 파이프 연결 (fd 반환)
if (stream) {
while (fgets(buffer, maxBuffer, stream) != NULL) result.append(buffer); // fgets: fd (stream)를 길이 (maxBuffer)만큼 읽어 버퍼 (buffer)에 저장
pclose(stream); // 파이프 닫는 것 잊지 마시고요!
pclose(stream);
}
return result;
std::stringstream ss(result);
while (std::getline(ss, token, '\n')) {
tokens.push(token);
}
return tokens;
}
void AsyncDownloadManager::downloadWorker() {
@@ -31,26 +38,26 @@ void AsyncDownloadManager::downloadWorker() {
//mutex lock
std::unique_lock<std::mutex> dlQueueLock(dlQueueMutex);
dlQueueCondition.wait(dlQueueLock, [&]{ return !downloadQueue.empty() || terminate; });
auto cluster = bot.lock();
assert(cluster);
if (terminate) {
cluster->log(dpp::ll_info, "Terminating Thread" + tid.str());
break;
}
std::string query = downloadQueue.front();
downloadQueue.pop();
dlQueueLock.unlock();
auto cluster = bot.lock();
assert(cluster);
cluster->log(dpp::ll_info, "Enqueuing " + query + " accepted.");
std::string idstring = getResultFromCommand("./yt-dlp --default-search ytsearch --flat-playlist --skip-download --quiet --ignore-errors --print id " + query);
std::queue<std::string> ids;
std::stringstream ss(idstring);
std::string _id;
while (std::getline(ss, _id, '\n')) {
ids.push(_id);
}
std::queue<std::string> ids = getResultFromCommand("./yt-dlp --default-search ytsearch --flat-playlist --skip-download --quiet --ignore-errors --print id " + query);
if (ids.size() >= 2) {
cluster->log(dpp::ll_info, "Playlist detected.");
while (!ids.empty()) {
if (ids.front() == "") {
ids.pop();
continue;
}
cluster->log(dpp::ll_info, "Enqueuing " + ids.front());
enqueue("https://youtu.be/" + ids.front());
ids.pop();
@@ -58,12 +65,31 @@ void AsyncDownloadManager::downloadWorker() {
break;
}
cluster->log(dpp::ll_info, "Thread id: " + tid.str() + ": " + ids.front() + " accepted.");
std::queue<std::string> urls = getResultFromCommand("./yt-dlp -f ba* --print urls https://youtu.be/" + ids.front());
system(("./yt-dlp -o \"Temp/%(id)s\" --no-clean-info-json --write-info-json --default-search ytsearch \
--flat-playlist --skip-download --quiet --ignore-errors -f ba* https://youtu.be/" + ids.front()).c_str());
cluster->log(dpp::ll_info, "url: " + urls.front());
cluster->log(dpp::ll_info, "Thread id: " + tid.str() + ": " + ids.front() + " downloaded.");
musicQueue->enqueue(std::make_shared<MusicQueueElement>(ids.front(), urls.front()));
std::string downloadID = ids.front();
std::thread th([&, downloadID](){
if (terminate)
return;
std::ostringstream tid;
tid << std::this_thread::get_id();
cluster->log(dpp::ll_info, "Thread id: " + tid.str() + ": " + downloadID + " accepted.");
system(("./yt-dlp -o \"Temp/%(id)s\" --quiet --ignore-errors -f ba* https://youtu.be/" + downloadID).c_str());
system((std::string() + "yes n 2>/dev/null | ffmpeg -hide_banner -loglevel error -i \""
+ "Temp/" + downloadID + "\" -acodec libopus -vn Music/" + downloadID + ".ogg").c_str());
system((std::string() + "rm -f Temp/" + downloadID).c_str());
cluster->log(dpp::ll_info, "Thread id: " + tid.str() + ": " + downloadID + " downloaded.");
});
th.detach();
}
}
}

View File

@@ -14,6 +14,8 @@ BumbleBee::BumbleBee(nlohmann::json settings) {
cluster->on_log(dpp::utility::cout_logger());
cluster->on_slashcommand([this](const dpp::slashcommand_t& event){on_slashcommand(event);});
cluster->on_ready([this](const dpp::ready_t &event){on_ready(event);});
queue = std::make_shared<MusicQueue>();
}
void BumbleBee::start() { this->cluster->start(dpp::st_wait); }

44
src/MusicQueue.cpp Normal file
View File

@@ -0,0 +1,44 @@
#include <MusicQueue.hpp>
#include <iostream>
namespace bumbleBee {
void MusicQueue::enqueue(std::shared_ptr<MusicQueueElement> Element) {
std::lock_guard<std::mutex> lock(queueMutex);
queue.push_back(Element);
}
std::shared_ptr<MusicQueueElement> MusicQueue::dequeue() {
std::lock_guard<std::mutex> lock(queueMutex);
auto value = std::move(queue.front());
queue.pop_front();
return value;
}
std::weak_ptr<MusicQueueElement> MusicQueue::nowplaying() {
return *currentPlayingPosition;
}
std::weak_ptr<MusicQueueElement> MusicQueue::next_music() {
std::lock_guard<std::mutex> lock(queueMutex);
if (currentPlayingPosition == queue.end())
return *currentPlayingPosition;
++currentPlayingPosition;
if (repeat && currentPlayingPosition == queue.end()) {
currentPlayingPosition = queue.begin();
}
return *currentPlayingPosition;
}
std::weak_ptr<MusicQueueElement> MusicQueue::jump_to_index(int idx) {
std::lock_guard<std::mutex> lock(queueMutex);
int index = 0;
for (auto iter = queue.begin(); iter != queue.end(); iter++) {
if (idx == index++) {
currentPlayingPosition = iter;
return *iter;
}
}
std::shared_ptr<MusicQueueElement> empty;
return empty;
}
}

View File

@@ -11,10 +11,11 @@ int main() {
bumbleBee::BumbleBee bot(configdocument);
bumbleBee::AsyncDownloadManager& manager = bumbleBee::AsyncDownloadManager::getInstance(5, bot.cluster, bot.queue);
manager.enqueue("https://music.youtube.com/playlist?list=PL5NSTAfQ-wQBqZYMTqxADemyUW8mxJq2h&si=S1OwPaaif_litCqN");
manager.enqueue("https://music.youtube.com/playlist?list=PL5NSTAfQ-wQBqZYMTqxADemyUW8mxJq2h&si=vFV4jlm70kxGfKNa");
std::thread th([](){sleep(100);});
std::thread th([](){sleep(11);});
th.join();
std::cout << "\n\n\n\n\nend\n\n\n\n\n\n\n";
//bot.start();
}