Downloader.hpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #pragma once
  2. #include "Path.hpp"
  3. #include "AsyncTask.hpp"
  4. #include <string>
  5. namespace QuickMedia {
  6. enum class DownloadUpdateStatus {
  7. DOWNLOADING,
  8. FINISHED,
  9. ERROR
  10. };
  11. class Downloader {
  12. public:
  13. Downloader(const std::string &url, const std::string &output_filepath) : url(url), output_filepath(output_filepath) {}
  14. virtual ~Downloader() = default;
  15. virtual bool start() = 0;
  16. virtual bool stop(bool download_completed) = 0;
  17. virtual DownloadUpdateStatus update() = 0;
  18. virtual float get_progress() = 0;
  19. virtual std::string get_progress_text() = 0;
  20. virtual std::string get_download_speed_text() = 0;
  21. const std::string& get_output_filepath() { return output_filepath; }
  22. protected:
  23. std::string url;
  24. std::string output_filepath;
  25. };
  26. class CurlDownloader : public Downloader {
  27. public:
  28. CurlDownloader(const std::string &url, const std::string &output_filepath, int64_t content_length = -1);
  29. bool start() override;
  30. bool stop(bool download_completed) override;
  31. DownloadUpdateStatus update() override;
  32. float get_progress() override;
  33. std::string get_progress_text() override;
  34. std::string get_download_speed_text() override;
  35. private:
  36. Path output_filepath_tmp;
  37. ReadProgram read_program;
  38. AsyncTask<bool> header_reader;
  39. std::string header;
  40. int64_t content_length = -1;
  41. int64_t downloaded_since_last_check = 0;
  42. float progress = 0.0f;
  43. std::mutex content_length_mutex;
  44. std::string progress_text;
  45. std::string download_speed_text;
  46. bool finished = false;
  47. };
  48. class YoutubeDlDownloader : public Downloader {
  49. public:
  50. YoutubeDlDownloader(const char *yt_dl_name, const std::string &url, const std::string &output_filepath, bool no_video);
  51. bool start() override;
  52. bool stop(bool download_completed) override;
  53. DownloadUpdateStatus update() override;
  54. float get_progress() override;
  55. std::string get_progress_text() override;
  56. std::string get_download_speed_text() override;
  57. private:
  58. ReadProgram read_program;
  59. FILE *read_program_file = nullptr;
  60. AsyncTask<bool> youtube_dl_output_reader;
  61. std::mutex progress_update_mutex;
  62. float progress = 0.0f;
  63. std::string progress_text;
  64. std::string download_speed_text;
  65. bool no_video;
  66. bool finished = false;
  67. const char *yt_dl_name;
  68. };
  69. struct MediaMetadata {
  70. std::string url;
  71. int64_t content_length;
  72. };
  73. struct YoutubeReadProgram {
  74. ReadProgram read_program;
  75. int64_t offset = 0;
  76. int64_t content_length = -1;
  77. int64_t bytes_downloaded = 0;
  78. int64_t downloaded_since_last_check = 0;
  79. char *url = nullptr;
  80. std::string output_filepath;
  81. std::string output_filepath_tmp;
  82. double progress = 0.0;
  83. std::string progress_text;
  84. std::string download_speed_text;
  85. bool finished = false;
  86. };
  87. class YoutubeDownloader : public Downloader {
  88. public:
  89. YoutubeDownloader(const MediaMetadata &video_metadata, const MediaMetadata &audio_metadata, const std::string &output_filepath);
  90. ~YoutubeDownloader();
  91. bool start() override;
  92. bool stop(bool download_completed) override;
  93. DownloadUpdateStatus update() override;
  94. float get_progress() override;
  95. std::string get_progress_text() override;
  96. std::string get_download_speed_text() override;
  97. private:
  98. YoutubeReadProgram* get_min_progress_downloader();
  99. DownloadUpdateStatus update(size_t program_index);
  100. private:
  101. MediaMetadata video_metadata;
  102. MediaMetadata audio_metadata;
  103. std::string video_output_filepath;
  104. std::string audio_output_filepath;
  105. YoutubeReadProgram *program[2];
  106. AsyncTask<bool> downloader_tasks[2];
  107. };
  108. }