Created
July 7, 2020 23:38
-
-
Save yongkyuns/16651e2d1a6b55d6405d330d839a4bc8 to your computer and use it in GitHub Desktop.
FFMPEG usage in rust using command and raw pixels
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::io::prelude::*; | |
use std::process::{Command, Stdio}; | |
fn main() { | |
let mut child = Command::new("ffmpeg") | |
// Overwrite file if it already exists | |
.arg("-y") | |
// Interpret the information from stdin as "raw video" ... | |
.arg("-f") | |
.arg("rawvideo") | |
// ... where every four bytes are [r, g, b, a] format | |
.arg("-pix_fmt") | |
.arg("rgba") | |
// The size of the video is 3840x2160 | |
.arg("-s") | |
.arg("1920x1080") | |
// 60 frames per second | |
.arg("-r") | |
.arg("60") | |
// Don't expect any audio in the stream | |
.arg("-an") | |
// Get the data from stdin | |
.arg("-i") | |
.arg("-") | |
// encode to h264 | |
.arg("-c:v") | |
.arg("libx264") | |
// variable video bitrate | |
.arg("-crf") | |
.arg("0") | |
// Output file | |
.arg("test.mp4") | |
// stdin, stderr, and stdout are piped | |
.stdin(Stdio::piped()) | |
.stderr(Stdio::piped()) | |
.stdout(Stdio::piped()) | |
// Run the child command | |
.spawn() | |
.unwrap(); | |
let stdin = child.stdin.as_mut().unwrap(); | |
let mut buffer = vec![0; 1920 * 1080 * 4]; | |
let mut frames = 0; | |
for r in 0..4 { | |
for gb in 0..=255 { | |
println!("{}", gb); | |
generate_frame(&mut buffer, 1920, 1080, r, gb, gb, 0xff); | |
stdin.write_all(&buffer); | |
frames += 1; | |
} | |
} | |
let output = child.wait_with_output().unwrap(); | |
println!("{}", String::from_utf8(output.stdout).unwrap()); | |
println!("{}", String::from_utf8(output.stderr).unwrap()); | |
println!("Generated {} frames.", frames) | |
} | |
fn generate_frame(buffer: &mut Vec<u8>, width: usize, height: usize, r: u8, g: u8, b: u8, a: u8) { | |
for row in 0..height { | |
for col in 0..width { | |
buffer[(row * width + col) * 4 + 0] = r; // red | |
buffer[(row * width + col) * 4 + 1] = g; // green | |
buffer[(row * width + col) * 4 + 2] = b; // blue | |
buffer[(row * width + col) * 4 + 3] = a; // alpha | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment