Skip to content
streamneo.
Tools12 min read

How to Use FFmpeg with Open Job Description for Video Workflows

Build an OpenJD job that runs FFmpeg: define parameters, validate a one-step encode, then connect rendering and video creation.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

Open Job Description (OpenJD) describes a batch job; FFmpeg does the media processing when that job invokes it. You can start with a parameterised encode, validate the template with the OpenJD CLI, and then extend the same idea into a render-then-encode workflow.

The important distinction is practical: a job template declares inputs, outputs, steps and executable actions, but it does not encode video or install FFmpeg. Your chosen runtime must already provide FFmpeg and any other software the actions need.

Keep the job definition separate from media processing

OpenJD is a specification for describing batch jobs in a way intended to be portable between scheduling deployments. It lets you express work as parameters, steps and actions. FFmpeg is a command-line media application: it reads media inputs, applies options and writes outputs. The template connects those roles by telling the job runner which FFmpeg command to invoke and with what arguments.

That separation helps you decide where to look when something fails. If a template has a misspelled parameter reference or an invalid dependency, inspect the job definition. If FFmpeg reports an unsupported codec, an unreadable input or a malformed command, inspect the executable, its environment and the command line. A valid job description is not proof that its media command will succeed.

The OpenJD specifications repository describes the format and its portability goal. Portability applies to the job description, not to every detail of the runtime. Two schedulers can interpret a valid job in environments with different installed programs, file access rules or storage arrangements. Before moving a job between systems, check what executables and input files will be available there.

This is also why an OpenJD template does not install FFmpeg. It can describe an action that calls ffmpeg, but the executable must be present in the environment where that action runs, and the process must be able to read its inputs and write its outputs. Treat environment preparation and job design as related but separate tasks.

Prepare the FFmpeg environment

First, choose where you intend to validate and run the job. For a local test, that may be a machine on which FFmpeg and the OpenJD CLI are available. In a scheduler deployment, the runtime or worker environment needs the executable, any other tools in the workflow, and access to the files named by the job. The OpenJD CLI documentation describes local checking and execution; it does not establish what a particular scheduler will install or mount for you.

Check the executable directly before involving the template. Run ffmpeg -version in the environment that will execute the action, then use the same shell or execution context to verify that your input path exists and that the intended output directory is writable. A command that works in an interactive terminal may still fail in a job if it depends on a different working directory or environment variable.

Keep paths explicit. A template may run its generated script in a temporary working directory. The AWS walkthrough points out that a relative output such as ./output.mp4 can land in that temporary space and be removed when the execution environment is cleaned up. Pass a durable output directory as a parameter instead, then confirm that the directory exists or that the job has a deliberate way to create it.

Do not assume that naming an output parameter makes the directory appear. Decide whether the directory is prepared before the job, created by a preceding action, or created by the relevant step. Confirm how your target runner handles filesystem access and cleanup. This detail is runtime-specific, so test it where the job will actually run.

For a rendered image sequence, the environment also needs the renderer and the expected frame files. If a second step calls Blender, installing or making Blender available is separate from defining that step. The official Blender and FFmpeg sample makes a render step and a video-creation step distinct parts of its workflow.

Define parameters for a one-step encode

Begin with the smallest useful job: one input, one output location and one encode step. Parameters make paths visible at the job boundary rather than burying machine-specific locations in the command. A file input can be declared as an input path, and an output directory as an output path, then both values can be substituted into the action.

Here is a deliberately abbreviated shape:

specificationVersion: 'jobtemplate-2023-09'
name: FFmpeg Encode
parameterDefinitions:
  - name: InputFile
    type: PATH
    objectType: FILE
    dataFlow: IN
  - name: OutputDir
    type: PATH
    objectType: DIRECTORY
    dataFlow: OUT
steps:
  - name: Encode
    script:
      actions:
        onRun:
          command: ffmpeg
          args: ["-i", "{{Param.InputFile}}", "{{Param.OutputDir}}/output.mp4"]

This is an illustration of the relationship between parameters and an action, not a complete schema example for every implementation. Check the specification version and required fields supported by your OpenJD implementation, and use a complete template based on its documentation. The AWS OpenJD and FFmpeg walkthrough provides a fuller example pattern.

Choose parameter names that explain what a value represents. InputFile is clear for one file, but if your job consumes a numbered image sequence, name the parameter to convey that and document the filename pattern expected by the command. OutputDir makes it clear that the action constructs a filename beneath a directory. Avoid treating a path parameter as a guarantee that the runner has permission to read or write it.

Keep the first command deliberately simple. Begin with an input and output you can inspect, and verify that a manual FFmpeg invocation works in the same environment. Then move its arguments into the template. This isolates command problems from template problems and makes it easier to review the substitutions. Once the basic encode succeeds, add codec, pixel-format, metadata or container options needed for your material.

The AWS tutorial shows one set of choices for an image sequence, including a 24 fps input sequence, H.264 encoding, pixel format, colour metadata and MP4 fast-start behaviour. Those are choices in that example, not defaults for every source or delivery target. Your frame rate, codec, colour handling and container should come from the source material and the intended playback or platform requirements.

Add the FFmpeg executable action

An executable action is where the job hands work to a program. In the abbreviated template, command: ffmpeg names the executable and args supplies individual arguments. Keeping arguments as separate entries is useful because it makes ordering and parameter substitution easier to inspect than a single shell command string.

FFmpeg's command-line documentation explains its inputs, outputs and options. In general, options apply to the next input or output file named, so order is meaningful. For example, an input-side option belongs before the relevant -i input, while output-side encoding options are placed with the output they govern. If you take a command that works by hand and rearrange its arguments while templating it, you can change what the options mean.

Stream selection deserves attention when inputs contain more than one audio or video stream, subtitles, or unusual stream layouts. FFmpeg can select streams automatically according to its rules and the output format, but automatic selection may not match your intent. The -map option gives you explicit control. Inspect the actual input and make selection intentional when the file contains streams you do not want in the output.

Avoid adding shell features until you need them. A direct executable and argument list is easier to reason about. If your workflow needs a shell script for setup, directory creation or conditional logic, make those actions explicit and ensure the script's working directory and environment are understood. A template can invoke a script, but that does not remove the need to provide the script and its dependencies.

For a one-step encode, decide how you will identify a successful result. Check the job's exit status, confirm the output file exists in the intended durable location, and inspect or play the resulting media. A process finishing without a visible error is not by itself evidence that the output has the intended streams, duration, frame rate or colour appearance.

Validate and inspect with the OpenJD CLI

Use the OpenJD CLI before submitting a template to a scheduler. Its documented interface includes openjd check to validate a template, openjd summary to inspect its parameters, steps and tasks, and openjd run to run a job locally. Consult the CLI documentation for the commands and options supported by the release you have installed.

A useful sequence is to check the template, read the summary, and only then run a selected step with explicit parameter values. The summary is a chance to catch an unexpected parameter name or a step layout that differs from what you intended before FFmpeg is invoked. Supply the input and output values using the CLI's documented parameter options for your installed release rather than assuming a command from a different version will be identical.

For a multi-step job, the CLI documentation also describes selecting tasks and requesting dependency steps. That lets you exercise a portion of a workflow while respecting the declared relationship between steps. Use the actual CLI help or documentation for the exact syntax, and keep in mind that local success only demonstrates behaviour in the local environment you tested.

A local run is not a substitute for checking scheduler behaviour. Storage mounts, environment variables, executable paths and cleanup policies can differ in deployment. If the job will run remotely, repeat the relevant checks there: confirm the same inputs are visible, output paths persist where expected, and the correct FFmpeg build is callable. Record the environment assumptions alongside the template so another operator can reproduce them.

When a run fails, separate the evidence. First ask whether the CLI accepted the job structure and parameter values. Next check whether the action launched the intended executable. Finally inspect FFmpeg's diagnostic output and the resulting files. This order avoids changing encoding options to solve what is actually a missing path, or rewriting the job definition to compensate for an unsupported codec.

Add a dependent frame-rendering step

Once the one-step encode works, a render-then-encode workflow can express two distinct pieces of work: render frames, then use those frames as an input sequence for FFmpeg. The second step should depend on the render step so the job runner understands that encoding must not begin before the frames are ready.

