diff options
-rw-r--r-- | src/plugins/Youtube.cpp | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp index b68e513..6923d04 100644 --- a/src/plugins/Youtube.cpp +++ b/src/plugins/Youtube.cpp @@ -3,6 +3,7 @@ #include <json/reader.h> #include <json/writer.h> #include <string.h> +#include <unordered_set> namespace QuickMedia { static void iterate_suggestion_result(const Json::Value &value, std::vector<std::string> &result_items, int &iterate_count) { @@ -16,7 +17,7 @@ namespace QuickMedia { } } - static std::unique_ptr<BodyItem> parse_content_video_renderer(const Json::Value &content_item_json) { + static std::unique_ptr<BodyItem> parse_content_video_renderer(const Json::Value &content_item_json, std::unordered_set<std::string> &added_videos) { if(!content_item_json.isObject()) return nullptr; @@ -29,6 +30,9 @@ namespace QuickMedia { return nullptr; std::string video_id_str = video_id_json.asString(); + if(added_videos.find(video_id_str) != added_videos.end()) + return nullptr; + std::string thumbnail_url = "https://img.youtube.com/vi/" + video_id_str + "/hqdefault.jpg"; const char *title = nullptr; @@ -51,6 +55,7 @@ namespace QuickMedia { auto body_item = std::make_unique<BodyItem>(title); body_item->url = "https://www.youtube.com/watch?v=" + video_id_str; body_item->thumbnail_url = std::move(thumbnail_url); + added_videos.insert(video_id_str); return body_item; } @@ -91,6 +96,8 @@ namespace QuickMedia { if(!json_root.isArray()) return PluginResult::ERR; + std::unordered_set<std::string> added_videos; + for(const Json::Value &json_item : json_root) { if(!json_item.isObject()) continue; @@ -137,7 +144,7 @@ namespace QuickMedia { continue; const Json::Value &rich_item_contents = rich_item_renderer_json["content"]; - std::unique_ptr<BodyItem> body_item = parse_content_video_renderer(rich_item_contents); + std::unique_ptr<BodyItem> body_item = parse_content_video_renderer(rich_item_contents, added_videos); if(body_item) result_items.push_back(std::move(body_item)); } @@ -242,16 +249,43 @@ namespace QuickMedia { return continuation_json.asString(); } - static void parse_item_section_renderer(const Json::Value &item_section_renderer_json, std::string &continuation_token, BodyItems &result_items) { + static void parse_item_section_renderer(const Json::Value &item_section_renderer_json, std::string &continuation_token, std::unordered_set<std::string> &added_videos, BodyItems &result_items) { if(continuation_token.empty()) continuation_token = item_section_renderer_get_continuation_token(item_section_renderer_json); const Json::Value &item_contents_json = item_section_renderer_json["contents"]; if(!item_contents_json.isArray()) return; - + + for(const Json::Value &content_item_json : item_contents_json) { + if(!content_item_json.isObject()) + continue; + + const Json::Value &shelf_renderer_json = content_item_json["shelfRenderer"]; + if(!shelf_renderer_json.isObject()) + continue; + + const Json::Value &item_content_json = shelf_renderer_json["content"]; + if(!item_content_json.isObject()) + continue; + + const Json::Value &vertical_list_renderer_json = item_content_json["verticalListRenderer"]; + if(!vertical_list_renderer_json.isObject()) + continue; + + const Json::Value &items_json = vertical_list_renderer_json["items"]; + if(!items_json.isArray()) + continue; + + for(const Json::Value &item_json : items_json) { + std::unique_ptr<BodyItem> body_item = parse_content_video_renderer(item_json, added_videos); + if(body_item) + result_items.push_back(std::move(body_item)); + } + } + for(const Json::Value &content_item_json : item_contents_json) { - std::unique_ptr<BodyItem> body_item = parse_content_video_renderer(content_item_json); + std::unique_ptr<BodyItem> body_item = parse_content_video_renderer(content_item_json, added_videos); if(body_item) result_items.push_back(std::move(body_item)); } @@ -288,6 +322,7 @@ namespace QuickMedia { return SuggestionResult::ERR; std::string continuation_token; + std::unordered_set<std::string> added_videos; /* The input contains duplicates, filter them out! */ for(const Json::Value &json_item : json_root) { if(!json_item.isObject()) @@ -325,7 +360,7 @@ namespace QuickMedia { if(!item_section_renderer_json.isObject()) continue; - parse_item_section_renderer(item_section_renderer_json, continuation_token, result_items); + parse_item_section_renderer(item_section_renderer_json, continuation_token, added_videos, result_items); } } @@ -367,6 +402,7 @@ namespace QuickMedia { return; std::string next_continuation_token; + std::unordered_set<std::string> added_videos; for(const Json::Value &json_item : json_root) { if(!json_item.isObject()) @@ -385,7 +421,7 @@ namespace QuickMedia { continue; // Note: item_section_continuation json object is compatible with item_section_renderer json object - parse_item_section_renderer(item_section_continuation_json, next_continuation_token, result_items); + parse_item_section_renderer(item_section_continuation_json, next_continuation_token, added_videos, result_items); } } |