From 8fdf45fcdc0853f0630640234a0b2612fbb1f0a9 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 17 Jun 2021 01:33:37 +0200 Subject: Fix youtube video playing after youtube update --- src/plugins/Youtube.cpp | 79 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 15 deletions(-) (limited to 'src/plugins/Youtube.cpp') diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp index f113e0c..7e71830 100644 --- a/src/plugins/Youtube.cpp +++ b/src/plugins/Youtube.cpp @@ -374,7 +374,7 @@ namespace QuickMedia { return (c >= 8 && c <= 13) || c == ' '; } - // TODO: Cache this and redownload it when a network request fails with this api key? + // TODO: Cache this and redownload it when a network request fails with this api key? Do that in the same place as the signature, which means it would be done asynchronously static std::string youtube_page_find_api_key() { size_t api_key_index; size_t api_key_index_end; @@ -1911,21 +1911,70 @@ namespace QuickMedia { std::vector cookies = get_cookies(); additional_args.insert(additional_args.end(), cookies.begin(), cookies.end()); - std::string response; - DownloadResult download_result = download_to_string("https://www.youtube.com/get_video_info?html5=1&video_id=" + video_id + "&eurl=https://www.youtube.googleapis.com/v/" + video_id, response, std::move(additional_args), true); - if(download_result != DownloadResult::OK) return download_result_to_plugin_result(download_result); - - std::string player_response_param = url_extract_param(response, "player_response"); - player_response_param = url_param_decode(player_response_param); - Json::Value json_root; - Json::CharReaderBuilder json_builder; - std::unique_ptr json_reader(json_builder.newCharReader()); - std::string json_errors; - if(!json_reader->parse(player_response_param.data(), player_response_param.data() + player_response_param.size(), &json_root, &json_errors)) { - fprintf(stderr, "Failed to read param as json, error: %s\n", json_errors.c_str()); - return PluginResult::ERR; - } + std::string request_data = +R"END( +{ + "context": { + "client": { + "hl": "en", + "gl": "US", + "deviceMake": "", + "deviceModel": "", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0,gzip(gfe)", + "clientName": "WEB", + "clientVersion": "2.20210615.01.00", + "osName": "Windows", + "osVersion": "10.0", + "originalUrl": "https://www.youtube.com/watch?v=%VIDEO_ID%", + "platform": "DESKTOP", + "clientFormFactor": "UNKNOWN_FORM_FACTOR", + "timeZone": "UTC", + "browserName": "Firefox", + "browserVersion": "78.0", + "screenWidthPoints": 1054, + "screenHeightPoints": 289, + "screenPixelDensity": 1, + "screenDensityFloat": 1, + "utcOffsetMinutes": 0, + "userInterfaceTheme": "USER_INTERFACE_THEME_LIGHT", + "clientScreen": "WATCH", + "mainAppWebInfo": { + "graftUrl": "/watch?v=%VIDEO_ID%", + "webDisplayMode": "WEB_DISPLAY_MODE_BROWSER", + "isWebNativeShareAvailable": false + } + }, + "user": { + "lockedSafetyMode": false + }, + "request": { + "useSsl": true, + "internalExperimentFlags": [], + "consistencyTokenJars": [] + } + }, + "videoId": "%VIDEO_ID%", + "playbackContext": { + "contentPlaybackContext": { + "currentUrl": "/watch?v=%VIDEO_ID%", + "vis": 0, + "splay": false, + "autoCaptionsDefaultOn": false, + "autonavState": "STATE_NONE", + "html5Preference": "HTML5_PREF_WANTS" + } + }, + "racyCheckOk": false, + "contentCheckOk": false +} +)END"; + string_replace_all(request_data, "%VIDEO_ID%", video_id); + additional_args.push_back({ "-H", "Content-Type: application/json" }); + additional_args.push_back({ "--data-raw", std::move(request_data) }); + + DownloadResult download_result = download_json(json_root, "https://www.youtube.com/youtubei/v1/player?key=" + api_key, additional_args, true); + if(download_result != DownloadResult::OK) return download_result_to_plugin_result(download_result); if(!json_root.isObject()) return PluginResult::ERR; -- cgit v1.2.3