Skip to content

Commit e075b4b

Browse files
fix
scale filter not working invalid time string error early exit encode task
1 parent b9af238 commit e075b4b

4 files changed

Lines changed: 62 additions & 48 deletions

File tree

ffmpeg_progress_monitor/src/lib.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,14 @@ pub struct ProgressMonitor {
3030
}
3131

3232
impl ProgressMonitor {
33-
pub fn new(total_duration_secs: f32) -> ProgressMonitorResult<Self> {
33+
pub fn new(total_duration_secs: f32, msg: String) -> ProgressMonitorResult<Self> {
3434
let pb = ProgressBar::new(100);
3535
pb.set_draw_target(ProgressDrawTarget::stderr_with_hz(4));
3636
pb.set_style(
3737
ProgressStyle::default_bar()
38-
.template("{spinner} [{elapsed_precise}] [{bar:40}] {percent}% ({eta})")?
39-
.progress_chars("#>-"),
38+
.template("{spinner} {msg} {percent}% elapsed:{elapsed} eta:{eta}")?,
4039
);
41-
40+
pb.set_message(msg);
4241
Ok(Self {
4342
pb,
4443
total_duration_secs,
@@ -64,13 +63,15 @@ impl ProgressMonitor {
6463
match key {
6564
"total_size" => total_size = value.parse()?,
6665
"out_time" => {
67-
let current_secs = Self::time_string_to_seconds(value)?;
68-
let new_progress =
69-
(current_secs / self.total_duration_secs * 100.0).clamp(0.0, 100.0) as u8;
70-
71-
if new_progress.abs_diff(last_progress) >= 1 {
72-
self.pb.set_position(new_progress.into());
73-
last_progress = new_progress;
66+
// 这里省略了错误处理,进度展示不应该影响 ffmpeg 的核心任务
67+
if let Ok(current_secs) = Self::time_string_to_seconds(value) {
68+
let new_progress = (current_secs / self.total_duration_secs * 100.0)
69+
.clamp(0.0, 100.0) as u8;
70+
71+
if new_progress.abs_diff(last_progress) >= 1 {
72+
self.pb.set_position(new_progress.into());
73+
last_progress = new_progress;
74+
}
7475
}
7576
}
7677
"progress" if value == "end" => {
@@ -142,7 +143,7 @@ mod test {
142143

143144
#[test]
144145
fn test_progress_data_parsing() -> ProgressMonitorResult<()> {
145-
let monitor = ProgressMonitor::new(100.0)?;
146+
let monitor = ProgressMonitor::new(100.0, String::default())?;
146147
let stderr = mock_ffmpeg_output(&[
147148
"total_size=2048000",
148149
"out_time=00:00:10.000",
@@ -159,7 +160,7 @@ mod test {
159160

160161
#[test]
161162
fn test_progress_calculation() -> ProgressMonitorResult<()> {
162-
let monitor = ProgressMonitor::new(200.0)?;
163+
let monitor = ProgressMonitor::new(200.0, String::default())?;
163164

164165
// 模拟时间推进:50秒 -> 100秒 -> 150秒
165166
let stderr = mock_ffmpeg_output(&[
@@ -177,7 +178,7 @@ mod test {
177178

178179
#[test]
179180
fn test_missing_end_flag() -> ProgressMonitorResult<()> {
180-
let monitor = ProgressMonitor::new(100.0)?;
181+
let monitor = ProgressMonitor::new(100.0, String::default())?;
181182
let stderr = mock_ffmpeg_output(&["total_size=1024000"]);
182183

183184
let result = monitor.process_progress_info(stderr);

src/encode_video.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ pub fn process_encode(
5252
let config = Config::init(PathBuf::from(input), *resolution, *preset, fps);
5353
let metadata = Metadata::retrive(input)?;
5454
let encoder = Encoder::new(&config, &metadata)?;
55-
let stat = encoder.encode(ProgressMonitor::new(metadata.duration())?)?;
55+
let stat = encoder.encode(ProgressMonitor::new(
56+
metadata.duration(),
57+
config.input().to_string_lossy().into_owned(),
58+
)?)?;
5659

5760
let reduction = stat.1 as f64 / metadata.size() as f64;
5861

src/main.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ fn main() {
1414
.init();
1515

1616
match run() {
17-
Ok(has_error) if has_error => process::exit(1),
17+
// has_error
18+
Ok(true) => process::exit(1),
1819
Ok(_) => process::exit(0),
1920
Err(e) => {
2021
log::error!("{}", e);
@@ -27,9 +28,7 @@ fn run() -> Result<bool> {
2728
let cli = Cli::parse();
2829

2930
match &cli.command {
30-
Commands::EncodeVideo(args) => encode_video::process_args(args)?,
31-
Commands::GenerateVideoThumbnail(args) => todo!(),
32-
};
33-
34-
Ok(true)
31+
Commands::EncodeVideo(args) => Ok(encode_video::process_args(args)?),
32+
Commands::GenerateVideoThumbnail(_) => Ok(false),
33+
}
3534
}

video_encoder/src/encoder.rs

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,45 +57,54 @@ impl Encoder {
5757
})
5858
}
5959

60-
fn scale_filter(&self) -> Option<[String; 2]> {
61-
match (self.scaled_width, self.scaled_height) {
62-
(Some(width), None) => Some(["-vf".to_string(), format!("scale={}:-2", width)]),
63-
(None, Some(height)) => Some(["-vf".to_string(), format!("scale=-2:{}", height)]),
64-
_ => None,
65-
}
66-
}
67-
68-
// ffmpeg -hide_banner -v error -progress pipe:2 -i input.mp4 -c:v libx265 -x265-params log-level=error:output-depth=10:crf=20 -pix_fmt -preset medium yuv420p10le -filter:v fps=24 -f mp4 -c:a copy output.mp4
60+
// ffmpeg -hide_banner -v error -progress pipe:2 -i input.mp4 -c:v libx265 -x265-params log-level=error:output-depth=10:crf=20 -pix_fmt yuv420p10le -preset medium -vf scale=1280:-2,fps=24 -f mp4 -c:a copy output.mp4
6961
pub(crate) fn build_ffmpeg_args(&self) -> EncodeResult<Vec<String>> {
7062
let mut args: Vec<String> = Vec::new();
63+
7164
args.extend(
72-
["-hide_banner", "-v", "error", "-progress", "pipe:2", "-i"].map(|s| s.to_string()),
65+
["-hide_banner", "-v", "error", "-progress", "pipe:2", "-i"]
66+
.iter()
67+
.map(|&s| s.to_string()),
7368
);
7469

75-
args.push(self.input.to_string_lossy().to_string());
76-
77-
args.extend(["-c:v", "libx265", "-x265-params"].map(|s| s.to_string()));
70+
args.push(self.input.to_string_lossy().into_owned());
71+
args.extend(
72+
["-c:v", "libx265", "-x265-params"]
73+
.iter()
74+
.map(|&s| s.to_string()),
75+
);
7876

7977
args.push(format!("log-level=error:output-depth=10:crf={}", self.crf));
8078

8179
args.push("-preset".to_string());
8280

8381
args.push(format!("{}", self.preset));
8482

85-
args.extend(["-pix_fmt", "yuv420p10le"].map(|s| s.to_string()));
83+
args.extend(["-pix_fmt", "yuv420p10le"].iter().map(|&s| s.to_string()));
8684

87-
if let Some(filter) = self.scale_filter() {
88-
args.extend(filter);
89-
}
90-
91-
if let Some(fps) = self.fps {
92-
args.push("-filter:v".to_string());
93-
args.push(format!("fps={}", fps));
85+
match (self.scaled_width, self.scaled_height, self.fps) {
86+
(Some(width), None, Some(fps)) => {
87+
args.push("-vf".to_string());
88+
args.push(format!("scale={}:-2,fps={}", width, fps));
89+
}
90+
(Some(width), None, None) => {
91+
args.push("-vf".to_string());
92+
args.push(format!("scale={}:-2", width));
93+
}
94+
(None, Some(height), Some(fps)) => {
95+
args.push("-vf".to_string());
96+
args.push(format!("scale=-2:{},fps={}", height, fps));
97+
}
98+
(None, Some(height), None) => {
99+
args.push("-vf".to_string());
100+
args.push(format!("scale=-2:{}", height));
101+
}
102+
_ => (),
94103
}
95104

96-
args.extend(["-f", "mp4", "-c:a", "copy"].map(|s| s.to_string()));
105+
args.extend(["-f", "mp4", "-c:a", "copy"].iter().map(|&s| s.to_string()));
97106

98-
args.push(self.output()?.to_string_lossy().to_string());
107+
args.push(self.output()?.to_string_lossy().into_owned());
99108

100109
Ok(args)
101110
}
@@ -189,9 +198,12 @@ mod test {
189198
assert_eq!(encoder.scaled_width, Some(config.resolution.width()));
190199
assert_eq!(encoder.scaled_height, None);
191200
let args = encoder.build_ffmpeg_args()?.join(" ");
192-
assert!(args.contains(&format!("fps={}", config.fps)));
193201
assert!(args.contains(&"crf=19".to_string()));
194-
assert!(args.contains(&format!("scale={}:-2", config.resolution.width())));
202+
assert!(args.contains(&format!(
203+
"-vf scale={}:-2,fps={}",
204+
config.resolution.width(),
205+
config.fps
206+
)));
195207

196208
// 竖屏
197209
let config = Config {
@@ -204,7 +216,7 @@ mod test {
204216
assert_eq!(encoder.scaled_width, None);
205217
assert_eq!(encoder.scaled_height, Some(config.resolution().height()));
206218
let args = encoder.build_ffmpeg_args()?.join(" ");
207-
assert!(args.contains(&format!("scale=-2:{}", config.resolution.height())));
219+
assert!(args.contains(&format!("-vf scale=-2:{}", config.resolution.height())));
208220
Ok(())
209221
}
210222

@@ -223,7 +235,6 @@ mod test {
223235
assert_eq!(encoder.scaled_width, None);
224236
assert_eq!(encoder.scaled_height, None);
225237
let args = encoder.build_ffmpeg_args()?.join(" ");
226-
assert!(!args.contains(&"fps=".to_string()));
227238
assert!(args.contains(&"crf=20".to_string()));
228239
assert!(!args.contains(&"-vf".to_string()));
229240

0 commit comments

Comments
 (0)