diff options
author | dec05eba <dec05eba@protonmail.com> | 2021-06-19 13:51:37 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2021-06-19 13:51:37 +0200 |
commit | 5ec1811fa7499386f324f13a3a49dbe7d8ea6741 (patch) | |
tree | 835c8b853cc9a6f96aa962070d685e2e3e2f110d /src/plugins | |
parent | 85c6c916541968f298badb391b718cdf6d81d332 (diff) |
Fix youtube sometimes needing a redirect for media url
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/Youtube.cpp | 30 |
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 |