diff options
author | ComradeCrow <comradecrow@vivaldi.net> | 2023-04-25 20:28:08 -0700 |
---|---|---|
committer | ComradeCrow <comradecrow@vivaldi.net> | 2023-04-25 20:28:08 -0700 |
commit | cf0ab4d19100846a9850a3cc39110d8d8cfd1607 (patch) | |
tree | 8077c8eacaf3d7f6161d8bff232ec0571a07c797 /src | |
parent | 407a6f2507c784918a1c77ade4114c706f2c1e34 (diff) | |
download | ytcpp-cf0ab4d19100846a9850a3cc39110d8d8cfd1607.tar.gz |
broken
Diffstat (limited to 'src')
-rw-r--r-- | src/YtdlpWrapper.cpp | 230 | ||||
-rw-r--r-- | src/YtdlpWrapper.hpp | 37 | ||||
-rw-r--r-- | src/invapi.cpp | 2 | ||||
-rw-r--r-- | src/main.cpp | 33 |
4 files changed, 278 insertions, 24 deletions
diff --git a/src/YtdlpWrapper.cpp b/src/YtdlpWrapper.cpp index 7368c14..a1e417f 100644 --- a/src/YtdlpWrapper.cpp +++ b/src/YtdlpWrapper.cpp @@ -10,6 +10,118 @@ using json = nlohmann::json; namespace py = pybind11; using namespace py::literals; +void Video::to_json(json& j, const format& f) { + + j = json{{"format", f.format}, + {"url", f.url}, + {"vcodec", f.vcodec}, + {"acodec", f.acodec}, + {"ext", f.ext} + }; + + if (f.quality.has_value()) { j["quality"] = f.quality.value(); } + if (f.resolution.has_value()) { j["resolution"] = f.resolution.value(); } + if (f.height.has_value()) { j["height"] = f.height.value(); } + if (f.width.has_value()) { j["width"] = f.width.value(); } +} + +void Video::to_json(json& j, const thumbnail& t) { + + j = json{{"url", t.url}, + {"preference", t.preference}, + {"id", t.id} + }; + + if (t.resolution.has_value()) { j["resolution"] = t.resolution.value(); } + if (t.height.has_value()) { j["height"] = t.height.value(); } + if (t.width.has_value()) { j["width"] = t.width.value(); } +} + +void Video::to_json(json& j, const video& v) { + + j = json{{"id", v.id}, + {"title", v.title}, + {"url", v.url}, + {"channel_id", v.channelId}, + {"channel_url", v.channelUrl}}; + + if (v.uploader.has_value()) { j["uploader"] = v.uploader.value(); } + if (v.uploaderId.has_value()) { j["uploader_id"] = v.uploaderId.value(); } + if (v.uploaderUrl.has_value()) { j["uploader_url"] = v.uploaderUrl.value(); } + if (v.duration.has_value()) { j["duration"] = v.duration.value(); } + if (v.viewcount.has_value()) { j["view_count"] = v.viewcount.value(); } + if (v.description.has_value()) { j["description"] = v.description.value(); } + + j["formats"] = json::array(); + + for (format f: v.formats) { + + j.at("formats").emplace_back(json(f)); + } + + j["thumbnails"] = json::array(); + + for (thumbnail t: v.thumbnails) { + + j.at("thumbnails").emplace_back(json(t)); + } +} + +void Video::from_json(const json& j, format& f) { + + j.at("format").get_to(f.format); + j.at("url").get_to(f.url); + j.at("vcodec").get_to(f.vcodec); + j.at("acodec").get_to(f.acodec); + j.at("ext").get_to(f.ext); + + if (j.contains("quality")) { f.quality = j.at("quality"); } + if (j.contains("resolution")) { f.resolution = j.at("resolution"); } + if (j.contains("width")) { f.width = j.at("width"); } + if (j.contains("height")) { f.height = j.at("height"); } +} + +void Video::from_json(const json& j, thumbnail& t) { + + j.at("url").get_to(t.url); + j.at("preference").get_to(t.preference); + j.at("id").get_to(t.id); + + if (j.contains("resolution")) { t.resolution = j.at("resolution"); } + if (j.contains("width")) { t.width = j.at("width"); } + if (j.contains("height")) { t.height = j.at("height"); } +} + +void Video::from_json(const json& j, video& v) { + + j.at("id").get_to(v.id); + j.at("title").get_to(v.title); + j.at("url").get_to(v.url); + j.at("channelId").get_to(v.channelId); + j.at("channelUrl").get_to(v.channelUrl); + + if (j.contains("uploader")) { v.uploader = j.at("uploader"); } + if (j.contains("uploader_id")) { v.uploaderId = j.at("uploader_id"); } + if (j.contains("uploader_url")) { v.uploaderUrl = j.at("uploader_url"); } + if (j.contains("duration")) { v.duration = j.at("duration"); } + if (j.contains("view_count")) { v.viewcount = j.at("view_count"); } + if (j.contains("description")) { v.description = j.at("description"); } + + for (json f: j.at("formats")) { + + format form; + from_json(j, form); + v.formats.push_back(form); + } + + for (json t: j.at("thumbnails")) { + + thumbnail thumb; + from_json(j, thumb); + v.thumbnails.push_back(thumb); + } +} + std::string pyDictToJsonString(const py::dict& dict) { pybind11::object json = py::module::import("json"); @@ -20,7 +132,6 @@ py::object YtdlpWrapper::get_ytdl() { if (ytdl.is_none()) { ytdl = py::module::import("yt_dlp"); - ytdl = ytdl.attr("YoutubeDL")(py::dict("ignoreerrors"_a=py::bool_(true))); } return ytdl; @@ -28,7 +139,9 @@ py::object YtdlpWrapper::get_ytdl() { json YtdlpWrapper::getJsonSearch(const std::string& searchTerm, int limit) { - py::dict info = get_ytdl().attr("extract_info")("ytsearch"+std::to_string(limit)+":"+searchTerm, "download"_a=py::bool_(false)); + py::dict info = get_ytdl() + .attr("YoutubeDL")(py::dict("ignoreerrors"_a=py::bool_(true))) + .attr("extract_info")("ytsearch"+std::to_string(limit)+":"+searchTerm, "download"_a=py::bool_(false)); return json::parse(pyDictToJsonString(info)); } @@ -38,10 +151,119 @@ std::vector<Video::video> YtdlpWrapper::searchVideos(const std::string& searchTe json info = getJsonSearch(searchTerm, limit); - for (json i: info["entries"]) { - std::cout << i["id"] << std::endl; + for (json i: info.at("entries")) { + Video::video entry{i.at("id"), i.at("title"), i.at("original_url"), {i.at("channel_url")}}; + + for (json j: i.at("formats")) { + + Video::format form{j.at("format"), j.at("url"), j.at("vcodec"), j.at("acodec"), j.at("ext")}; + + if (j.contains("quality")) { + + form.quality = j.at("quality"); + } + + if (j.contains("resolution")) { + + form.resolution = j.at("resolution"); + } + + if (j.contains("width")) { + + form.width = j.at("width"); + } + + if (j.contains("height")) { + + form.height = j.at("height"); + } + entry.formats.push_back(form); + } + + for (json j: i.at("thumbnails")) { + + Video::thumbnail thumb{j.at("url"), j.at("preference"), j.at("id")}; + + if (j.contains("resolution")) { + + thumb.resolution = j.at("resolution"); + } + + if (j.contains("height")) { + + thumb.height = j.at("height"); + } + + if (j.contains("width")) { + + thumb.width = j.at("width"); + } + + entry.thumbnails.push_back(thumb); + } + + resp.push_back(entry); } return resp; } + +Video::video YtdlpWrapper::getVideoByUrl(const std::string& url) { + + json info = json::parse(pyDictToJsonString( + get_ytdl().attr("YoutubeDL")(py::dict("ignoreerrors"_a=py::bool_(true), "noplaylist"_a=py::bool_(true))) + .attr("extract_info")(url, "download"_a=py::bool_(false)) + )); + + Video::video resp{info.at("id"), info.at("title"), info.at("original_url"), {info.at("channel_url")}}; + + for (json j: info.at("formats")) { + + Video::format form{j.at("format"), j.at("url"), j.at("vcodec"), j.at("acodec"), j.at("ext")}; + + if (j.contains("quality")) { + + form.quality = j.at("quality"); + } + + if (j.contains("resolution")) { + + form.resolution = j.at("resolution"); + } + + if (j.contains("width")) { + + form.width = j.at("width"); + } + + if (j.contains("height")) { + + form.height = j.at("height"); + } + resp.formats.push_back(form); + } + + for (json j: info.at("thumbnails")) { + + Video::thumbnail thumb{j.at("url"), j.at("preference"), j.at("id")}; + + if (j.contains("resolution")) { + + thumb.resolution = j.at("resolution"); + } + + if (j.contains("height")) { + + thumb.height = j.at("height"); + } + + if (j.contains("width")) { + + thumb.width = j.at("width"); + } + + resp.thumbnails.push_back(thumb); + } + return resp; +} \ No newline at end of file diff --git a/src/YtdlpWrapper.hpp b/src/YtdlpWrapper.hpp index f2e916e..9138346 100644 --- a/src/YtdlpWrapper.hpp +++ b/src/YtdlpWrapper.hpp @@ -8,11 +8,15 @@ namespace Video { struct format { - std::optional<float> quality; - std::optional<std::string> ext; + std::string format; std::string url; std::string vcodec; std::string acodec; + std::string ext; + std::optional<float> quality; + std::optional<std::string> resolution; + std::optional<int> height; + std::optional<int> width; }; struct thumbnail { @@ -25,33 +29,36 @@ namespace Video { std::optional<int> width; }; - struct channel { - - std::string channelUrl; - std::optional<std::string> channelId; - std::optional<std::string> uploader; - std::optional<std::string> uploaderId; - std::optional<std::string> uploaderUrl; - }; - struct video { std::string id; std::string title; std::string url; - channel uploader; + std::string channelId; + std::string channelUrl; + std::vector<format> formats; + std::vector<thumbnail> thumbnails; + std::optional<std::string> uploader; + std::optional<std::string> uploaderId; + std::optional<std::string> uploaderUrl; std::optional<int> duration; std::optional<int> viewcount; std::optional<std::string> description; - std::vector<format> formats; - std::vector<thumbnail> thumbnails; }; -} + + void to_json(nlohmann::json& j, const format& f); + void to_json(nlohmann::json& j, const thumbnail& t); + void to_json(nlohmann::json& j, const video& v); + void from_json(const nlohmann::json& j, format& f); + void from_json(const nlohmann::json& j, thumbnail& t); + void from_json(const nlohmann::json& j, video& v); +}; class YtdlpWrapper { public: nlohmann::json getJsonSearch(const std::string& searchTerm, int limit = 1); + Video::video getVideoByUrl(const std::string& url); std::vector<Video::video> searchVideos(const std::string& searchterm, int limit = 1); private: pybind11::object get_ytdl(); diff --git a/src/invapi.cpp b/src/invapi.cpp index b96d18b..1433c10 100644 --- a/src/invapi.cpp +++ b/src/invapi.cpp @@ -24,7 +24,7 @@ vector<string> getInstances() { json j = json::parse(r.text); for ( json i: j ) { - if ( i[1]["api"] != json::value_t::null && i[1]["api"]) { + if ( i.at(1).at("api") != json::value_t::null && i.at(1).at("api")) { result.push_back( i[1]["uri"] ); } diff --git a/src/main.cpp b/src/main.cpp index 8c9503d..059657c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,12 @@ // #include <cpr/cpr.h> -// #include <nlohmann/json.hpp> +#include <nlohmann/json.hpp> // #include <pybind11/embed.h> // #include <sqlite3.h> // #include <string> -// #include <iostream> +#include <iostream> // #include <exception> // #include <vector> +#include <fstream> #include "tui.hpp" #include "invapi.hpp" @@ -15,11 +16,35 @@ // namespace py = pybind11; using namespace std; +using json = nlohmann::json; + +void validateStructConversions() { + + std::ifstream inputFile{"./raycharles.json"}; + auto size = inputFile.tellg(); + cout << size << endl; + std::string str(size, '\0'); // construct string to stream size + inputFile.seekg(0); + if(inputFile.read(&str[0], size)) + std::cout << str << '\n'; + + // json info = json::parse(inputFile); + // Video::video v = info["entries"].get<Video::video>(); + // json j = v; + // cout << j << endl; +} int main(int argc, char **argv) { - YtdlpWrapper yt; - yt.searchVideos("the very thought of you", 5); + validateStructConversions(); + + // YtdlpWrapper yt; + // vector<Video::video> response = yt.searchVideos("factorio"); + // for (Video::video i: response) { + + // cout << i.id << ", " << i.url << ", " << endl; + // } + // nlohmann::json j = yt.getJsonSearch("the very thought of you"); // cout << j << endl; |