diff --git a/src-lib/src/video.rs b/src-lib/src/video.rs index c0814eb..259a467 100644 --- a/src-lib/src/video.rs +++ b/src-lib/src/video.rs @@ -3,6 +3,7 @@ use core::cmp::Ordering; use std::fs; use std::path::Path; use std::io::Write; +use std::io::Read; pub fn screenshotify(input: &String) -> Result, String> { let output_d = format!("{}.d", input); @@ -51,6 +52,8 @@ fn ify(input: &String, mut cb: impl FnMut(ContentSpan) -> Result<(), String>) -> pub fn clip(output: &String, input: &String, content_span: ContentSpan) -> Result<(), String> { fs::create_dir_all(Path::new(output).parent().unwrap()).unwrap(); match std::process::Command::new("ffmpeg") + .stdin(std::process::Stdio::null()) + .stdout(std::process::Stdio::inherit()) .args([ "-y", "-ss", &content_span.start.to_string(), @@ -84,6 +87,8 @@ pub fn screenshot(output: &String, input: &String, ts: f32) -> Result<(), String pub fn screenshot_png(input: &String, ts: f32) -> Result, String> { match std::process::Command::new("ffmpeg") + .stdin(std::process::Stdio::null()) + .stdout(std::process::Stdio::inherit()) .args([ "-y", "-ss", &ts.to_string(), @@ -108,7 +113,11 @@ pub fn inspect(file: &String) -> Result, String> { } fn _inspect(file: &String) -> Result { - match std::process::Command::new("ffmpeg") + let mut bind = std::process::Command::new("ffmpeg"); + let cmd = bind + .stdin(std::process::Stdio::null()) + .stdout(std::process::Stdio::piped()) + .stderr(std::process::Stdio::piped()) .args([ "-i", file, "-vf", "mpdecimate", @@ -116,18 +125,38 @@ fn _inspect(file: &String) -> Result { "-loglevel", "debug", "-f", "null", "-", - ]) - .output() { - Ok(output) => { - let stderr = String::from_utf8(output.stderr).unwrap(); - let stdout = String::from_utf8(output.stdout).unwrap(); - let line_iter = stderr.split("\n").chain(stdout.split("\n")); - Ok(Inspection{ - lines: line_iter.map(|x| x.to_string()).collect(), - }) - }, - Err(msg) => Err(format!("failed to ffmpeg inspect {}: {}", file, msg)), + ]); + + let mut child = cmd.spawn().expect("failed to inspect with ffmpeg"); + let mut bind = vec![0; 10]; + let mut buff: &mut [u8] = bind.as_mut(); + let mut stdout: Vec = vec![]; + let mut stderr: Vec = vec![]; + let mut delay = 100; + while let Ok(None) = child.try_wait() { + eprintln!("ffmpeg still inspecting..."); + std::thread::sleep(std::time::Duration::from_millis(delay)); + delay = if 2 * delay < 5000 { delay * 2 } else { 5000 }; + match child.stderr.as_mut().unwrap().read(buff.as_mut()) { + Ok(n) => { buff[..n].iter().for_each(|c| stderr.push(*c)); }, + Err(_) => {}, + }; + match child.stdout.as_mut().unwrap().read(buff.as_mut()) { + Ok(n) => { buff.iter().for_each(|c| stdout.push(*c)); }, + Err(_) => {}, + }; } + child.wait().expect("failed to wait for inspect with ffmpeg"); + + child.stderr.as_mut().unwrap().read_to_end(&mut stderr).unwrap(); + child.stdout.as_mut().unwrap().read_to_end(&mut stdout).unwrap(); + + let stderr = String::from_utf8(stderr).unwrap(); + let stdout = String::from_utf8(stdout).unwrap(); + let line_iter = stderr.split("\n").chain(stdout.split("\n")); + Ok(Inspection{ + lines: line_iter.map(|x| x.to_string()).collect(), + }) } struct Inspection {