aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Youtube.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-06-19 13:51:37 +0200
committerdec05eba <dec05eba@protonmail.com>2021-06-19 13:51:37 +0200
commit5ec1811fa7499386f324f13a3a49dbe7d8ea6741 (patch)
tree835c8b853cc9a6f96aa962070d685e2e3e2f110d /src/plugins/Youtube.cpp
parent85c6c916541968f298badb391b718cdf6d81d332 (diff)
Fix youtube sometimes needing a redirect for media url
Diffstat (limited to 'src/plugins/Youtube.cpp')
-rw-r--r--src/plugins/Youtube.cpp30
1 files changed, 28 insertions, 2 deletions
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp
index b45b5fe..717bc8f 100644
--- a/src/plugins/Youtube.cpp
+++ b/src/plugins/Youtube.cpp
@@ -1981,6 +1981,32 @@ R"END(
return nullptr;
}
+ // Sometimes youtube returns a redirect url (not in the header but in the body...).
+ // TODO: Find why this happens and if there is a way bypass it.
+ static std::string get_playback_url_recursive(std::string playback_url) {
+ const int max_redirects = 5;
+ for(int i = 0; i < max_redirects; ++i) {
+ std::string response_headers;
+ if(download_head_to_string(playback_url, response_headers, true) != DownloadResult::OK)
+ return "";
+
+ std::string content_type = header_extract_value(response_headers, "content-type");
+ if(content_type.empty())
+ return "";
+
+ if(string_starts_with(content_type, "video") || string_starts_with(content_type, "audio"))
+ return playback_url;
+
+ // TODO: Download head and body in one request
+ std::string new_url;
+ if(download_to_string(playback_url, new_url, {}, true) != DownloadResult::OK)
+ return "";
+
+ playback_url = std::move(new_url);
+ }
+ return playback_url;
+ }
+
std::string YoutubeVideoPage::get_video_url(int max_height, bool &has_embedded_audio) {
if(!hls_manifest_url.empty()) {
has_embedded_audio = true;
@@ -2007,7 +2033,7 @@ R"END(
print_chosen_format(*chosen_video_format);
has_embedded_audio = chosen_video_format->has_embedded_audio;
- return chosen_video_format->base.url;
+ return get_playback_url_recursive(chosen_video_format->base.url);
}
std::string YoutubeVideoPage::get_audio_url() {
@@ -2017,7 +2043,7 @@ R"END(
// TODO: The "worst" (but still good) quality audio is chosen right now because youtube seeking freezes for up to 15 seconds when choosing the best quality
const YoutubeAudioFormat *chosen_audio_format = &audio_formats.back();
fprintf(stderr, "Choosing youtube audio format: bitrate: %d, mime type: %s\n", chosen_audio_format->base.bitrate, chosen_audio_format->base.mime_type.c_str());
- return chosen_audio_format->base.url;
+ return get_playback_url_recursive(chosen_audio_format->base.url);
}
// Returns -1 if timestamp is in an invalid format