aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-07-17 09:43:20 +0200
committerdec05eba <dec05eba@protonmail.com>2021-07-17 09:43:20 +0200
commite671784144174c4fceaa6df3737ba9b4de4a6c63 (patch)
treea3ad7d12959b92f5be9430c961d86a9c131d7036 /include
parentb09d1e70661226697e2441c18ea6ff59c387fb93 (diff)
Youtube: remove dependency on youtube-dl for downloads (also fixes downloads of age restricted videos)
Diffstat (limited to 'include')
-rw-r--r--include/DownloadUtils.hpp2
-rw-r--r--include/Downloader.hpp104
-rw-r--r--include/QuickMedia.hpp4
3 files changed, 107 insertions, 3 deletions
diff --git a/include/DownloadUtils.hpp b/include/DownloadUtils.hpp
index dbac921..398f82c 100644
--- a/include/DownloadUtils.hpp
+++ b/include/DownloadUtils.hpp
@@ -32,6 +32,6 @@ namespace QuickMedia {
// Note: if |cloudflare_bypass| is set to true then tls is limited to version 1.1 and the user agent is changed.
DownloadResult download_to_file(const std::string &url, const std::string &destination_filepath, const std::vector<CommandArg> &additional_args, bool use_browser_useragent = false, bool cloudflare_bypass = false);
// Returns false if there was an error trying to create the download process
- bool download_async_gui(const std::string &url, const std::string &file_manager_start_dir, bool use_youtube_dl, bool no_video);
+ bool download_async_gui(const std::string &url, const std::string &file_manager_start_dir, bool no_video);
DownloadResult download_to_json(const std::string &url, rapidjson::Document &result, const std::vector<CommandArg> &additional_args, bool use_browser_useragent = false, bool fail_on_error = true);
} \ No newline at end of file
diff --git a/include/Downloader.hpp b/include/Downloader.hpp
new file mode 100644
index 0000000..f09f9bf
--- /dev/null
+++ b/include/Downloader.hpp
@@ -0,0 +1,104 @@
+#pragma once
+
+#include "Path.hpp"
+#include "AsyncTask.hpp"
+#include "../plugins/youtube/YoutubeMediaProxy.hpp"
+#include <string>
+
+namespace QuickMedia {
+ enum class DownloadUpdateStatus {
+ DOWNLOADING,
+ FINISHED,
+ ERROR
+ };
+
+ class Downloader {
+ public:
+ Downloader(const std::string &url, const std::string &output_filepath) : url(url), output_filepath(output_filepath) {}
+ virtual ~Downloader() = default;
+
+ virtual bool start() = 0;
+ virtual bool stop(bool download_completed) = 0;
+ virtual DownloadUpdateStatus update() = 0;
+
+ virtual float get_progress() = 0;
+ virtual std::string get_progress_text() = 0;
+ virtual std::string get_download_speed_text() = 0;
+
+ const std::string& get_output_filepath() { return output_filepath; }
+ protected:
+ std::string url;
+ std::string output_filepath;
+ };
+
+ class CurlDownloader : public Downloader {
+ public:
+ CurlDownloader(const std::string &url, const std::string &output_filepath, int64_t content_length = -1);
+ bool start() override;
+ bool stop(bool download_completed) override;
+ DownloadUpdateStatus update() override;
+ float get_progress() override;
+ std::string get_progress_text() override;
+ std::string get_download_speed_text() override;
+ private:
+ Path output_filepath_tmp;
+ ReadProgram read_program;
+ AsyncTask<bool> header_reader;
+ std::string header;
+ int64_t content_length = -1;
+ size_t downloaded_since_last_check = 0;
+ float progress = 0.0f;
+ std::mutex content_length_mutex;
+ std::string progress_text;
+ std::string download_speed_text;
+ bool finished = false;
+ };
+
+ class YoutubeDlDownloader : public Downloader {
+ public:
+ YoutubeDlDownloader(const std::string &url, const std::string &output_filepath, bool no_video);
+ bool start() override;
+ bool stop(bool download_completed) override;
+ DownloadUpdateStatus update() override;
+ float get_progress() override;
+ std::string get_progress_text() override;
+ std::string get_download_speed_text() override;
+ private:
+ ReadProgram read_program;
+ FILE *read_program_file = nullptr;
+ AsyncTask<bool> youtube_dl_output_reader;
+ std::mutex progress_update_mutex;
+ float progress = 0.0f;
+ std::string progress_text;
+ std::string download_speed_text;
+ bool no_video;
+ bool finished = false;
+ };
+
+ struct MediaMetadata {
+ std::string url;
+ int64_t content_length;
+ };
+
+ class YoutubeDownloader : public Downloader {
+ public:
+ YoutubeDownloader(const MediaMetadata &video_metadata, const MediaMetadata &audio_metadata, const std::string &output_filepath);
+ bool start() override;
+ bool stop(bool download_completed) override;
+ DownloadUpdateStatus update() override;
+ float get_progress() override;
+ std::string get_progress_text() override;
+ std::string get_download_speed_text() override;
+ private:
+ CurlDownloader* get_min_progress_downloader();
+ private:
+ MediaMetadata video_metadata;
+ MediaMetadata audio_metadata;
+ std::string video_output_filepath;
+ std::string audio_output_filepath;
+ std::unique_ptr<CurlDownloader> downloaders[2];
+ AsyncTask<void> downloader_task;
+ std::unique_ptr<YoutubeMediaProxy> youtube_video_media_proxy;
+ std::unique_ptr<YoutubeMediaProxy> youtube_audio_media_proxy;
+ };
+} \ No newline at end of file
diff --git a/include/QuickMedia.hpp b/include/QuickMedia.hpp
index cc4a10f..765a346 100644
--- a/include/QuickMedia.hpp
+++ b/include/QuickMedia.hpp
@@ -113,7 +113,7 @@ namespace QuickMedia {
using PageLoopSubmitHandler = std::function<void(const std::vector<Tab> &new_tabs)>;
// Returns false if the page loop was escaped by user navigation (pressing escape) or if there was an error at startup
bool page_loop(std::vector<Tab> &tabs, int start_tab_index = 0, PageLoopSubmitHandler after_submit_handler = nullptr);
- void video_page_download_video(const std::string &url, bool use_youtube_dl, sf::WindowHandle video_player_window = None);
+ void video_page_download_video(const std::string &url, sf::WindowHandle video_player_window = None);
bool video_download_if_non_streamable(std::string &video_url, std::string &audio_url, bool &is_audio_only, bool &has_embedded_audio, PageType previous_page);
void video_content_page(Page *parent_page, VideoPage *video_page, std::string video_title, bool download_if_streaming_fails, Body *parent_body, BodyItems &next_play_items, int play_index, int *parent_body_page = nullptr, const std::string &parent_page_search = "");
// Returns -1 to go to previous chapter, 0 to stay on same chapter and 1 to go to next chapter
@@ -123,7 +123,7 @@ namespace QuickMedia {
void chat_login_page();
bool chat_page(MatrixChatPage *matrix_chat_page, RoomData *current_room);
void after_matrix_login_page();
- void download_page(const char *url, bool download_use_youtube_dl);
+ void download_page(const std::string &url);
// Returns the full path where the file should be saved, or an empty string if the operation was cancelled
std::string file_save_page(const std::string &filename);