oxideav_cli_convert/lib.rs
1//! `oxideav convert` engine.
2//!
3//! Translates ImageMagick-style arg syntax into an in-memory
4//! [`oxideav_pipeline::Job`] and runs it through the same executor
5//! the `oxideav run` subcommand uses. One code path serves image,
6//! video, and audio inputs — a PNG → JPG is just a 1-frame stream.
7//!
8//! Entry point: [`run`] takes the slice of arguments that come after
9//! `oxideav convert` plus the caller-supplied registries, and does
10//! everything.
11//!
12//! # Example
13//!
14//! ```no_run
15//! use oxideav_core::RuntimeContext;
16//!
17//! let mut ctx = RuntimeContext::new();
18//! oxideav_source::register(&mut ctx);
19//!
20//! // Equivalent to:
21//! // oxideav convert in.png -resize 800x600 out.jpg
22//! oxideav_cli_convert::run(
23//! &[
24//! "in.png".into(),
25//! "-resize".into(),
26//! "800x600".into(),
27//! "out.jpg".into(),
28//! ],
29//! &ctx,
30//! ).unwrap();
31//! ```
32
33pub mod args;
34pub mod op;
35pub mod plan_to_job;
36
37pub use op::{ConvertPlan, Dither, Op};
38
39use oxideav_core::{Error, RuntimeContext};
40
41/// Run convert with a caller-supplied [`RuntimeContext`].
42///
43/// The CLI passes the same context produced by `oxideav::with_all_features()`
44/// it uses for `remux` / `transcode` / `run`; third-party embedders can
45/// pass a narrower set.
46pub fn run(args: &[String], ctx: &RuntimeContext) -> Result<(), Error> {
47 let plan = args::parse(args)?;
48 let job = plan_to_job::plan_to_job(&plan)?;
49 let stats = oxideav_pipeline::Executor::new(&job, ctx).run()?;
50 eprintln!(
51 "convert: {} packet(s) read, {} frame(s) decoded, {} frame(s) written",
52 stats.packets_read, stats.frames_decoded, stats.frames_written
53 );
54 Ok(())
55}