Files
oak-editor/crates/oak-cli
Mike-Solar 18ff60f147 feat(engine): clip move, clip effect_input, mandatory static FFmpeg
- oakengine_sequence_move_clip implemented for real (oaktimeline
  TrackMoveBlockCommand; fixes the graph-ownership/gap-anchor/ripple
  trim bugs the stub was hiding); same-track via the frozen C ABI,
  cross-track supported by the module command
- oaknode clip blocks now declare a tex_in texture input and set
  effect_input to it, so timeline clips can host effect chains; facade
  test covers effect insert/remove on a real clip
- oakffmpeg-link: FFMPEG_DIR is now mandatory with a clear panic (a
  Homebrew upgrade left the system ffmpeg .pc pointing at a deleted
  dav1d Cellar path, breaking links); reads a git-ignored workspace
  .env for IDEs that cannot inject env vars (RustRover); links the C++
  stdlib for C++ codec libs (svt-av1)
- oakengine re-exports oaknode so tests share one crate instance;
  it_node uses the direct instance's value type where it calls the
  module FFI (the --workspace dev-dependency feature split builds
  oaknode twice)
2026-08-11 23:04:48 +08:00
..

oak-cli (Rust)

Headless command-line consumer of the liboakengine C ABI facade — the Rust rewrite of cli/main.cpp (which stays in the tree until cutover). Same subcommands, same output format, same exit codes:

exit meaning
0 success
1 general error (bad project/media file, no sequence, I/O failure)
2 rendering unavailable or failed (e.g. no GL render backend)
64 usage error

Build and test

cargo build --release      # binary: target/release/oak-cli
cargo test                 # unit + integration tests (29 tests)

The crate builds standalone: its only dependency besides clap is the oakengine rlib (../oakengine), which has no third-party dependencies.

Subcommands

Every subcommand of the C++ original is implemented:

oak-cli info <project.ove> <start> <end> <out_dir>   project name/sequences/footage
oak-cli render <project.ove> <start_seconds> <end_seconds> <out_dir>
oak-cli probe <mediafile>
oak-cli transcode <input_media> <out> [width] [--format ppm|mp4]

Argument validation is faithful to the C++ (invalid start seconds, invalid width, unknown --format … all exit 64). The output formatters (src/fmt.rs) reproduce the C++ printf output byte for byte and are golden-tested against the output captured from the C++ binary on the test fixtures (tests/project_with_footage.ove, tests/demo.mp4); the PPM and WAV writers (src/ppm.rs, src/wav.rs) are the exact ports of the C++ write_ppm/write_wav and are unit-tested.

Facade status: everything is currently deferred

All four subcommands depend on facade families that are still deferred in the oakengine crate (crates/oakengine/src/deferred.rs), so today each subcommand validates its arguments, then prints a clear "not yet available" error naming the missing families and the reasons, and exits with the C++-compatible code — it never crashes and never fakes output:

subcommand needs current behavior
info init + node (project/footage) + timeline "not yet available", exit 1
probe init + node (footage) "not yet available", exit 1
render init + node + timeline + render "not yet available", exit 2
transcode init + node + timeline + render + exporter "not yet available", exit 2

The deferral registry is src/deferred.rs (field-for-field in sync with the facade's own deferred.rs). When a family is wrapped by the facade:

  1. remove its entry from src/deferred.rs,
  2. wire the call-through in src/cmd/ using the extern declarations in src/ffi.rs (verbatim mirrors of the engine headers) and the tested formatters/writers — no manifest or signature change is needed, because the externs resolve against the already-linked oakfacade rlib.

Layout

src/
  main.rs       clap surface, --help/-h + unknown-command handling, dispatch
  ffi.rs        the oakengine_* surface oak-cli consumes (declarations only)
  deferred.rs   facade-family availability registry (mirror of facade deferred.rs)
  fmt.rs        golden output formatters (info/probe)
  ppm.rs        P6 PPM writer (f32/u8 frames)
  wav.rs        PCM s16 WAV writer (interleaved float samples)
  cmd/          per-subcommand validation + deferred gate
tests/cli.rs    binary-level tests (exit codes, messages, usage errors)