CLI User Guide¶
Overview¶
orc-cli is the command-line interface for Decode Orc, a cross-platform orchestration and processing framework for LaserDisc and tape decoding workflows. It provides a text-based interface for batch processing video projects defined in .orcprj files.
The CLI uses the same core processing library as the GUI (orc-gui), ensuring that project files created in the graphical interface can be executed unchanged via the command line, and vice versa.
Key Features¶
- Batch Processing: Process complete DAG pipelines without user interaction
- Automation: Integrate into scripts and automated workflows
- Reproducibility: Execute the same project file consistently across runs
- Progress Tracking: Real-time progress updates during processing
- Flexible Logging: Configurable logging levels and output destinations
- Crash Reporting: Automatic diagnostic bundle creation for troubleshooting
Basic Usage¶
Command Syntax¶
orc-cli <project-file> [options]
orc-cli --source/--filters/--sink <...>
orc-cli plugins <subcommand> [options]
orc-cli stages <subcommand> [options]
Required Arguments¶
<project-file>: Path to an Orc project file (.orcprj) — not needed by thepluginsandstagessubcommands, which do not run a pipeline
Options¶
| Option | Description | Default |
|---|---|---|
--process |
Process the complete DAG pipeline (trigger all sink nodes) | Required |
--source GRAPH, -i GRAPH |
Input (source) stage(s), for the source/filters/sink triad | - |
--filters GRAPH, -f GRAPH |
Processing stage(s), for the triad | - |
--sink GRAPH, -o GRAPH |
Output (sink) stage(s), for the triad | - |
--export-project FILE |
Save the assembled filtergraph as a .orcprj file instead of running it |
- |
--video-format NTSC\|PAL\|PAL-M |
Set the video format if no stage implies one (works when running directly too, but only --export-project requires it) |
- |
--source-type composite\|yc |
Same idea, for the source signal type | - |
--log-level LEVEL |
Set logging verbosity level | info |
--log-file FILE |
Write logs to specified file | None (console only) |
--log-out console\|file\|both |
Where log output is sent | both |
--help, -h |
Display help message and exit | - |
Log Levels¶
Available log levels (from most to least verbose):
trace: Extremely detailed debugging informationdebug: Detailed debugging informationinfo: General informational messageswarn: Warning messageserror: Error messagescritical: Critical errors onlyoff: Disable logging
Log Destinations¶
--log-out selects where log records are written:
console: console only — any--log-fileis ignoredfile: log file only — nothing is written to the consoleboth(default): console, plus the log file when--log-fileis given
file and both only reach a file when --log-file is also given. Asking for
--log-out file without a log file leaves nothing to write to, so logging
falls back to the console and a warning is emitted rather than discarding the
log silently.
The default (both with no --log-file) is plain console logging, which is
the behaviour of earlier releases.
Examples¶
Basic Processing¶
Process a project file with default settings:
Detailed Logging¶
Enable debug logging for troubleshooting:
Log to File¶
Save all log output to a file:
Log to File Only¶
Keep the console clear and send every log record to the file instead:
Combined Options¶
Process with debug logging saved to file:
Filtergraph Mode¶
As an alternative to authoring a .orcprj file, a decode pipeline can be
described directly on the command line with --source, --filters, and
--sink (short forms -i, -f, -o). This builds the same in-memory DAG a
.orcprj file would and triggers all sink nodes, so results are identical.
The .orcprj workflow itself is unchanged.
Video format (NTSC/PAL/PAL-M) and source signal type (composite/Y-C) are
usually detected automatically from the stage modules used — a stage
that is exclusively NTSC-compatible implies NTSC; a source stage with both
y_path and c_path set implies Y/C; one with input_path set implies
composite. If two stages imply conflicting formats, that is reported as an
error before anything runs. Some stages (tbc_source in particular) are
format-agnostic — they read their own format from a metadata sidecar file
rather than declaring one — so no stage in the graph may give any hint at
all; running in memory tolerates this, but see
Exporting instead of running below for the
one case where it matters.
The source/filters/sink triad¶
--source, --filters, and --sink enforce that stages go where they
belong: every stage named in --source must be a source, every stage in
--sink must be a sink, and every stage in --filters must be neither (a
transform or similar processing stage). Putting a sink in --source, for
example, is rejected with a clear error naming the correct flag — this is
checked against each stage's real role (the same metadata the GUI uses), not
guessed from its name, so it works for any third-party plugin stage too.
- Stages within a single
--source/--filters/--sinkvalue are separated by,(or;, for a separate filterchain) and are auto-connected in order. - Values may be wrapped in single quotes (
'...') or double quotes ("...") — whichever is more convenient for your shell — to include:,;and spaces literally; the two quote styles are interchangeable, and a value quoted with one may freely contain the other. A value may also be escaped with a backslash (\) instead of quoting, and may itself contain=.
orc-cli \
--source "tbc_source=input_path=capture.tbc" \
--filters "dropout_correct" \
--sink "video_sink=output_path=capture.mp4"
The same thing with short options and a CVBS source:
Any of the three may be omitted, but at least one must be non-empty.
Windows paths¶
Unquoted Windows paths (drive letters and backslashes) are parsed correctly:
If a value needs to rule out any ambiguity — for instance it contains a literal comma or semicolon — wrap it in single or double quotes, whichever your shell passes through more conveniently.
Non-linear graphs¶
Fan-in (multiple sources into one stage, e.g. a stacker) and fan-out (one
stage feeding several sinks) are fully supported, using [label] link
syntax to connect stages across --source/--filters/--sink:
orc-cli --source "tbc_source=input_path=a.tbc[a]; tbc_source=input_path=b.tbc[b]; tbc_source=input_path=c.tbc[c]" \
--filters "[a][b][c] stacker" \
--sink video_sink
Exporting instead of running¶
--export-project builds the project exactly as --source/--filters/
--sink normally would, but saves it as a .orcprj file instead of
triggering it — using the same saveProject() writer the GUI's "Save As"
uses, so this isn't a new save format, just a different way to reach the
existing one:
orc-cli --source "tbc_source=input_path=capture.tbc" --sink video_sink \
--export-project capture.orcprj
Useful for building a project quickly from the command line and then
opening it in the GUI, or reusing it later with --process.
A saved .orcprj file requires an explicit video format and source signal
type — unlike running in memory, which tolerates either being undetermined.
If no stage implies one (a format-agnostic source like tbc_source reads
its own format from its metadata sidecar file rather than implying one),
--video-format and/or --source-type set them explicitly:
orc-cli --source "tbc_source=input_path=capture.tbc" --sink video_sink \
--export-project capture.orcprj --video-format NTSC --source-type composite
--video-format/--source-type also work without --export-project — set
them when running a graph directly and no stage implies a format, and the
graph gets the same format-specific parameter defaults it would after being
exported and reprocessed with --process, rather than only the
exported/reprocessed path ever getting a concrete value. --export-project
is the only thing that actually requires one, since it's the .orcprj
file format itself that demands an explicit value, not the pipeline.
Discovering stages and their parameters¶
Every stage's parameter names, types, and which ones are required come from
the same descriptors the GUI uses (getStageParameters()), so a mismatch
between a filtergraph and what a stage actually accepts is caught before
anything runs — see the "Missing required parameter" and "not recognised"
errors below. Ask orc-cli stages for the exact name and parameters of any
stage this build can run; see Stage introspection.
Processing Workflow¶
When you run orc-cli --process, the following occurs:
- Project Loading: The
.orcprjfile is loaded and validated - DAG Construction: The processing pipeline is built from the project definition
- Validation: Input files and parameters are verified
- Sink Triggering: All sink nodes in the DAG are triggered sequentially
- Progress Reporting: Real-time progress updates are displayed (every 5%)
- Completion: Exit code indicates success (0) or failure (non-zero)
Progress Output¶
During processing, you'll see progress updates like:
[2026-02-08 10:15:23.456] [cli] [info] Loading project: my-project.orcprj
[2026-02-08 10:15:23.789] [cli] [info] Project loaded: My Video Project
[2026-02-08 10:15:24.012] [cli] [info] [Progress: 0%] Starting decoding...
[2026-02-08 10:15:45.234] [cli] [info] [Progress: 5%] Processing frames...
[2026-02-08 10:16:12.567] [cli] [info] [Progress: 10%] Processing frames...
...
[2026-02-08 10:25:34.890] [cli] [info] [Progress: 100%] Decode complete
Plugin management¶
orc-cli plugins edits the same registry file the GUI's Plugin Manager
edits,
and uses the same words for the same things. Changes take effect at the next
application launch, never mid-run.
Selectors¶
Every identifier plugins list prints is accepted verbatim by the commands
that take one, so a line of listing output is usable as input without editing.
A selector is the entry's plugin id when it has one, and otherwise a
path:<path> or url:<asset-url> handle; bare paths and asset URLs are
accepted too. A selector that matches more than one entry is an error listing
the candidates, never a guess.
Installed plugins¶
orc-cli plugins list # plugins you installed
orc-cli plugins list --core # ...and the ones that ship with Orc
orc-cli plugins list --check-updates # ...with each entry's update status
Core plugins are hidden by default, matching the Plugin Manager's unticked
Show core plugins; --core (or --all) includes them. Each entry reports
its selector, source and a single status — Enabled when it will load at
the next launch, otherwise the one reason it will not (Disabled,
Not trusted yet, Needs a rebuild — with the Orc ABI number it needs a
rebuild for — Binary missing, Core plugin).
plugins list never goes to the network unless --check-updates is passed.
Trust¶
Plugins execute code locally, so adding, installing, updating and enabling a
plugin ask for confirmation before the binary is allowed to run — the same
warning the GUI shows. Pass --yes to confirm without prompting. When stdin is
not a terminal and --yes is absent, the command fails immediately naming
--yes rather than waiting for an answer that cannot arrive.
orc-cli plugins add /path/to/plugin.so --yes
orc-cli plugins add --url https://github.com/owner/repo/releases --yes
orc-cli plugins enable com.example.myplugin --yes
orc-cli plugins remove --dry-run com.example.myplugin # resolve, write nothing
Withdrawing a permission grants nothing, so the commands that only take
capability away never prompt (each still accepts --yes, so a script can
pass the flag uniformly):
orc-cli plugins disable com.example.myplugin
orc-cli plugins untrust com.example.myplugin
orc-cli plugins remove com.example.myplugin
plugins trust and plugins untrust remain as explicit primitives for
scripts. trust is what enable does implicitly, so it asks the same
question; the GUI has no separate trust control, because there adding,
installing and ticking Enabled are the trust-granting actions.
Available plugins¶
orc-cli plugins search # the whole curated index
orc-cli plugins search chroma --compatible # ...matching, with a build for this host
orc-cli plugins search --installed # ...already installed
orc-cli plugins info org.example.plugin
orc-cli plugins install org.example.plugin --yes
Entries are annotated installed, incompatible or unreachable, exactly as
the GUI's Browse Plugins… dialog labels them. The id printed for an entry
is what info and install take, and for an installed entry it is also its
registry selector.
Inspecting one plugin¶
orc-cli plugins info com.example.myplugin # installed, indexed, or both
orc-cli plugins info path:/plugins/example.so # an entry with no plugin id
plugins info accepts any selector plugins list prints and any id
plugins search prints: it describes the installed copy, the index entry, or
both when a plugin is both offered and installed. The fields it prints — and
their order — are what the Plugin Manager's Details pane and the Browse
Plugins… details pane show, so the two front ends describe a plugin
identically; for an installed copy the installed field says which version you
have and whether a newer release is published. An id found in neither place
fails with a message naming both places searched. A path: or url: selector
is registry-only, so it never goes to the network.
Diagnostics¶
Reports the registry path, the runtime plugin search paths, and every
diagnostic the plugin runtime recorded while loading — the same lines the
Plugin Manager's Diagnostics section shows, prefixed Info, Warning or
Error. It reports rather than judges: finding problems is the answer to the
question, so it still exits 0.
Updating¶
orc-cli plugins updates # check every registered plugin
orc-cli plugins update com.example.myplugin --yes
orc-cli plugins update --all --yes # every plugin with an update
An update downloads a fresh binary, so it is confirmed like an install;
--all confirms once for the whole batch and lists what it will update first.
Stage introspection¶
orc-cli stages answers, without opening the GUI, what a stage is called, what
it takes and what it does — the same information the GUI's Add Stage menu,
parameter dialog and Help... dialog show, from the same source.
A stage name is the internal token — tbc_source, not "TBC Source". It is
what stages info, stages help and --source/--filters/--sink all
accept; the display name is reported as a separate field and is never accepted
where a name belongs.
Listing stages¶
orc-cli stages list --core # every stage this build can run
orc-cli stages list --kind source --core # just the source stages
orc-cli stages list --plugin com.example.myplugin
orc-cli stages list --format PAL --core # only stages usable with PAL
Core stages are hidden by default, matching plugins list and the Plugin
Manager's unticked Show core plugins; --core (or --all) includes them,
and a note reports how many were hidden. --kind takes source, filter
(equivalently transform), analysis or sink — the categories the GUI's Add
Stage menu groups by. sink lists everything the --sink slot accepts,
analysis sinks included; analysis narrows to those alone. The plugin id each entry reports is a plugin selector, so
it feeds plugins info and stages list --plugin unchanged.
Describing one stage¶
Reports the stage's identity, then every parameter with its display name,
description, type, whether it is required, its default, any minimum, maximum or
allowed values, what it depends on, and the file-extension hint — the same
descriptor data the GUI's parameter dialog renders. --format reports the
defaults that video format selects, as the GUI does for a project of that
format.
Frame and line numbers are shown 1-based, as the GUI shows them, even though a project file stores them 0-based.
Pasting a stage into a project or a filtergraph¶
orc-cli stages info frame_map --yaml # a .orcprj parameter block
orc-cli stages info frame_map --filtergraph # stage=key=value:key=value
--yaml emits a node parameters: block with every default filled in, shaped
and indented exactly as the project writer emits one under dag: nodes:, so
it loads unmodified when pasted under a node in a .orcprj file. --filtergraph emits the form
--source/--filters/--sink take, quoted so it runs unmodified. Both carry
the 0-based values a project file and the filtergraph parser read back,
not the 1-based numbers stages info displays.
Stage instructions¶
Prints the stage's instructions.md as Markdown — the same document the GUI's
Help... context-menu action renders, read at runtime from beside the plugin
binary. A stage that ships no instructions reports that and exits non-zero,
rather than succeeding with nothing to say.
Machine-readable output¶
Every query command takes --json:
orc-cli plugins list --json
orc-cli plugins search --json
orc-cli plugins info com.example.myplugin --json
orc-cli plugins updates --json
orc-cli plugins doctor --json
orc-cli stages list --core --json
orc-cli stages info tbc_source --json
plugins list, plugins search, plugins info and plugins doctor emit one
object; plugins updates and stages list emit an array. Keys are the
presenter's own field names — lower case with underscores, never a display
label — and a field with nothing to say is still there, as "", [] or
null, so every entry has the same shape.
# Enable everything that is registered but not trusted yet
orc-cli plugins list --json \
| python3 -c 'import json,sys
for e in json.load(sys.stdin)["entries"]:
if e["load_state"] == "not_trusted": print(e["selector"])' \
| xargs -rn1 orc-cli plugins enable --yes
Points to script against:
- Identifiers come back verbatim. Every plugin object carries
selectorand every stage object carriesname; pass either straight back to the commands that take one. No string surgery on the other fields. - States are stable ids, not the words the table prints.
load_stateiswill_load/disabled/not_trusted/abi_mismatch/file_missing/core; an updatestatusisup_to_date/update_available/unreachable/unknown/not_applicable; a diagnosticseverityisinfo/warning/error; a stagekindis the word--kindaccepts. The labels stay in the human output, where they can be reworded. - Booleans and numbers are JSON booleans and numbers, not the
yes/nothe table prints. - Parameter defaults are the stored, 0-based values, matching
--yamland--filtergraphrather than the 1-based frame and line numbersstages infodisplays — this side is read by a machine, so it carries what a project file stores. - Only the document is on stdout. Runtime log lines go to stderr in this
mode, so
--jsonoutput can be piped straight into a parser. stages infoemits one format at a time:--json,--yamlor--filtergraph, not several.
Exit Codes¶
0: Success - all operations completed successfully1: Error - processing failed or invalid arguments
The plugins and stages subcommands add more specific codes so a script can
tell the cases apart:
2: Not found - no plugin matched the selector, or it matched more than one; or no stage of that name is registered (near matches are listed)3: Unavailable - the curated index or a release could not be reached4: Trust declined - confirmation was required and not given; nothing was recorded
Always check the exit code in scripts:
if orc-cli project.orcprj --process; then
echo "Processing successful!"
else
echo "Processing failed!" >&2
exit 1
fi
Project Files¶
Project File Format¶
Project files (.orcprj) are YAML-based files that define:
- Source configurations (input TBC files)
- DAG structure (processing nodes and connections)
- Node parameters (decoder settings, output formats, etc.)
- Project metadata (name, description, video format)
- Optional
required_pluginsmetadata for third-party plugin-backed stages
When a project contains stages supplied by third-party plugins, Decode-Orc now
saves a root-level required_plugins block in the .orcprj file. Each entry
records the plugin identity, repository or release URL metadata, ABI
expectation, and the stage names from that plugin that are still used by the
project.
This block is refreshed every time the project is saved:
- Plugin entries are kept only if at least one of their stage names is still present in the current DAG
- Plugin metadata is refreshed from the current local plugin registry when available
- Stale entries are removed automatically if the corresponding plugin-backed stages were deleted while editing
If a project is opened on a machine where one of those stages is unavailable,
Decode-Orc uses the saved required_plugins metadata to give a more specific
missing-stage error that can point the user at the expected plugin and its
repository URL.
Creating Projects¶
Project files are typically created using orc-gui, but they can also be:
- Hand-edited (with care - see technical documentation)
- Generated programmatically
- Version controlled (recommended for reproducibility)
Project Compatibility¶
Projects created in the GUI can be executed in the CLI without modification. This ensures:
- Consistent results across interfaces
- Batch processing of GUI-created projects
- Easy integration into automated workflows
Common Use Cases¶
Batch Processing Multiple Files¶
Process multiple projects in a loop:
for project in *.orcprj; do
echo "Processing $project..."
orc-cli "$project" --process --log-level info
done
Automated Workflow¶
Integrate into a processing pipeline:
#!/bin/bash
set -e
# Process video
orc-cli capture1.orcprj --process --log-file capture1.log
# Check for errors
if [ $? -ne 0 ]; then
echo "Processing failed, check capture1.log"
exit 1
fi
# Continue with next step...
Monitoring Progress¶
Capture and monitor progress in real-time:
Error Handling¶
Common Errors¶
Project file not found:
→ Ensure the.orcprj file path is correct
Missing command:
→ Add the--process flag
Processing failure:
→ Check project file syntax and input file pathsFiltergraph parse error:
→ Check the filtergraph syntax near characterN; quote values containing
: , ; or spaces (single or double quotes both work)
Unknown stage:
→ Use a stage name that exists in your buildStage used in the wrong triad category:
--source: stage 'video_sink' (Video Sink) is an output (sink) stage — it
belongs under --sink, not --source.
Missing required parameter:
→ Supply the parameterCannot export — no video format:
Cannot export: none of the stages used imply a video format (NTSC/PAL/PAL-M),
so the saved project would fail to reload. Pass --video-format NTSC|PAL|PAL-M,
or run the pipeline directly instead of exporting.
--video-format, or add a format-specific source stage to the graph
Cannot export — no source signal type:
Cannot export: none of the stages used imply a source signal type
(composite/Y-C), so the saved project would fail to reload. Pass
--source-type composite|yc, or run the pipeline directly instead of
exporting.
--source-type, or ensure a source stage's parameters reveal its
signal type (y_path+c_path, or input_path)
Crash Diagnostics¶
If orc-cli crashes unexpectedly, it automatically creates a diagnostic bundle containing:
- System information (OS, CPU, memory)
- Stack backtrace showing crash location
- Application logs
- Core dump file (when available)
The crash bundle is saved as a ZIP file in the current working directory, on Linux, macOS and Windows alike:
When reporting issues, attach this bundle to your bug report on GitHub Issues.
See Issue Reporting for full details of the bundle
contents and the locations used by orc-gui.