mirror of
https://github.com/crunchy-labs/crunchy-cli.git
synced 2026-01-21 04:02:00 -06:00
Fix crashes when converting subtitles (#408)
This commit is contained in:
parent
53a710a373
commit
48bb7a5ef6
3 changed files with 30 additions and 18 deletions
|
|
@ -30,7 +30,7 @@ log = { version = "0.4", features = ["std"] }
|
|||
num_cpus = "1.16"
|
||||
regex = "1.10"
|
||||
reqwest = { version = "0.12", features = ["socks", "stream"] }
|
||||
rsubs-lib = ">=0.2.1"
|
||||
rsubs-lib = "0.3"
|
||||
rusty-chromaprint = "0.2"
|
||||
serde = "1.0"
|
||||
serde_json = "1.0"
|
||||
|
|
@ -38,6 +38,7 @@ serde_plain = "1.0"
|
|||
shlex = "1.3"
|
||||
sys-locale = "0.3"
|
||||
tempfile = "3.10"
|
||||
time = "0.3"
|
||||
tokio = { version = "1.37", features = ["io-util", "macros", "net", "rt-multi-thread", "time"] }
|
||||
tokio-util = "0.7"
|
||||
tower-service = "0.3"
|
||||
|
|
|
|||
|
|
@ -13,17 +13,19 @@ use indicatif::{ProgressBar, ProgressDrawTarget, ProgressFinish, ProgressStyle};
|
|||
use log::{debug, warn, LevelFilter};
|
||||
use regex::Regex;
|
||||
use reqwest::Client;
|
||||
use rsubs_lib::{ssa, vtt};
|
||||
use rsubs_lib::{SSA, VTT};
|
||||
use std::borrow::Borrow;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::io::Write;
|
||||
use std::ops::Add;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use std::{env, fs};
|
||||
use tempfile::TempPath;
|
||||
use time::Time;
|
||||
use tokio::io::{AsyncBufReadExt, AsyncReadExt, BufReader};
|
||||
use tokio::select;
|
||||
use tokio::sync::mpsc::unbounded_channel;
|
||||
|
|
@ -929,36 +931,43 @@ impl Downloader {
|
|||
) -> Result<TempPath> {
|
||||
let buf = subtitle.data().await?;
|
||||
let mut ass = match subtitle.format.as_str() {
|
||||
"ass" => ssa::parse(String::from_utf8_lossy(&buf).to_string()),
|
||||
"vtt" => vtt::parse(String::from_utf8_lossy(&buf).to_string()).to_ass(),
|
||||
"ass" => SSA::parse(String::from_utf8_lossy(&buf))?,
|
||||
"vtt" => VTT::parse(String::from_utf8_lossy(&buf))?.to_ssa(),
|
||||
_ => bail!("unknown subtitle format: {}", subtitle.format),
|
||||
};
|
||||
// subtitles aren't always correct sorted and video players may have issues with that. to
|
||||
// prevent issues, the subtitles are sorted
|
||||
ass.events
|
||||
.sort_by(|a, b| a.line_start.total_ms().cmp(&b.line_start.total_ms()));
|
||||
// (https://github.com/crunchy-labs/crunchy-cli/issues/208)
|
||||
ass.events.sort_by(|a, b| a.start.cmp(&b.start));
|
||||
// it might be the case that the start and/or end time are greater than the actual video
|
||||
// length. this might also result in issues with video players, thus the times are stripped
|
||||
// to be maxim
|
||||
// to be at most as long as `max_length`
|
||||
// (https://github.com/crunchy-labs/crunchy-cli/issues/32)
|
||||
for i in (0..ass.events.len()).rev() {
|
||||
if ass.events[i].line_end.total_ms() > max_length.num_milliseconds() as u32 {
|
||||
if ass.events[i].line_start.total_ms() > max_length.num_milliseconds() as u32 {
|
||||
ass.events[i]
|
||||
.line_start
|
||||
.set_ms(max_length.num_milliseconds() as u32);
|
||||
let max_len = Time::from_hms(0, 0, 0)
|
||||
.unwrap()
|
||||
.add(Duration::from_millis(max_length.num_milliseconds() as u64));
|
||||
|
||||
if ass.events[i].start > max_len {
|
||||
if ass.events[i].end > max_len {
|
||||
ass.events[i].start = max_len
|
||||
}
|
||||
ass.events[i]
|
||||
.line_end
|
||||
.set_ms(max_length.num_milliseconds() as u32);
|
||||
ass.events[i].end = max_len
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// without this additional info, subtitle look very messy in some video player
|
||||
// (https://github.com/crunchy-labs/crunchy-cli/issues/66)
|
||||
ass.info
|
||||
.additional_fields
|
||||
.insert("ScaledBorderAndShadows".to_string(), "yes".to_string());
|
||||
|
||||
let tempfile = tempfile(".ass")?;
|
||||
let path = tempfile.into_temp_path();
|
||||
|
||||
ass.to_file(path.to_string_lossy().to_string().as_str())?;
|
||||
fs::write(&path, ass.to_string())?;
|
||||
|
||||
Ok(path)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue