marzeq/vedit
clone
Language reference
vedit programmes are postfix: literals and sources push values, while operations consume values
from the top of the stack and push results. Signatures below show the stack from left to right,
with the rightmost value at the top. For example, VIDEO DURATION -> VIDEO means that the duration
is popped first, followed by the video.
Comments begin with # outside a quoted path. Each source, literal, or operation occupies one line.
Value types
| Type | Meaning |
|---|---|
VIDEO |
A video stream that can be edited independently. |
AUDIO |
An audio stream that can be edited independently. |
COMBINED |
A value containing separate video and audio streams. Editing either requires extracting it first. |
SUBTITLES |
A subtitle input suitable for attaching to a combined result. |
DURATION |
A non-negative time value in seconds internally. |
SCALAR |
A finite floating-point number used for volume and speed. |
BOOL |
A compile-time Boolean used by logic and structured control flow. |
Sources and literals
| Form | Signature | Description |
|---|---|---|
video "path" |
() -> VIDEO |
Push the first video stream from an input. |
audio "path" |
() -> AUDIO |
Push the first audio stream from an input. |
combined "path" |
() -> COMBINED |
Push separate video and audio streams from one input. |
subtitles "path" |
() -> SUBTITLES |
Push a subtitle input. |
duration 5s |
() -> DURATION |
Push seconds. Decimals are accepted. |
duration 250ms |
() -> DURATION |
Push milliseconds. |
duration 01:23.500 |
() -> DURATION |
Push a minutes:seconds duration. |
scalar 0.7 |
() -> SCALAR |
Push a finite floating-point value. |
true |
() -> BOOL |
Push true. |
false |
() -> BOOL |
Push false. |
Paths must be quoted and may contain spaces or # characters.
Quoted strings support positional interpolation: video "$1" substitutes the first script
argument, while video "clips/$2.mp4" inserts the second argument into a larger string. $0 and
references to missing arguments are rejected. Source paths must remain quoted.
Stack operations
| Operation | Signature | Effect |
|---|---|---|
dup |
A -> A A |
Duplicate the top value. |
drop |
A -> () |
Discard the top value. |
swap |
A B -> B A |
Exchange the top two values. |
over |
A B -> A B A |
Copy the second value to the top. |
rot |
A B C -> B C A |
Rotate the third value to the top. |
A, B, and C may be values of any type. Duplicated media is automatically routed through an
FFmpeg split or asplit only when multiple reachable consumers require it.
Combined media
| Operation | Signature | Description |
|---|---|---|
get-video |
COMBINED -> VIDEO |
Extract only the video stream. |
get-audio |
COMBINED -> AUDIO |
Extract only the audio stream. |
split |
COMBINED -> VIDEO AUDIO |
Extract both streams, with audio on top. |
mux |
VIDEO AUDIO -> COMBINED |
Combine independently edited video and audio. Ordering is strict. |
attach |
COMBINED SUBTITLES -> COMBINED |
Attach and map subtitles to the output. |
Extracting or editing one stream never modifies the other stream in a COMBINED value.
Time and stream editing
These operations accept either video or audio where shown, but never subtitles or combined values.
| Operation | Signature | Description |
|---|---|---|
length |
VIDEO -> DURATION |
Push the known video duration. |
AUDIO -> DURATION |
Push the known audio duration. | |
COMBINED -> DURATION |
Push the longer known video/audio duration. | |
slice |
VIDEO START LENGTH -> VIDEO |
Keep LENGTH beginning at START and reset timestamps. |
AUDIO START LENGTH -> AUDIO |
Audio form of slice. |
|
take |
VIDEO LENGTH -> VIDEO |
Keep at most the first LENGTH. |
AUDIO LENGTH -> AUDIO |
Audio form of take. |
|
concat |
VIDEO VIDEO -> VIDEO |
Append the second video to the first. |
AUDIO AUDIO -> AUDIO |
Append the second audio to the first. Mixed types are rejected. | |
delay |
VIDEO DURATION -> VIDEO |
Shift video timestamps later. |
AUDIO DURATION -> AUDIO |
Insert an audio delay. |
length fails at compilation if no duration can be determined. Source durations come from ffprobe;
edited durations are propagated without creating temporary media.
Audio operations
| Operation | Signature | Description |
|---|---|---|
volume |
AUDIO SCALAR -> AUDIO |
Multiply audio volume by the scalar. |
mix |
AUDIO AUDIO -> AUDIO |
Mix two streams; the result lasts as long as the longer input. |
silence |
DURATION -> AUDIO |
Generate stereo 48 kHz silence of the requested duration. |
Speed and fades
| Operation | Signature | Description |
|---|---|---|
speed |
VIDEO SCALAR -> VIDEO |
Change video speed using timestamps. |
AUDIO SCALAR -> AUDIO |
Change audio speed using one or more atempo stages. |
|
fade-in |
VIDEO DURATION -> VIDEO |
Fade video in from the start. |
AUDIO DURATION -> AUDIO |
Fade audio in from the start. | |
fade-out |
VIDEO DURATION -> VIDEO |
Fade video out over the final duration. |
AUDIO DURATION -> AUDIO |
Fade audio out over the final duration. |
Speed must be greater than zero. Fades preserve stream duration. fade-out requires a known input
duration so its start time can be calculated.
Arithmetic and comparisons
| Operation | Signature | Description |
|---|---|---|
add |
SCALAR SCALAR -> SCALAR |
Add scalars. |
DURATION DURATION -> DURATION |
Add durations. | |
sub |
SCALAR SCALAR -> SCALAR |
Subtract the right scalar from the left. |
DURATION DURATION -> DURATION |
Subtract durations; a negative result is rejected. | |
mul |
SCALAR SCALAR -> SCALAR |
Multiply scalars. |
DURATION SCALAR -> DURATION |
Scale a duration. | |
div |
SCALAR SCALAR -> SCALAR |
Divide scalars. |
DURATION SCALAR -> DURATION |
Divide a duration by a scalar. | |
eq, ne |
T T -> BOOL |
Test equality or inequality for matching SCALAR, DURATION, or BOOL values. |
lt, le, gt, ge |
T T -> BOOL |
Compare matching SCALAR or DURATION values. |
and, or |
BOOL BOOL -> BOOL |
Boolean conjunction or disjunction. |
not |
BOOL -> BOOL |
Boolean negation. |
T must be the same type on both sides. Media values are not comparable. Division by zero,
non-finite arithmetic, and negative duration results are rejected.
Conditionals
Conditionals use structured if, optional else, and end markers:
video "$1"
dup
length
duration 10s
gt
if
duration 10s
take
else
# The original video remains unchanged.
end
if consumes a BOOL. Both branches begin with the same remaining stack and must leave identical
stack types. Both branches are typechecked, but only the selected branch is compiled, probed, and
added to the FFmpeg graph. Omitting else is equivalent to an empty false branch, so the true branch
must preserve the stack shape in that case.
Conceptually, if both branches transform S into T:
S BOOL if ... else ... end -> T
Unrollable loops
Loops use Forth-style begin, while, and repeat markers:
video "$1"
scalar 0
begin
dup
scalar 3
lt
while
swap
duration 1s
take
swap
scalar 1
add
repeat
drop
At begin, let the current stack shape be S. The condition section must transform S into
S BOOL. while consumes that Boolean. The body must transform S back into exactly S before
repeat. When the condition becomes false, the loop leaves S on the stack.
Loops execute during compilation and are fully unrolled into the FFmpeg graph. Consequently, every condition must be computable from literals, arithmetic, Boolean operations, and known probed media durations. There is no frame-time or sample-time control flow. A loop that attempts more than 10,000 iterations is rejected.
Programme result
A valid programme must leave exactly one VIDEO, AUDIO, or COMBINED value on the stack.
SUBTITLES, DURATION, SCALAR, and BOOL cannot be final results. A combined result maps video
and audio separately; attached subtitles are mapped as an additional output stream.