diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/QuickMedia.cpp | 14 | ||||
-rw-r--r-- | src/Storage.cpp | 10 | ||||
-rw-r--r-- | src/VideoPlayer.cpp | 18 | ||||
-rw-r--r-- | src/plugins/Youtube.cpp | 110 |
4 files changed, 66 insertions, 86 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index ed94700..42e018d 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -383,7 +383,7 @@ namespace QuickMedia { // continue; auto body_item = std::make_unique<BodyItem>(std::move(title_str)); - body_item->url = "https://youtube.com/watch?v=" + video_id_str; + body_item->url = "https://www.youtube.com/watch?v=" + video_id_str; body_item->thumbnail_url = "https://img.youtube.com/vi/" + video_id_str + "/hqdefault.jpg"; body_items.push_back(std::move(body_item)); } @@ -485,10 +485,10 @@ namespace QuickMedia { sf::Text history_tab_text("History", font, tab_text_size); sf::Text recommended_tab_text("Recommended", font, tab_text_size); - if(current_plugin->name == "youtube") { - recommended_body = std::make_unique<Body>(this, font, bold_font); - recommended_body->draw_thumbnails = true; - } + //if(current_plugin->name == "youtube") { + // recommended_body = std::make_unique<Body>(this, font, bold_font); + // recommended_body->draw_thumbnails = true; + //} struct Tab { Body *body; @@ -883,7 +883,7 @@ namespace QuickMedia { auto load_video_error_check = [this, &video_player, previous_page]() mutable { watched_videos.insert(content_url); - VideoPlayer::Error err = video_player->load_video(content_url.c_str(), window.getSystemHandle()); + VideoPlayer::Error err = video_player->load_video(content_url.c_str(), window.getSystemHandle(), current_plugin->name); if(err != VideoPlayer::Error::OK) { std::string err_msg = "Failed to play url: "; err_msg += content_url; @@ -1019,7 +1019,7 @@ namespace QuickMedia { video_player = std::make_unique<VideoPlayer>(current_plugin->use_tor, use_system_mpv_config, video_event_callback, on_window_create); std::string new_video_url = "https://www.invidio.us/latest_version?id=" + youtube_video_id + "&itag=22"; - VideoPlayer::Error err = video_player->load_video(new_video_url.c_str(), window.getSystemHandle()); + VideoPlayer::Error err = video_player->load_video(new_video_url.c_str(), window.getSystemHandle(), current_plugin->name); if(err != VideoPlayer::Error::OK) { std::string err_msg = "Failed to play url: "; err_msg += content_url; diff --git a/src/Storage.cpp b/src/Storage.cpp index 7d2b9ca..588b085 100644 --- a/src/Storage.cpp +++ b/src/Storage.cpp @@ -56,6 +56,16 @@ namespace QuickMedia { return get_home_dir().join(".cache").join("quickmedia"); } + int get_cookies_filepath(Path &path, const std::string &plugin_name) { + Path cookies_dir = get_storage_dir().join("cookies"); + int res = create_directory_recursive(cookies_dir); + if(res != 0) + return res; + path = cookies_dir; + path.join(plugin_name).append(".txt"); + return 0; + } + int create_directory_recursive(const Path &path) { size_t index = 0; while(true) { diff --git a/src/VideoPlayer.cpp b/src/VideoPlayer.cpp index c30f147..48b7f52 100644 --- a/src/VideoPlayer.cpp +++ b/src/VideoPlayer.cpp @@ -1,5 +1,6 @@ #include "../include/VideoPlayer.hpp" #include "../include/Program.h" +#include "../include/Storage.hpp" #include <string> #include <json/reader.h> #include <json/writer.h> @@ -56,7 +57,7 @@ namespace QuickMedia { XCloseDisplay(display); } - VideoPlayer::Error VideoPlayer::launch_video_process(const char *path, sf::WindowHandle _parent_window) { + VideoPlayer::Error VideoPlayer::launch_video_process(const char *path, sf::WindowHandle _parent_window, const std::string &plugin_name) { parent_window = _parent_window; if(!tmpnam(ipc_server_path)) { @@ -90,6 +91,17 @@ namespace QuickMedia { }); } + std::string cookies_file_arg; + if(!plugin_name.empty()) { + Path cookies_filepath; + if(get_cookies_filepath(cookies_filepath, plugin_name) != 0) { + fprintf(stderr, "Warning: Failed to create %s cookies file\n", plugin_name.c_str()); + } else { + cookies_file_arg = "--cookies-file=" + cookies_filepath.data; + args.insert(args.end(), { "--cookies", cookies_file_arg.c_str() }); + } + } + args.insert(args.end(), { "--", path, nullptr }); if(exec_program_async(args.data(), &video_process_id) != 0) @@ -111,12 +123,12 @@ namespace QuickMedia { return Error::OK; } - VideoPlayer::Error VideoPlayer::load_video(const char *path, sf::WindowHandle _parent_window) { + VideoPlayer::Error VideoPlayer::load_video(const char *path, sf::WindowHandle _parent_window, const std::string &plugin_name) { // This check is to make sure we dont change window that the video belongs to. This is not a usecase we will have so // no need to support it for now at least. assert(parent_window == 0 || parent_window == _parent_window); if(video_process_id == -1) - return launch_video_process(path, _parent_window); + return launch_video_process(path, _parent_window, plugin_name); Json::Value command_data(Json::arrayValue); command_data.append("loadfile"); diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp index 95ee8e3..b68e513 100644 --- a/src/plugins/Youtube.cpp +++ b/src/plugins/Youtube.cpp @@ -2,20 +2,9 @@ #include "../../include/Storage.hpp" #include <json/reader.h> #include <json/writer.h> -#include <uuid.h> #include <string.h> namespace QuickMedia { - const int VISITOR_ID_SIZE = 12; - const char visitor_id_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQSTUVWXYZ0123456789-_"; - static void generate_visitor_id(char visitor_id[VISITOR_ID_SIZE]) { - uuid_t uuid_num; - uuid_generate_random(uuid_num); - for(int i = 0; i < VISITOR_ID_SIZE; ++i) { - visitor_id[i] = visitor_id_chars[uuid_num[i] % (sizeof(visitor_id_chars) - 1)]; - } - } - static void iterate_suggestion_result(const Json::Value &value, std::vector<std::string> &result_items, int &iterate_count) { ++iterate_count; if(value.isArray()) { @@ -27,23 +16,6 @@ namespace QuickMedia { } } - static bool json_read_cookies(const Json::Value &json_cookies, std::string &visitor_info_live, std::string &ysc) { - if(!json_cookies.isObject()) - return false; - - const Json::Value &visitor_info_live_json = json_cookies["visitor_info_live"]; - if(!visitor_info_live_json.isString()) - return false; - - const Json::Value &ysc_json = json_cookies["ysc"]; - if(!ysc_json.isString()) - return false; - - visitor_info_live = visitor_info_live_json.asString(); - ysc = ysc_json.asString(); - return true; - } - static std::unique_ptr<BodyItem> parse_content_video_renderer(const Json::Value &content_item_json) { if(!content_item_json.isObject()) return nullptr; @@ -83,42 +55,14 @@ namespace QuickMedia { } Youtube::Youtube() : Plugin("youtube") { - Path youtube_config_dir = get_storage_dir().join("youtube"); - if(create_directory_recursive(youtube_config_dir) == 0) { - Path cookie_path = youtube_config_dir; - cookie_path.join("cookies.json"); - - bool cookies_read_from_file = false; - std::string cookie_file_content; - if(file_get_content(cookie_path, cookie_file_content) == 0) { - Json::Value json_root; - Json::CharReaderBuilder json_builder; - std::unique_ptr<Json::CharReader> json_reader(json_builder.newCharReader()); - std::string json_errors; - if(json_reader->parse(&cookie_file_content[0], &cookie_file_content[cookie_file_content.size()], &json_root, &json_errors) && json_read_cookies(json_root, visitor_info_live, ysc)) { - cookies_read_from_file = true; - } else { - fprintf(stderr, "Youtube failed to read cookies: %s\n", json_errors.c_str()); - } - } - - if(!cookies_read_from_file) { - visitor_info_live.resize(VISITOR_ID_SIZE); - ysc.resize(VISITOR_ID_SIZE); - generate_visitor_id(&visitor_info_live[0]); - generate_visitor_id(&ysc[0]); - - Json::Value json_cookies(Json::objectValue); - json_cookies["visitor_info_live"] = visitor_info_live; - json_cookies["ysc"] = ysc; - - Json::StreamWriterBuilder json_builder; - file_overwrite(cookie_path, Json::writeString(json_builder, json_cookies)); - } - } + } PluginResult Youtube::get_front_page(BodyItems &result_items) { + bool disabled = true; + if(disabled) + return PluginResult::OK; + std::string url = "https://youtube.com/"; std::vector<CommandArg> additional_args = { @@ -128,9 +72,8 @@ namespace QuickMedia { { "-H", "referer: " + url } }; - std::optional<CommandArg> cookies = get_cookies(); - if(cookies) - additional_args.push_back(cookies.value()); + std::vector<CommandArg> cookies = get_cookies(); + additional_args.insert(additional_args.end(), cookies.begin(), cookies.end()); std::string website_data; if(download_to_string(url + "?pbj=1", website_data, additional_args, use_tor, true) != DownloadResult::OK) @@ -325,9 +268,8 @@ namespace QuickMedia { { "-H", "referer: " + url } }; - std::optional<CommandArg> cookies = get_cookies(); - if(cookies) - additional_args.push_back(cookies.value()); + std::vector<CommandArg> cookies = get_cookies(); + additional_args.insert(additional_args.end(), cookies.begin(), cookies.end()); std::string website_data; if(download_to_string(url + "&pbj=1", website_data, additional_args, use_tor, true) != DownloadResult::OK) @@ -405,9 +347,8 @@ namespace QuickMedia { { "-H", "referer: " + url } }; - std::optional<CommandArg> cookies = get_cookies(); - if(cookies) - additional_args.push_back(cookies.value()); + std::vector<CommandArg> cookies = get_cookies(); + additional_args.insert(additional_args.end(), cookies.begin(), cookies.end()); std::string website_data; if(download_to_string(next_url, website_data, additional_args, use_tor, true) != DownloadResult::OK) @@ -448,10 +389,17 @@ namespace QuickMedia { } } - std::optional<CommandArg> Youtube::get_cookies() const { - if(!visitor_info_live.empty() && !ysc.empty()) - return CommandArg { "-H", "cookie: VISITOR_INFO1_LIVE=" + visitor_info_live + "; YSC=" + ysc + "; wide=1; PREF=; GPS=0" }; - return std::nullopt; + std::vector<CommandArg> Youtube::get_cookies() const { + Path cookies_filepath; + if(get_cookies_filepath(cookies_filepath, name) != 0) { + fprintf(stderr, "Warning: Failed to create youtube cookies file\n"); + return {}; + } + + return { + CommandArg{ "-b", cookies_filepath.data }, + CommandArg{ "-c", cookies_filepath.data } + }; } static std::string remove_index_from_playlist_url(const std::string &url) { @@ -498,9 +446,19 @@ namespace QuickMedia { BodyItems result_items; std::string modified_url = remove_index_from_playlist_url(url); + std::vector<CommandArg> additional_args = { + { "-H", "x-spf-referer: " + url }, + { "-H", "x-youtube-client-name: 1" }, + { "-H", "x-spf-previous: " + url }, + { "-H", "x-youtube-client-version: 2.20200626.03.00" }, + { "-H", "referer: " + url } + }; + + std::vector<CommandArg> cookies = get_cookies(); + additional_args.insert(additional_args.end(), cookies.begin(), cookies.end()); std::string website_data; - if(download_to_string(modified_url, website_data, {}, use_tor, true) != DownloadResult::OK) + if(download_to_string(modified_url, website_data, additional_args, use_tor, true) != DownloadResult::OK) return result_items; size_t data_start = website_data.find("window[\"ytInitialData\"] = {"); @@ -518,7 +476,7 @@ namespace QuickMedia { std::unique_ptr<Json::CharReader> json_reader(json_builder.newCharReader()); std::string json_errors; if(!json_reader->parse(&website_data[data_start], &website_data[data_end], &json_root, &json_errors)) { - fprintf(stderr, "Youtube search json error: %s\n", json_errors.c_str()); + fprintf(stderr, "Youtube related media error: %s\n", json_errors.c_str()); return result_items; } |