use crate::prelude::*;
#[injectable]
pub(crate) struct TranscodeJobFactory {
paths: Ref<PathManager>,
copy_options: Ref<CopyOptions>,
target_options: Ref<TargetOptions>,
sox: Ref<SoxFactory>,
}
impl TranscodeJobFactory {
pub(crate) fn create(
&self,
flacs: &[FlacFile],
source: &Source,
format: TargetFormat,
) -> Result<Vec<Job>, Failure<TranscodeAction>> {
let mut jobs = Vec::new();
for (index, flac) in flacs.iter().enumerate() {
jobs.push(self.create_single(index, flac, source, format)?);
}
Ok(jobs)
}
pub(crate) fn create_single(
&self,
index: usize,
flac: &FlacFile,
source: &Source,
format: TargetFormat,
) -> Result<Job, Failure<TranscodeAction>> {
let info = flac.get_stream_info().map_err(Failure::wrap_with_path(
TranscodeAction::ReadFlac,
&flac.path,
))?;
let id = format!("Transcode {:<4}{index:>3}", format.to_string());
let output_path = self.paths.get_transcode_path(source, format, flac);
let repeatable = !self.target_options.sox_random_dither;
let variant = match format {
TargetFormat::Flac => {
if is_resample_required(&info) {
Variant::Resample(Resample {
input: flac.path.clone(),
output: output_path.clone(),
resample_rate: get_resample_rate(&info).map_err(
Failure::wrap_with_path(TranscodeAction::GetSampleRate, &flac.path),
)?,
repeatable,
sox: self.sox.clone(),
})
} else {
Variant::Include(Include {
input: flac.path.clone(),
output: output_path.clone(),
hard_link: self.copy_options.hard_link,
})
}
}
TargetFormat::_320 | TargetFormat::V0 => {
let resample_rate = is_resample_required(&info)
.then(|| get_resample_rate(&info))
.transpose()
.map_err(Failure::wrap_with_path(
TranscodeAction::GetSampleRate,
&flac.path,
))?;
Variant::Transcode(
Decode {
input: flac.path.clone(),
resample_rate,
repeatable,
sox: self.sox.clone(),
},
Encode {
format,
output: output_path.clone(),
},
)
}
};
let tags = if matches!(format, TargetFormat::_320 | TargetFormat::V0) {
Some(flac.id3_tags()?.clone())
} else {
None
};
let exclude_vorbis_comments = self.target_options.exclude_vorbis_comments.clone();
Ok(Job::Transcode(TranscodeJob {
id,
variant,
tags,
exclude_vorbis_comments,
}))
}
}