mirror of
https://github.com/HappyTanuki/BumbleCee.git
synced 2025-10-25 17:35:58 +00:00
임시저장
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -76,6 +76,7 @@
|
||||
"typeindex": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp"
|
||||
"variant": "cpp",
|
||||
"*.ipp": "cpp"
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
44
src/MusicQueue.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
Reference in New Issue
Block a user