aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2025-04-27 14:47:57 +0200
committerdec05eba <dec05eba@protonmail.com>2025-04-27 14:47:57 +0200
commit91db117734301a24e47ea784a677ec1b3df44465 (patch)
tree15806357a86aa9a397b206566a187d2c9497dfa8
parent69ac43bc5136c1e6638e367280cf4be85322fb1d (diff)
Fix unable to play youtube videos (require dependency on yt-dlp for now)HEADmaster
-rw-r--r--README.md5
-rw-r--r--TODO3
-rw-r--r--src/QuickMedia.cpp2
-rw-r--r--src/plugins/Youtube.cpp97
4 files changed, 82 insertions, 25 deletions
diff --git a/README.md b/README.md
index 1db226e..35b30d7 100644
--- a/README.md
+++ b/README.md
@@ -37,12 +37,13 @@ Meson needs to be installed to run the build script.
### Libraries
`libglvnd (LibGL.so)`, `libx11`, `libxrandr`, `libmpv`
### Executables
-`curl`
+`curl`.\
+`yt-dlp` needs to be installed right now to play youtube videos. This requirement will be removed in the future.
### Fonts
`noto-fonts` (when `use_system_fonts` config is not set to `true`)
### Optional
`noto-fonts-cjk` needs to be installed to view chinese, japanese and korean characters (when `use_system_fonts` config is not set to `true`).\
-`yt-dlp/youtube-dl` needs to be installed to download soundcloud music, fallback for youtube (for example for age restricted videos) or to play/download xxx videos.\
+`yt-dlp` needs to be installed to download soundcloud music or to play/download xxx videos.\
`notify-send` (which is part of `libnotify`) needs to be installed to show notifications (on Linux and other systems that uses d-bus notification system).\
[automedia](https://git.dec05eba.com/AutoMedia/) needs to be installed when tracking anime/manga with `Ctrl + T`.\
`waifu2x-ncnn-vulkan` needs to be installed when using the `--upscale-images` or `--upscale-images-always` option.\
diff --git a/TODO b/TODO
index 97d53c3..9515ea4 100644
--- a/TODO
+++ b/TODO
@@ -299,4 +299,5 @@ Use stb_image_resize2.h
Youtube audio only download if audio stream not available, also for youtube-dl fallback.
Make history (local-manga and others) use relative path to the downloads directory for thumbnails. Otherwise the thumbnails wont show when moving the download directory.
Keep the rooms that we were kicked/banned from so we can still read them and re-read the reason for why we were kicked/banned. Or add a list of historical rooms with leave reason.
-Fix youtube broken (always falls back to low quality yt-dlp). \ No newline at end of file
+Fix youtube broken without yt-dlp. Unable to download video.
+Use different font for chinese, japanese and korean (or maybe only for korean).
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 0671349..b09e09f 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -1095,6 +1095,8 @@ namespace QuickMedia {
if(!youtube_dl_name)
return false;
+ const int video_max_height = video_get_max_height();
+
std::string ytdl_format;
if(no_video)
ytdl_format = "(bestaudio/best)";
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp
index 2c20f3f..7095e6b 100644
--- a/src/plugins/Youtube.cpp
+++ b/src/plugins/Youtube.cpp
@@ -21,7 +21,7 @@ extern "C" {
#include <unistd.h>
namespace QuickMedia {
- static const char *youtube_client_version = "x-youtube-client-version: 2.20210622.10.00";
+ static const char *youtube_client_version = "x-youtube-client-version: 2.20250327.01.00";
static const std::array<std::string, 11> invidious_urls = {
"yewtu.be",
"invidious.snopyta.org",
@@ -3189,26 +3189,33 @@ namespace QuickMedia {
}
}
- const Json::Value &playability_status_json = json_root["playabilityStatus"];
- if(playability_status_json.isObject()) {
- const Json::Value &status_json = playability_status_json["status"];
- if(status_json.isString() && (strcmp(status_json.asCString(), "UNPLAYABLE") == 0 || strcmp(status_json.asCString(), "LOGIN_REQUIRED") == 0)) {
- fprintf(stderr, "Failed to load youtube video, trying with yt-dlp instead\n");
- if(program->youtube_dl_extract_url(url, youtube_dl_video_fallback_url, youtube_dl_audio_fallback_url)) {
- if(get_config().youtube.sponsorblock.enable)
- sponsorblock_add_chapters(this, url, get_config().youtube.sponsorblock.min_votes, sponsor_segments);
- use_youtube_dl_fallback = true;
- return PluginResult::OK;
- } else {
- const Json::Value &reason_json = playability_status_json["reason"];
- if(reason_json.isString())
- err_str = reason_json.asString();
- fprintf(stderr, "Unable to play video, status: %s, reason: %s\n", status_json.asCString(), reason_json.isString() ? reason_json.asCString() : "Unknown");
- return PluginResult::ERR;
- }
- }
+ if(program->youtube_dl_extract_url(url, youtube_dl_video_fallback_url, youtube_dl_audio_fallback_url)) {
+ if(get_config().youtube.sponsorblock.enable)
+ sponsorblock_add_chapters(this, url, get_config().youtube.sponsorblock.min_votes, sponsor_segments);
+ use_youtube_dl_fallback = true;
+ return PluginResult::OK;
}
+ // const Json::Value &playability_status_json = json_root["playabilityStatus"];
+ // if(playability_status_json.isObject()) {
+ // const Json::Value &status_json = playability_status_json["status"];
+ // if(status_json.isString() && (strcmp(status_json.asCString(), "UNPLAYABLE") == 0 || strcmp(status_json.asCString(), "LOGIN_REQUIRED") == 0)) {
+ // fprintf(stderr, "Failed to load youtube video, trying with yt-dlp instead\n");
+ // if(program->youtube_dl_extract_url(url, youtube_dl_video_fallback_url, youtube_dl_audio_fallback_url)) {
+ // if(get_config().youtube.sponsorblock.enable)
+ // sponsorblock_add_chapters(this, url, get_config().youtube.sponsorblock.min_votes, sponsor_segments);
+ // use_youtube_dl_fallback = true;
+ // return PluginResult::OK;
+ // } else {
+ // const Json::Value &reason_json = playability_status_json["reason"];
+ // if(reason_json.isString())
+ // err_str = reason_json.asString();
+ // fprintf(stderr, "Unable to play video, status: %s, reason: %s\n", status_json.asCString(), reason_json.isString() ? reason_json.asCString() : "Unknown");
+ // return PluginResult::ERR;
+ // }
+ // }
+ // }
+
const Json::Value *streaming_data_json = &json_root["streamingData"];
if(!streaming_data_json->isObject())
return PluginResult::ERR;
@@ -3254,7 +3261,51 @@ namespace QuickMedia {
const int num_request_types = 1;
std::string request_data[num_request_types] = {
R"END(
- {"context":{"client":{"hl":"en","gl":"US","clientName":"IOS","clientVersion":"17.33.2","deviceModel":"iPhone14,3"}},"videoId":"%VIDEO_ID%"}
+{
+ "context": {
+ "client": {
+ "hl": "en",
+ "gl": "SE",
+ "deviceMake": "",
+ "deviceModel": "",
+ "userAgent": "Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0,gzip(gfe)",
+ "clientName": "WEB",
+ "clientVersion": "2.20250327.01.00",
+ "osName": "X11",
+ "osVersion": "",
+ "originalUrl": "https://www.youtube.com/watch?v=%VIDEO_ID%",
+ "platform": "DESKTOP",
+ "clientFormFactor": "UNKNOWN_FORM_FACTOR",
+ "userInterfaceTheme": "USER_INTERFACE_THEME_DARK",
+ "timeZone": "Europe/Paris",
+ "browserName": "Firefox",
+ "browserVersion": "136.0",
+ "acceptHeader": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
+ "clientScreen": "WATCH",
+ "mainAppWebInfo": {
+ "graftUrl": "/watch?v=%VIDEO_ID%",
+ "pwaInstallabilityStatus": "PWA_INSTALLABILITY_STATUS_UNKNOWN",
+ "webDisplayMode": "WEB_DISPLAY_MODE_BROWSER",
+ "isWebNativeShareAvailable": false
+ }
+ }
+ },
+ "videoId": "%VIDEO_ID%",
+ "playbackContext": {
+ "contentPlaybackContext": {
+ "currentUrl": "/watch?v=%VIDEO_ID%",
+ "vis": 0,
+ "splay": false,
+ "autoCaptionsDefaultOn": false,
+ "autonavState": "STATE_OFF",
+ "html5Preference": "HTML5_PREF_WANTS",
+ "referer": "https://www.youtube.com/",
+ "lactMilliseconds": "-1"
+ }
+ },
+ "racyCheckOk": false,
+ "contentCheckOk": false
+}
)END",
};
@@ -3263,7 +3314,7 @@ R"END(
};
std::string client_versions[num_request_types] = {
- "2.20210622.10.00"
+ "2.20250327.01.00"
};
for(int i = 0; i < num_request_types; ++i) {
@@ -3280,7 +3331,7 @@ R"END(
additional_args.insert(additional_args.end(), cookies.begin(), cookies.end());
Json::Value json_root;
- DownloadResult download_result = download_json(json_root, "https://www.youtube.com/youtubei/v1/player?key=" + api_key + "&gl=US&hl=en&prettyPrint=false", additional_args, true);
+ DownloadResult download_result = download_json(json_root, "https://www.youtube.com/youtubei/v1/player?prettyPrint=false", additional_args, true);
if(download_result != DownloadResult::OK)
continue;
@@ -3423,6 +3474,7 @@ R"END(
continue;
}
+ //video_format.base.url += "&alr=yes";
video_formats.push_back(std::move(video_format));
} else if(strncmp(youtube_format_base.mime_type.c_str(), "audio/", 6) == 0) {
// Some youtube videos have multiple audio tracks and sometimes the audio tracks are in the same language
@@ -3445,6 +3497,7 @@ R"END(
continue;
}
+ //audio_format.base.url += "&alr=yes";
audio_formats.push_back(std::move(audio_format));
}
}