Skip to main content

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}