use ez_ffmpeg::{Output, VideoWriter};
const WIDTH: u32 = 640;
const HEIGHT: u32 = 360;
const FPS: i32 = 30;
const SECONDS: i32 = 8;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let output = Output::from("plasma.mp4")
.set_video_codec("mpeg4")
.set_video_qscale(5);
let mut writer = VideoWriter::builder(WIDTH, HEIGHT)
.pixel_format("rgba") .fps(FPS, 1)
.open(output)?;
let frame_size = writer.frame_size();
let mut frame = vec![0u8; frame_size];
let total = FPS * SECONDS;
for i in 0..total {
render_plasma(&mut frame, WIDTH, HEIGHT, i as f32);
writer.write(&frame)?;
}
writer.finish()?;
println!("Wrote {total} frames to plasma.mp4");
Ok(())
}
fn render_plasma(buf: &mut [u8], width: u32, height: u32, t: f32) {
let w = width as f32;
let h = height as f32;
let phase = t * 0.06;
for y in 0..height {
let fy = y as f32 / h;
for x in 0..width {
let fx = x as f32 / w;
let v = (fx * 9.0 + phase).sin()
+ (fy * 7.0 - phase * 1.3).sin()
+ ((fx + fy) * 6.0 + phase * 0.7).sin()
+ ((fx - fy) * 8.0 - phase).sin();
let n = (v + 4.0) / 8.0;
let r = (0.5 + 0.5 * (n * std::f32::consts::TAU).sin()) * 255.0;
let g = (0.5 + 0.5 * (n * std::f32::consts::TAU + 2.094).sin()) * 255.0;
let b = (0.5 + 0.5 * (n * std::f32::consts::TAU + 4.188).sin()) * 255.0;
let idx = ((y * width + x) * 4) as usize;
buf[idx] = r as u8;
buf[idx + 1] = g as u8;
buf[idx + 2] = b as u8;
buf[idx + 3] = 255;
}
}
}