diff --git a/substudy/src/main.rs b/substudy/src/main.rs index d9acc72..4dc14c2 100644 --- a/substudy/src/main.rs +++ b/substudy/src/main.rs @@ -156,6 +156,11 @@ If you have no related text at all, you can omit both `--related-text` and /// Path to the subtitle file to translate. foreign_subs: PathBuf, + /// Language to translate from. This can normally be omitted, but it + /// might help with closely-related languages or mixed-language content. + #[arg(long)] + foreign_lang: Option, + /// Target language code (e.g. "en" for English). #[arg(long)] native_lang: String, @@ -318,8 +323,12 @@ async fn main() -> Result<()> { } Args::Translate { foreign_subs, + foreign_lang, native_lang, - } => cmd_translate(&ui, &foreign_subs, &native_lang).await, + } => { + cmd_translate(&ui, &foreign_subs, foreign_lang.as_deref(), &native_lang) + .await + } } } @@ -444,10 +453,17 @@ async fn cmd_transcribe( Ok(()) } -async fn cmd_translate(ui: &Ui, foreign_subs: &Path, native_lang: &str) -> Result<()> { +async fn cmd_translate( + ui: &Ui, + foreign_subs: &Path, + foreign_lang: Option<&str>, + native_lang: &str, +) -> Result<()> { let file = SubtitleFile::cleaned_from_path(foreign_subs)?; + let foreign_lang = foreign_lang.map(|f| Lang::iso639(f)).transpose()?; let native_lang = Lang::iso639(native_lang)?; - let translated = translate_subtitle_file(ui, &file, native_lang).await?; + let translated = + translate_subtitle_file(ui, &file, foreign_lang, native_lang).await?; print!("{}", translated.to_string()); Ok(()) } diff --git a/substudy/src/services/oai/translate.rs b/substudy/src/services/oai/translate.rs index c1e523e..165b310 100644 --- a/substudy/src/services/oai/translate.rs +++ b/substudy/src/services/oai/translate.rs @@ -68,12 +68,15 @@ lazy_static! { pub async fn translate_subtitle_file( ui: &Ui, file: &SubtitleFile, + from_lang: Option, to_lang: Lang, ) -> Result { // Infer the language of the subtitle file. - let from_lang = file.detect_language().ok_or_else(|| { - anyhow!("Could not detect the language of the input subtitle file") - })?; + let from_lang = from_lang + .or_else(|| file.detect_language()) + .ok_or_else(|| { + anyhow!("Could not detect the language of the input subtitle file") + })?; // Split into chunks of at least `MIN_CHUNK_SIZE`, but then try to end on a // sentence boundary. Even if we can't find a sentence boundary, end @@ -302,7 +305,7 @@ mod tests { let ui = Ui::init_for_tests(); let translated = - translate_subtitle_file(&ui, &file, Lang::iso639("es").unwrap()) + translate_subtitle_file(&ui, &file, None, Lang::iso639("es").unwrap()) .await .unwrap(); assert_eq!(translated.subtitles.len(), file.subtitles.len());