When I try to spawn a child ffmpeg process I use additonal flag -progress
, next I use pipe to pass this progress output to the stderr.
So the whole command looks like:
ffmpeg -i ... -progress pipe:2 ...
Without -progress
flag ffmepg outputs following line in stderr, probably once per second:
frame=46 46 fps=0.0 q=0.0 size= 0kB time=00:00:01.72 bitrate= 0.2kbits/s speed=2.69x
With -progress
flag ffmepg outputs (multiple lines) in stderr, probably once per second:
frame=1 1 fps=0.0 q=0.0 size= 0kB time=00:00:00.19 bitrate= 2.0kbits/s speed=2.94x
fps=0.00
stream_0_0_q=0.0
bitrate= 2.0kbits/s
total_size=48
out_time_us=192000
out_time_ms=192000
out_time=00:00:00.192000
dup_frames=0
drop_frames=0
speed=2.94x
progress=continue
The main puppose of using -progress
flag is to calc percentage of completion by parsing out_time_ms
line and comparing to the whole duration.
Reading this chunk (portion of lines) is pretty simple in NodeJS:
const { spawn } = require('child_process');
const child = spawn('ffmpeg', [..., '-progress', 'pipe:2', ...]);
child.stderr.on('data', (data) => {
// data will contain multiple lines, exactly one chunk
});
Reading this chunk (portion of lines) is pretty simple in Deno also:
const child = Deno.spawnChild("ffmpeg", {
args: [..., '-progress', 'pipe:2', ...],
});
const stderrReader = child.stderr.getReader();
let readResult = await stderrReader.read();
while (readResult.done !== true) {
readResult = await stderrReader.read();
// readResult will contain multiple lines, exactly one chunk
}
I can't achieve the same in rust:
let mut command = Command::new("ffmpeg");
command.args(["...", "-progress", "pipe:2", "..."]);
let mut child = command
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.unwrap();
let child_stderr = child.stderr.as_mut().expect("Unable to pipe stderr");
let mut reader = BufReader::new(child_stderr);
let mut buff = String::new();
while reader.read_line(&mut buff).expect("Unable to read chunk") > 0 {
// buff will contain only on line
buff.clear();
}
I am new in Rust. I can not detect what character signals end of chunk.
- Runnig
read_line()
- will read only one line. - Runnig
read_to_end()
- will read the whole output until the end of process (EOF).
How can I read in Rust portion of lines that ffmpeg outputs probably once per second? How Node/Deno detects this "end of chunk"? Does rust have such event/signal also?