I am trying to read a video stream through a pipe from ffmpeg running in a child process. My program currently looks like this:
const std = @import("std");
const INPUT_WIDTH = 786;
const INPUT_HEIGHT = 588;
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
var allocator = gpa.allocator();
const argv = [_][]const u8{ "ffmpeg", "ffmpeg -i teapot.mp4 -f image2pipe -vcodec rawvideo -pix_fmt rgb24 -" };
var process = std.process.Child.init(&argv, allocator);
process.stdout_behavior = .Pipe;
try process.spawn();
var buffer: [INPUT_WIDTH * INPUT_HEIGHT * 3]u8 = undefined;
var n_bytes: usize = undefined;
while (true) {
n_bytes = try process.stdout.?.read(&buffer);
// TODO: Process video input
if (n_bytes == 0) break;
}
}
However when running the program, I get the following error:
Unable to find a suitable output format for ' -i in.mov -f rawvideo - '-i in.mov -f rawvideo - : Invalid argument
Now I am aware that this is an error coming from ffmpeg and not something Zig-specific. BUT: I've tried running this very similar C program which uses popen() to read from ffmpeg running in a child process and it works absolutely fine:
Now I am wondering:
-
Is spawning a child process and reading from its
stdouteven the correct way to pipe the output of a child process into a Zig program? -
Is there maybe a different way to do what
popen()does in the C example linked above?