blob_dl/assembling/youtube/
config.rs1use crate::assembling::youtube;
2use crate::analyzer;
3use std::process;
4
5#[derive(Debug, Clone)]
7pub struct DownloadConfig {
8 url: String,
9
10 output_path: String,
11 include_indexes: bool,
13 chosen_format: youtube::VideoQualityAndFormatPreferences,
15 media_selected: youtube::MediaSelection,
17 pub download_target: analyzer::DownloadOption,
19}
20
21impl DownloadConfig {
22 pub(crate) fn new_playlist (
23 url: &str,
24 output_path: String,
25 include_indexes: bool,
26 chosen_format: youtube::VideoQualityAndFormatPreferences,
27 media_selected: youtube::MediaSelection,
28 )
29 -> DownloadConfig
30 {
31 DownloadConfig { url: url.to_string(), output_path, include_indexes, chosen_format, media_selected,
32 download_target: analyzer::DownloadOption::YtPlaylist }
33 }
34
35 pub(crate) fn new_video (
36 url: &str,
37 chosen_format: youtube::VideoQualityAndFormatPreferences,
38 output_path: String,
39 media_selected: youtube::MediaSelection,
40 )
41 -> DownloadConfig
42 {
43 DownloadConfig { url: url.to_string(), chosen_format, output_path, media_selected,
44 include_indexes: false, download_target: analyzer::DownloadOption::YtVideo(0) }
45 }
46}
47
48impl DownloadConfig {
50 pub(crate) fn build_command(&self) -> (process::Command, DownloadConfig) {
54 (
55 match self.download_target {
56 analyzer::DownloadOption::YtVideo(_) => self.build_yt_video_command(),
57 analyzer::DownloadOption::YtPlaylist => self.build_yt_playlist_command(),
58 },
59
60 self.clone()
61 )
62 }
63
64 fn build_yt_playlist_command(&self) -> process::Command {
65 let mut command = process::Command::new("yt-dlp");
66
67 command.arg("-i");
69
70 command.arg("--yes-playlist");
72
73 self.choose_output_path(&mut command);
75
76 let id = match &self.chosen_format {
79 youtube::VideoQualityAndFormatPreferences::UniqueFormat(id) => id.to_string(),
80 _ => String::new(),
81 };
82
83 self.choose_format(&mut command, id.as_str());
85
86 command.arg(self.url.clone());
88
89 command
90 }
91
92 fn build_yt_video_command(&self) -> process::Command {
93 let mut command = process::Command::new("yt-dlp");
94
95 self.choose_output_path(&mut command);
96
97 let id = match &self.chosen_format {
100 youtube::VideoQualityAndFormatPreferences::UniqueFormat(id) => id.to_string(),
101 _ => String::new(),
102 };
103
104 self.choose_format(&mut command, &id);
105
106 command.arg("--no-playlist");
107
108 command.arg(self.url.clone());
109
110 command
111 }
112
113 pub fn build_command_for_video(&self, video_id: &str) -> process::Command {
117 let mut command = process::Command::new("yt-dlp");
118
119 self.choose_output_path(&mut command);
120
121 let id = match &self.chosen_format {
124 youtube::VideoQualityAndFormatPreferences::UniqueFormat(id) => id.to_string(),
125 _ => String::new(),
126 };
127
128 self.choose_format(&mut command, id.as_str());
129
130 command.arg("--no-playlist");
131
132 command.arg(video_id);
133
134 command
135 }
136
137 fn choose_output_path(&self, command: &mut process::Command) {
138 command.arg("-o");
139 command.arg(
140 {
141 let mut path_and_scheme = String::new();
142 path_and_scheme.push_str(self.output_path.as_str());
144
145 if self.download_target == analyzer::DownloadOption::YtPlaylist {
146 #[cfg(target_os = "windows")]
148 path_and_scheme.push_str("\\%(playlist)s\\");
149
150 #[cfg(not(target_os = "windows"))]
151 path_and_scheme.push_str("/%(playlist)s/");
152
153 if self.include_indexes {
154 path_and_scheme.push_str("%(playlist_index)s_");
155 };
156 path_and_scheme.push_str("%(title)s");
157 } else {
158 #[cfg(target_os = "windows")]
160 path_and_scheme.push_str("\\%(title)s.%(ext)s");
161
162 #[cfg(not(target_os = "windows"))]
163 path_and_scheme.push_str("/%(title)s.%(ext)s");
164 }
165
166 path_and_scheme
167 }
168 );
169 }
170
171 fn choose_format(&self, command: &mut process::Command, format_id: &str) {
172 match self.media_selected {
173 youtube::MediaSelection::FullVideo => {
174 match &self.chosen_format {
175 youtube::VideoQualityAndFormatPreferences::BestQuality => {}
176
177 youtube::VideoQualityAndFormatPreferences::SmallestSize => {
178 command.arg("-S").arg("+size,+br");
179 }
180
181 youtube::VideoQualityAndFormatPreferences::UniqueFormat(_) => {
182 command.arg("-f").arg(format_id);
183 }
184 youtube::VideoQualityAndFormatPreferences::ConvertTo(f) => {
185 command.arg("--recode-video").arg(f.as_str());
186 }
187 }
188 }
189
190 youtube::MediaSelection::AudioOnly => {
191 match &self.chosen_format {
192 youtube::VideoQualityAndFormatPreferences::BestQuality => {
193 command.arg("-f").arg("bestaudio");
194 }
195
196 youtube::VideoQualityAndFormatPreferences::SmallestSize => {
197 command.arg("-f").arg("worstaudio");
198 }
199
200 youtube::VideoQualityAndFormatPreferences::UniqueFormat(_) => {
201 command.arg("-f").arg(format_id);
202 }
203 youtube::VideoQualityAndFormatPreferences::ConvertTo(f) => {
204 command.arg("-x").arg("--audio-format").arg(f.as_str());
205 }
206 }
207 }
208
209 youtube::MediaSelection::VideoOnly => {
210 match &self.chosen_format {
211 youtube::VideoQualityAndFormatPreferences::BestQuality => {
212 command.arg("-f").arg("bestvideo");
213 }
214
215 youtube::VideoQualityAndFormatPreferences::SmallestSize => {
216 command.arg("-f").arg("worstvideo");
217 }
218
219 youtube::VideoQualityAndFormatPreferences::UniqueFormat(_) => {
220 command.arg("-f").arg(format_id);
221 }
222 youtube::VideoQualityAndFormatPreferences::ConvertTo(f) => {
223 command.arg("--recode-video").arg(f.as_str());
224 }
225 }
226 }
227 };
228 }
229}