blob: f09f9bfa5b93f08bfdb2e5dfc7ef219b2e7039c4 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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;
};
}
|