aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-03-04 00:06:11 +0100
committerdec05eba <dec05eba@protonmail.com>2022-03-04 00:06:11 +0100
commita13c19e31cb033730fa179a90f0bc5bd961bd3dc (patch)
treeee459da17b1baa8a1aba503451231a5075c46c8a /src
parent8497b3daea44fe26fbc2d089a55e75a219e8d603 (diff)
Fix xv video and related page, fix possible crash when going back from related video
Diffstat (limited to 'src')
-rw-r--r--src/QuickMedia.cpp30
-rw-r--r--src/plugins/MediaGeneric.cpp56
2 files changed, 74 insertions, 12 deletions
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<MediaRelatedItem> 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<CommandArg> extra_commands = {
{ "--header", "Cookie: last_views=%5B%2236247565-" + std::to_string(time(nullptr)) + "%22%5D" }
};
auto search_page = std::make_unique<MediaGenericSearchPage>(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<MediaGenericSearchPage>(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<void>([&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<MediaTextQuery> &text_queries, const std::vector<MediaThumbnailQuery> &thumbnail_queries, mgl::vec2i thumbnail_max_size, MediaRelatedCustomHandler *custom_handler, BodyItems &result_items, bool cloudflare_bypass, const std::vector<CommandArg> &extra_commands) {
+ static PluginResult fetch_page_results(
+ const std::string &url, const std::string &website_url, const std::vector<MediaTextQuery> &text_queries,
+ const std::vector<MediaThumbnailQuery> &thumbnail_queries, mgl::vec2i thumbnail_max_size,
+ MediaRelatedCustomHandler *related_custom_handler,
+ BodyItems &result_items, bool cloudflare_bypass, const std::vector<CommandArg> &extra_commands)
+ {
std::vector<CommandArg> 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<MediaRelatedItem> media_related_items = (*custom_handler)(website_data);
+ if(related_custom_handler && *related_custom_handler) {
+ std::vector<MediaRelatedItem> 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<MediaTextQuery> 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<MediaGenericRelatedPage>(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<MediaChapter>&, std::string &err_msg) {
+ video_url.clear();
+ if(!search_page->video_custom_handler) {
+ video_url = url;
+ return PluginResult::OK;
+ }
+
+ std::vector<CommandArg> 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