The official Blender/FFmpeg sample uses this shape: a RenderScene step renders an animation, and a CreateVideoFromRender step depends on it and creates a video from the generated frames. Read the sample as a concrete example of step separation and dependency declaration, not as a guarantee that every scheduler stores or exposes artifacts in the same way.

Design the handoff explicitly. Decide where the renderer writes frames, how the next step locates them, what numbering or filename pattern FFmpeg expects, and where the final video should persist. If the two actions run in different environments or on different workers, the scheduler must make the frames available across that boundary. The job description can express the dependency, but deployment storage and transfer behaviour determine whether files are actually available.

This workflow is useful when rendering is expensive or when you need to inspect or reuse frames before encoding. It also gives you a clearer place to diagnose a failure: if frames are absent, inspect the render step and handoff; if frames exist but video creation fails, inspect the FFmpeg action and sequence arguments. The trade-off is additional workflow coordination and intermediate storage compared with encoding a supplied video file in one step.

The sample's requirements comment says it was tested with Blender 4.0.2 and FFmpeg 6.1.1. Those figures describe the sample's testing context, not current compatibility guarantees or universal recommendations. Check the versions and command behaviour in your own target environment before adopting a sample unchanged.

Produce video from rendered frames

For a numbered sequence, FFmpeg needs an input pattern that matches the rendered filenames and an appropriate input frame rate. Validate the pattern against actual files before launching the job. A sequence such as numbered PNG frames is not interchangeable with an arbitrary directory of images; naming gaps, different extensions or a mismatched starting number can prevent the input from being read as expected.

Keep the sequence input options in the correct position in the argument list, then provide output-side options and a durable output filename. An illustrative command shape might use an image-sequence input pattern and an MP4 output, but the exact pattern, rate and encoding settings depend on the renderer's output and delivery requirements. The FFmpeg manual is the primary reference for the syntax and behaviour of the options you select.

Do not infer that a successful encode means the output is suitable. Check frame count or duration against the render, inspect the first and last frames, listen to audio if the workflow includes it, and review the encoded file for the intended dimensions and playback behaviour. If audio or other streams are involved, state which streams should be included rather than relying on automatic selection without checking.

Keep rendered intermediates until you have confirmed the final video and established whether the workflow needs those frames again. Deleting them too early makes a failed encode more expensive to recover from; retaining them indefinitely consumes storage. Make the retention decision part of the workflow rather than an accidental consequence of a temporary directory.

If your final destination is a live channel rather than a rendered deliverable, encoding a file and operating a continuous broadcast are separate jobs. You still need to check YouTube's current requirements and arrange a runtime that can keep the broadcast going. For that separate operational question, see the guide to looping MP4 files in a YouTube live stream and the comparison of FFmpeg and OBS for an always-on stream. For longer-running operations, the monitoring guide for a remote YouTube stream covers a different concern from batch encoding.

When the repeated burden is keeping a source file broadcasting after the encode is done, StreamNeo removes the need to leave your own computer switched on to keep that YouTube stream running; it does not replace the OpenJD and FFmpeg steps used to create the file.

Before committing, compare the operating options on the pricing page. When the file and channel are ready, start free — 24-hour trial, no card.

FAQ

Does OpenJD encode video?

No. OpenJD describes the batch job and its actions; FFmpeg performs the media processing when an action invokes it. The environment running the action must provide FFmpeg and access to the files.

Does an OpenJD template install FFmpeg?

No. A template can name FFmpeg as an executable, but it does not install the program. Make the executable available in the local or scheduler environment where the job runs, and verify the path there.

Why parameterise the output directory?

A job may execute from a temporary working directory, so a relative output path can place the video somewhere that is later cleaned up. A parameter lets you direct the result to a known location, but you still need to confirm that location is writable and persistent in the target runtime.

Can I run a render step and an encode step separately?

Yes. OpenJD can describe a dependency so the encode step follows the render step, as shown in the Blender/FFmpeg sample. You must still ensure the rendered frames are available to the dependent step under the storage and transfer rules of your scheduler.

YOU’VE REACHED THE END

Keep the ideas coming.

More guides, useful tools and a little help for your next broadcast.

Back to the journal ↗
YOUR NEXT READ

A little more to explore.

More Tools guides ↗ · All topics ↗