From a13c19e31cb033730fa179a90f0bc5bd961bd3dc Mon Sep 17 00:00:00 2001 From: dec05eba Date: Fri, 4 Mar 2022 00:06:11 +0100 Subject: Fix xv video and related page, fix possible crash when going back from related video --- src/QuickMedia.cpp | 30 +++++++++++++++++------- src/plugins/MediaGeneric.cpp | 56 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 74 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 1ee0816..b788e0b 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -922,6 +922,23 @@ namespace QuickMedia { media_generic_search_page->search_handler("https://www.xvideos.com/?k=%s&p=%p", 0) .text_handler({{"//div[id='main']//div[class='thumb-under']//a", "title", "href", "/video"}}) .thumbnail_handler({{"//div[id='main']//div[class='thumb']//img", "data-src", "/videos"}}) + .video_url_custom_handler([](const std::string &html_source) -> std::string { + size_t start_index = html_source.find("html5player.setVideoHLS"); + if(start_index == std::string::npos) + return ""; + + start_index += 23; + start_index = html_source.find("'", start_index); + if(start_index == std::string::npos) + return ""; + + start_index += 1; + size_t end_index = html_source.find("'", start_index); + if(end_index == std::string::npos) + return ""; + + return html_source.substr(start_index, end_index - start_index); + }) .related_media_custom_handler([](const std::string &html_source) { std::vector related_items; size_t related_start = html_source.find("video_related=["); @@ -969,10 +986,10 @@ namespace QuickMedia { static void add_xhamster_handlers(MediaGenericSearchPage *media_generic_search_page) { media_generic_search_page->search_handler("https://xhamster.com/search/%s?page=%p", 1) - .text_handler({{"//div[class='video-thumb-info']//a", "text", "href", "/videos/"}}) - .thumbnail_handler({{"//img", "src", "/thumb-"}}) - .related_media_text_handler({{"//div[class='video-thumb-info']//a", "text", "href", "/videos/"}}) - .related_media_thumbnail_handler({{"//img", "src", "/thumb-"}}); + .text_handler({{"//div[data-role='video-list']//div[class='video-thumb-info']//a", "text", "href", "/videos/"}}) + .thumbnail_handler({{"//div[data-role='video-list']//img", "src", "/thumb-"}}) + .related_media_text_handler({{"//div[data-role='video-relations']//div[class='video-thumb-info']//a", "text", "href", "/videos/"}}) + .related_media_thumbnail_handler({{"//div[data-role='video-relations']//img", "src", "/thumb-"}}); } static void check_youtube_dl_installed(const std::string &plugin_name) { @@ -1250,15 +1267,12 @@ namespace QuickMedia { tabs.push_back(Tab{create_body(false, true), std::move(search_page), create_search_bar("Search...", 500)}); use_youtube_dl = true; } else if(strcmp(plugin_name, "xvideos") == 0) { - check_youtube_dl_installed(plugin_name); - std::vector extra_commands = { { "--header", "Cookie: last_views=%5B%2236247565-" + std::to_string(time(nullptr)) + "%22%5D" } }; auto search_page = std::make_unique(this, "https://www.xvideos.com/", mgl::vec2i(352/1.5f, 198/1.5f), true, std::move(extra_commands)); add_xvideos_handlers(search_page.get()); tabs.push_back(Tab{create_body(false, true), std::move(search_page), create_search_bar("Search...", 500)}); - use_youtube_dl = true; } else if(strcmp(plugin_name, "xhamster") == 0) { check_youtube_dl_installed(plugin_name); auto search_page = std::make_unique(this, "https://xhamster.com/", mgl::vec2i(240, 135), true); @@ -2854,7 +2868,6 @@ namespace QuickMedia { return url.find("pornhub.com") != std::string::npos || url.find("xhamster.com") != std::string::npos || url.find("spankbang.com") != std::string::npos - || url.find("xvideos.com") != std::string::npos // TODO: Remove when youtube-dl is no longer required to download soundcloud music || is_soundcloud(url); } @@ -3235,6 +3248,7 @@ namespace QuickMedia { return; std::string url = video_page->get_url(); + related_videos.clear(); related_videos_task = AsyncTask([&related_videos, url, video_page]() { video_page->mark_watched(); related_videos = video_page->get_related_media(url); diff --git a/src/plugins/MediaGeneric.cpp b/src/plugins/MediaGeneric.cpp index adbac0d..5ee5fbc 100644 --- a/src/plugins/MediaGeneric.cpp +++ b/src/plugins/MediaGeneric.cpp @@ -37,7 +37,12 @@ namespace QuickMedia { } } - static PluginResult fetch_page_results(const std::string &url, const std::string &website_url, const std::vector &text_queries, const std::vector &thumbnail_queries, mgl::vec2i thumbnail_max_size, MediaRelatedCustomHandler *custom_handler, BodyItems &result_items, bool cloudflare_bypass, const std::vector &extra_commands) { + static PluginResult fetch_page_results( + const std::string &url, const std::string &website_url, const std::vector &text_queries, + const std::vector &thumbnail_queries, mgl::vec2i thumbnail_max_size, + MediaRelatedCustomHandler *related_custom_handler, + BodyItems &result_items, bool cloudflare_bypass, const std::vector &extra_commands) + { std::vector args = extra_commands; if(!website_url.empty()) args.push_back({ "--header", "referer: " + website_url }); @@ -49,8 +54,8 @@ namespace QuickMedia { if(website_data.empty()) return PluginResult::OK; - if(custom_handler && *custom_handler) { - std::vector media_related_items = (*custom_handler)(website_data); + if(related_custom_handler && *related_custom_handler) { + std::vector media_related_items = (*related_custom_handler)(website_data); for(MediaRelatedItem &media_related_item : media_related_items) { auto body_item = BodyItem::create(media_related_item.title); body_item->url = std::move(media_related_item.url); @@ -163,6 +168,11 @@ namespace QuickMedia { return *this; } + MediaGenericSearchPage& MediaGenericSearchPage::video_url_custom_handler(MediaVideoUrlCustomHandler handler) { + video_custom_handler = std::move(handler); + return *this; + } + MediaGenericSearchPage& MediaGenericSearchPage::related_media_text_handler(std::vector queries) { related_media_text_queries = std::move(queries); related_custom_handler = nullptr; @@ -176,7 +186,7 @@ namespace QuickMedia { } MediaGenericSearchPage& MediaGenericSearchPage::related_media_custom_handler(MediaRelatedCustomHandler handler) { - related_custom_handler = handler; + related_custom_handler = std::move(handler); related_media_text_queries.clear(); related_media_thumbnail_queries.clear(); return *this; @@ -199,4 +209,42 @@ namespace QuickMedia { result_tabs.push_back(Tab{std::move(related_page_body), std::make_unique(program, search_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); return PluginResult::OK; } + + std::string MediaGenericVideoPage::get_download_url(int max_height) { + // TODO: Use max_height, if possible + (void)max_height; + return video_url; + } + + std::string MediaGenericVideoPage::get_video_url(int max_height, bool &has_embedded_audio, std::string &ext) { + // TODO: Use max_height, if possible + (void)max_height; + has_embedded_audio = true; + ext = "m3u8"; + return video_url; + } + + PluginResult MediaGenericVideoPage::load(std::string&, std::string&, std::vector&, std::string &err_msg) { + video_url.clear(); + if(!search_page->video_custom_handler) { + video_url = url; + return PluginResult::OK; + } + + std::vector args = search_page->extra_commands; + if(!url.empty()) + args.push_back({ "--header", "referer: " + url }); + + std::string website_data; + if(download_to_string(url, website_data, args, true, true, search_page->cloudflare_bypass) != DownloadResult::OK) + return PluginResult::NET_ERR; + + video_url = search_page->video_custom_handler(website_data); + if(video_url.empty()) { + err_msg = "Failed to extract video url"; + return PluginResult::ERR; + } else { + return PluginResult::OK; + } + } } \ No newline at end of file -- cgit v1.2.3