aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Youtube.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-08-08 14:56:46 +0200
committerdec05eba <dec05eba@protonmail.com>2021-08-08 14:56:46 +0200
commitc2efd1e6587223cf9fff302fbc0ef80fcb4340e2 (patch)
treea7c35ff0ac054de8617e4cdcbe9da423d72aa8a9 /src/plugins/Youtube.cpp
parent23ab8cc08d2d6281ef56c184f1e1e905e70a2a22 (diff)
Youtube: use innertube api for loading videos (and pretend to be android)
Diffstat (limited to 'src/plugins/Youtube.cpp')
-rw-r--r--src/plugins/Youtube.cpp112
1 files changed, 32 insertions, 80 deletions
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp
index f81d934..ea72f03 100644
--- a/src/plugins/Youtube.cpp
+++ b/src/plugins/Youtube.cpp
@@ -18,64 +18,7 @@ extern "C" {
#include <fcntl.h>
namespace QuickMedia {
- static const char *youtube_client_version = "x-youtube-client-version: 2.20210615.01.00";
- static const std::string key_api_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";
+ static const char *youtube_client_version = "x-youtube-client-version: 2.20210622.10.00";
bool youtube_url_extract_id(const std::string &youtube_url, std::string &youtube_video_id) {
size_t index = youtube_url.find("youtube.com/watch?v=");
@@ -1259,7 +1202,7 @@ R"END(
client_json["deviceModel"] = "";
client_json["userAgent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36";
client_json["clientName"] = "WEB";
- client_json["clientVersion"] = "2.20210701.07.00";
+ client_json["clientVersion"] = "2.20210622.10.00";
client_json["osName"] = "X11";
client_json["osVersion"] = "";
client_json["originalUrl"] = video_url;
@@ -1347,7 +1290,7 @@ R"END(
client_json["deviceModel"] = "";
client_json["userAgent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36";
client_json["clientName"] = "WEB";
- client_json["clientVersion"] = "2.20210304.08.01";
+ client_json["clientVersion"] = "2.20210622.10.00";
client_json["osName"] = "X11";
client_json["osVersion"] = "";
client_json["originalUrl"] = url + "/videos";
@@ -1436,7 +1379,7 @@ R"END(
client_json["deviceModel"] = "";
client_json["userAgent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36";
client_json["clientName"] = "WEB";
- client_json["clientVersion"] = "2.20210304.08.01";
+ client_json["clientVersion"] = "2.20210622.10.00";
client_json["osName"] = "X11";
client_json["osVersion"] = "";
client_json["originalUrl"] = url + "/videos";
@@ -2387,34 +2330,43 @@ R"END(
return PluginResult::ERR;
}
+ std::string request_data =
+R"END(
+{
+ "context": {
+ "client": {
+ "clientName": "ANDROID",
+ "clientVersion": "16.20",
+ "hl": "en"
+ }
+ },
+ "videoId": "%VIDEO_ID%",
+ "playbackContext": {
+ "contentPlaybackContext": {
+ "html5Preference": "HTML5_PREF_WANTS"
+ }
+ },
+ "contentCheckOk": true,
+ "racyCheckOk": true
+}
+)END";
+ string_replace_all(request_data, "%VIDEO_ID%", video_id);
+
std::vector<CommandArg> additional_args = {
- { "-H", "x-youtube-client-name: 1" },
- { "-H", youtube_client_version },
+ { "-H", "Content-Type: application/json" },
+ { "-H", "X-YouTube-Client-Name: 3" },
+ { "-H", "X-YouTube-Client-Version: 16.20" },
+ { "--data-raw", std::move(request_data) }
};
std::vector<CommandArg> cookies = get_cookies();
additional_args.insert(additional_args.end(), cookies.begin(), cookies.end());
- // TODO: Remove this code completely and replace with existing player? api
Json::Value json_root;
- DownloadResult download_result = download_json(json_root, "https://www.youtube.com/watch?v=" + video_id + "&pbj=1&gl=US&hl=en", additional_args, true);
+ DownloadResult download_result = download_json(json_root, "https://www.youtube.com/youtubei/v1/player?key=" + api_key + "&gl=US&hl=en", additional_args, true);
if(download_result != DownloadResult::OK) return download_result_to_plugin_result(download_result);
- if(!json_root.isArray())
- return PluginResult::ERR;
-
- for(const Json::Value &json_item : json_root) {
- if(!json_item.isObject())
- continue;
-
- const Json::Value &player_response_json = json_item["playerResponse"];
- if(!player_response_json.isObject())
- continue;
-
- return parse_video_response(player_response_json, title, channel_url, chapters);
- }
-
- return PluginResult::ERR;
+ return parse_video_response(json_root, title, channel_url, chapters);
}
void YoutubeVideoPage::mark_watched() {