diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 006bbfa..1c0723a 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -90,6 +90,16 @@ pub struct Archive { #[arg(long)] #[arg(value_parser = FFmpegPreset::parse)] pub(crate) ffmpeg_preset: Option, + #[arg( + help = "The number of threads used by ffmpeg to generate the output file. Does not work with every codec/preset" + )] + #[arg( + long_help = "The number of threads used by ffmpeg to generate the output file. \ + Does not work with every codec/preset and is skipped entirely when specifying custom ffmpeg output arguments instead of a preset for `--ffmpeg-preset`. \ + By default, ffmpeg chooses the thread count which works best for the output codec" + )] + #[arg(long)] + pub(crate) ffmpeg_threads: Option, #[arg( help = "Set which subtitle language should be set as default / auto shown when starting a video" @@ -182,6 +192,7 @@ impl Execute for Archive { let download_builder = DownloadBuilder::new() .default_subtitle(self.default_subtitle.clone()) .ffmpeg_preset(self.ffmpeg_preset.clone().unwrap_or_default()) + .ffmpeg_threads(self.ffmpeg_threads) .output_format(Some("matroska".to_string())) .audio_sort(Some(self.audio.clone())) .subtitle_sort(Some(self.subtitle.clone())) diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index cf1a049..a45354b 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -57,7 +57,7 @@ pub struct Download { pub(crate) output_specials: Option, #[arg(help = "Video resolution")] - #[arg(long_help = "The video resolution.\ + #[arg(long_help = "The video resolution. \ Can either be specified via the pixels (e.g. 1920x1080), the abbreviation for pixels (e.g. 1080p) or 'common-use' words (e.g. best). \ Specifying the exact pixels is not recommended, use one of the other options instead. \ Crunchyroll let you choose the quality with pixel abbreviation on their clients, so you might be already familiar with the available options. \ @@ -74,6 +74,16 @@ pub struct Download { #[arg(long)] #[arg(value_parser = FFmpegPreset::parse)] pub(crate) ffmpeg_preset: Option, + #[arg( + help = "The number of threads used by ffmpeg to generate the output file. Does not work with every codec/preset" + )] + #[arg( + long_help = "The number of threads used by ffmpeg to generate the output file. \ + Does not work with every codec/preset and is skipped entirely when specifying custom ffmpeg output arguments instead of a preset for `--ffmpeg-preset`. \ + By default, ffmpeg chooses the thread count which works best for the output codec" + )] + #[arg(long)] + pub(crate) ffmpeg_threads: Option, #[arg(help = "Skip files which are already existing")] #[arg(long, default_value_t = false)] @@ -203,6 +213,7 @@ impl Execute for Download { None }) .ffmpeg_preset(self.ffmpeg_preset.clone().unwrap_or_default()) + .ffmpeg_threads(self.ffmpeg_threads) .threads(self.threads); for mut single_formats in single_format_collection.into_iter() { diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index c154103..c715362 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -51,6 +51,7 @@ pub struct DownloadBuilder { subtitle_sort: Option>, force_hardsub: bool, threads: usize, + ffmpeg_threads: Option, } impl DownloadBuilder { @@ -63,6 +64,7 @@ impl DownloadBuilder { subtitle_sort: None, force_hardsub: false, threads: num_cpus::get(), + ffmpeg_threads: None, } } @@ -75,7 +77,9 @@ impl DownloadBuilder { subtitle_sort: self.subtitle_sort, force_hardsub: self.force_hardsub, - threads: self.threads, + + download_threads: self.threads, + ffmpeg_threads: self.ffmpeg_threads, formats: vec![], } @@ -102,7 +106,9 @@ pub struct Downloader { subtitle_sort: Option>, force_hardsub: bool, - threads: usize, + + download_threads: usize, + ffmpeg_threads: Option, formats: Vec, } @@ -343,6 +349,7 @@ impl Downloader { } } + let preset_custom = matches!(self.ffmpeg_preset, FFmpegPreset::Custom(_)); let (input_presets, mut output_presets) = self.ffmpeg_preset.into_input_output_args(); let fifo = temp_named_pipe()?; @@ -356,6 +363,11 @@ impl Downloader { command_args.extend(input); command_args.extend(maps); command_args.extend(metadata); + if !preset_custom { + if let Some(ffmpeg_threads) = self.ffmpeg_threads { + command_args.extend(vec!["-threads".to_string(), ffmpeg_threads.to_string()]) + } + } // set default subtitle if let Some(default_subtitle) = self.default_subtitle { @@ -618,7 +630,7 @@ impl Downloader { None }; - let cpus = self.threads; + let cpus = self.download_threads; let mut segs: Vec> = Vec::with_capacity(cpus); for _ in 0..cpus { segs.push(vec![])