Native macOS CLI and Framework for professional video encoding, HDR color conversion, dynamic metadata processing, MOV/MP4/MXF mastering, linked timeline workflows, batch encoding, and external-audio replacement.
MOV remains the default container. HEVC and AV1 can also be written to MP4
with -ef mp4 or simply by giving -o a .mp4 filename. --outupt-video-raw
(-ovr) writes the final encoded video elementary stream; Dolby Vision Profile
7.6 writes its required separate BL and EL HEVC streams.
- Correct PQ source-peak fallback when static mastering metadata is absent, so a 10,000-nit ST 2084 signal is tone-mapped correctly to the requested target luminance.
This project is licensed under the GNU Affero General Public License v3.0 for general public use. See LICENSE.
A designated commercial-license grant may be provided in the LICENSE file for specific organizations and their eligible subsidiaries or controlled affiliates. That grant applies only to source code owned by this project.
The AV1 encoder integration uses the bundled SVT-AV1 library. AAF interchange uses the bundled AAF Framework. Their files and license terms remain separate from project-owned source code.
The project license and any designated commercial-license exception do not relicense those bundled dependencies.
- macOS with standard command-line build tools installed.
- Project build support for the included project file.
- Bundled project-owned framework directories kept in their expected locations.
- Self-contained runtime behavior; the CLI does not require users to install separate external command-line media tools for normal operation.
xcodebuild -project "prores encoder.xcodeproj" \
-scheme "prores encoder" \
-configuration Release buildThe Release binary is written to:
Build/Release/prores encoderOptional local install:
cp "Build/Release/prores encoder" ~/bin/proresencoderThe CLI embeds its Metal kernel fallback in the Mach-O binary, so the executable
can be copied by itself without a neighboring default.metallib or helper
program.
The ProResEncoderFramework target builds the same native Swift/C++/GPU
encoding pipeline as the CLI:
xcodebuild -project "prores encoder.xcodeproj" \
-scheme ProResEncoderFramework \
-configuration Release buildThe framework is written to:
Build/Release/ProResEncoderFramework.framework
Its public API supports MOV, MXF OP-1a, and MXF OP-Atom output, including the same gamut, transfer-function, and peak-luminance conversion used by the CLI:
import ProResEncoderFramework
let encoder = ProResEncoder()
let options = ProResEncodeOptions(
quality: "422hq",
forcedOutputStartTimecode: "01:00:00:00",
colorConversion: ProResColorConversion(
gamut: .rec709,
transferFunction: .gamma24,
targetPeakNits: 100
)
)
try await encoder.encode(
inputURL: inputURL,
outputURL: outputURL,
options: options
)The framework also embeds the Metal kernel fallback in code. A bundled
default.metallib remains compatible with older layouts, but framework clients
do not need to copy a GPU library or invoke helper programs separately.
Set the Framework codec-tag option to true only when the target workflow
requires the alternate dynamic-HDR sample entry; its default should remain
false for normal output.
Set ProResEncodeOptions.deleteSourceAudio to true to omit input audio.
It can be combined with extraAudioURL so the source audio is removed before
the external track is added.
Framework clients can also fan one input out to independently encoded raw video
streams. Unlike ProResEncodeOptions.outputVideoRaw / CLI -ovr, this method is
multi-format and raw-only: its temporary MOV staging files are deleted, and the
result contains only .prores, .hevc, or .obu artifacts. Profile 7.6 returns
separate base-layer and enhancement-layer files.
let rawResult = try await encoder.encodeVideoElementaryStreams(
inputURL: gradedMasterURL,
outputDirectoryURL: deliveryDirectoryURL,
options: ProResElementaryStreamOptions(
formats: ProResElementaryStreamFormat.allDolbyVision,
dolbyVisionXMLURL: dolbyVisionXMLURL,
hevcBitrateMbps: 50,
profile76BitrateMbps: 80,
av1BitrateMbps: 50,
dolbyVisionGamut: .rec2020,
targetPeakNits: 1_000
)
)ProResElementaryStreamFormat.allStandard includes every ProRes variant plus
plain HEVC and AV1 and is the default. allCases adds every Dolby Vision
profile, which requires dolbyVisionXMLURL. This batch API is Framework only;
the CLI intentionally has no equivalent multi-format option.
- MOV is the default container; MP4 is available for HEVC and AV1 only.
- Source decode for compressed inputs uses native media sessions plus project pixel conversion and chroma downsampling.
- Dynamic HDR metadata generation and writing are implemented in project code, then packaged into the selected output bitstream or metadata track.
- Enhanced-layer workflows perform closed-loop base-layer encode and reconstruction, derive a residual signal on the GPU, encode the enhanced layer, and interleave metadata directly into output samples.
- CLI encoding emits no separate elementary-stream files unless
--outupt-video-raw(-ovr) is explicitly requested. Framework clients may instead use the raw-only multi-format batch API described above.
Final compressed samples are inspected before the file is accepted:
- HEVC output uses a verifier-oriented sample entry by default, including streams carrying dynamic HDR metadata.
- AV1 output similarly uses a verifier-oriented sample entry by default.
- Pass
--dv-flag/-dfonly when an explicit alternate dynamic-HDR sample entry is required. - A requested dynamic HDR metadata encode fails instead of returning a file if the finalized stream contains no requested metadata.
proresencoder -i input.mov -o output.movSet output quality:
proresencoder -i input.mov -q 422hq -o output.mov
proresencoder -i input.mov -q 4444xq -o output.movSupported quality values:
proxy, 422lt, 422, 422hq, 4444, 4444xq, pass, hevc, av1
Use pass when you want a stream copy where supported:
proresencoder -i input.mov -q pass -o output.movThe three target-color options are atomic: all three must be present, or encoding is refused.
proresencoder -i hdr.mov -o sdr.mov -q 422hq \
--gamut rec709 \
--oetf gamma2.4 \
--nit 100Supported targets:
--gamutor--color-spacerec709|rec2020|rec2020lm|p3d65--oetf gamma2.4|gamma2.6|pq|hlg--nit <target peak nits>, from 1 through 10000
The source gamut and transfer function are read from the input video metadata. Rec.709, Rec.2020, and P3-D65 sources with Gamma 2.4, Gamma 2.6, PQ, or HLG are supported. Pixel processing runs on the GPU before ProRes/HEVC/AV1 submission; there is no CPU color-conversion fallback.
--nit controls the actual pixel luminance mapping. Already-mastered programme
material is mapped with a display-referred EETF-style curve and a matched
inverse for range expansion. This provides one monotonic mapping for HDR-to-SDR,
SDR-to-HDR, HDR-to-HDR, and SDR-to-SDR conversions. Equal source/target peaks
remain colorimetric; different peaks preserve tonal separation while mapping
the detected source peak to the requested target peak.
When these options are omitted, the encoder keeps its previous behavior and does not perform color conversion or tone mapping.
--gamunt was the original misspelled option. It remains accepted for backward
compatibility and prints a deprecation warning.
Burn a .cube LUT into the encoded pixels with the LUT's declared output color
space. LUT processing uses the built-in parser and GPU texture sampling without
invoking a separate media-processing executable.
proresencoder -i input.mov -o graded.mov -q 422hq \
--lut look.cube \
--gamut-lut rec709 \
--oetf-lut gamma2.4 \
--nit-lut 100--color-space-lut is an alias for --gamut-lut. The LUT form supports 1D,
3D, and combined 1D+3D .cube files, including TITLE, comments,
DOMAIN_MIN, DOMAIN_MAX, LUT_1D_INPUT_RANGE, and LUT_3D_INPUT_RANGE.
The 1D table is applied first, followed by the 3D table with Metal linear
sampling. --lut and its three *-lut target options are atomic and cannot
be combined with direct --gamut/--color-space, --oetf, and --nit
mapping. LUT burn-in is also rejected with Dolby Vision XML/RPU metadata,
because those metadata must be generated from the graded pixels.
Generate an analyzed XML sidecar:
proresencoder -i hdr.mov -o prores.mov -q 422hq --cmu 1000For ProRes/MXF output, metadata analysis writes only the .xml sidecar; it does
not create JSON or Markdown log files. HEVC/AV1 output can use a temporary XML
internally and remove it after encoding.
Add --cmu-include to use the generated XML directly as the native metadata
source. Do not also pass an external metadata XML:
# ProRes MOV: remux the encoded video with a metadata track
proresencoder -i hdr.mov -o prores_metadata.mov -q 422hq \
--cmu 1000 --cmu-include
# HEVC Profile 8.1: generate and inject one metadata unit per frame
proresencoder -i hdr.mov -o hevc_metadata.mov -q hevc -b 50 -dp 81 \
--cmu 1000 --cmu-include
# HEVC Profile 5: convert Rec.2020/PQ to Native IPT-PQ-C2 with Metal
proresencoder -i hdr.mov -o hevc_native_p5.mov -q hevc -b 50 -dp 5 \
--gamut rec2020 --oetf pq --nit 1000 \
--cmu 1000 --cmu-include
# HEVC enhanced-layer workflow
proresencoder -i hdr.mov -o hevc_enhanced.mov -q hevc -b 80 -dp 76 \
--cmu 1000 --cmu-include
# AV1 Native Profile 10: full-range IPT-PQ-C2 plus T.35/EMDF RPU
proresencoder -i hdr.mov -o av1_native_p10.mov -q av1 -b 50 -dp 10 \
--gamut rec2020 --oetf pq --nit 1000 \
--cmu 1000 --cmu-include
# AV1 Profile 10.1: HDR10-compatible base layer
proresencoder -i hdr.mov -o av1_p101.mov -q av1 -b 50 -dp 101 \
--cmu 1000 --cmu-includeAdd --dv-flag / -df only when an explicit alternate dynamic-HDR sample entry is
required by the target workflow:
proresencoder -i hdr.mov -o hevc_metadata.mov -q hevc -b 50 -dp 81 \
-dovi metadata.xml --dv-flag
proresencoder -i hdr.mov -o av1_metadata.mov -q av1 -b 50 -dp 101 \
-dovi metadata.xml -dfProfile arguments are strict integers: -dp 5 is HEVC Profile 5, -dp 10
is Native AV1 Profile 10, -dp 101 is Profile 10.1, and -dp 104 is Profile
10.4. Decimal aliases such as 10.1 and the former 100 alias are rejected.
Profile 5 and Native Profile 10 accept only direct rec2020, rec2020lm, or
p3d65 output together with pq and --nit. The declared PQ reference pixels
are then converted to full-range IPT-PQ-C2; they are not tagged or encoded as an
HDR10 base layer. Without -df, P5/P10 keep the ordinary hvc1/av01 sample
entry for verifier compatibility. -df changes only the reserved player-facing
sample entry to dvh1/dav1; it does not alter pixels, RPU, or bitstream
processing. These additions target stream, color, RPU/EMDF, and container
conformance.
--cmu and -dovi are mutually exclusive.
--cmu-include requires --cmu, supports MOV or compressed MP4 output, and requires the
matching -dp value for HEVC or AV1. For HEVC/AV1, the internally generated
XML is converted to one native metadata unit per frame and injected during the
encode; for ProRes it is embedded as a metadata track.
MOV:
proresencoder -i input.mov -ef mov -q 422hq -o output.mov
proresencoder -i input.mov -ef mov -q hevc -b 50 -o output_hevc.mov
proresencoder -i input.mov -ef mov -q av1 -b 50 -o output_av1.mov
proresencoder -i input.mov -ef mp4 -q hevc -b 50 -o output_hevc.mp4
proresencoder -i input.mov -q av1 -b 50 -o output_av1.mp4 # infers MP4The CLI defaults to .mov and normalizes an explicit -ef mov output to that
extension. -ef mp4, or a .mp4 -o filename when -ef is omitted, selects
MP4; MP4 accepts HEVC and AV1 only. -ovr writes *_raw.prores,
*_raw.hevc, or *_raw.obu next to the container. With HEVC Dolby Vision
Profile 7.6 it instead writes *_P7_6_BL.hevc and *_P7_6_EL.hevc.
MOV timecode behavior:
- If the source already contains a MOV timecode track, the output MOV keeps that source timecode.
- If the source has no MOV timecode track, the output MOV writes a synthetic timecode track.
- The default synthetic start timecode is
01:00:00:00. - Use
-ffoato override that synthetic start value when needed.
Example:
proresencoder -i input.mov -ef mov -q 422hq -ffoa 10:00:00:00 -o output.movMXF OP-1a:
proresencoder -i input.mov -ef op1a -q 422hq -o output_dirMXF OP-Atom:
proresencoder -i input.mov -ef opatom -q 422hq --audio-ch-per-file 1 -o output_dirUse -aa to add an external audio track. The encoder accepts audio readable
through the native runtime, including common PCM and compressed audio formats.
MOV-compatible codecs are muxed where supported; inputs that require conversion
use an explicit channel layout.
Add --audio-replace / -ar, or combine -aa with
--delete-source-audio / -dsa, to drop source audio and keep only the
supplied track.
proresencoder \
-i input.mov \
-q 4444xq \
-aa audio_if_needed.wav \
--audio-replace \
-ef mov \
-o output.movShort form:
proresencoder -i input.mov -q 4444xq -aa replacement_7_1.wav -ar -o output.mov
proresencoder -i input.mov -q pass -dsa -aa external_audio.ec3 -o output.mov
proresencoder -i input.mov -q pass -dsa -o silent_output.movSafety rules:
--audio-replace/-arrequires-aa <audio_file>.--delete-source-audio/-dsadoes not conflict with-aa; deletion is applied first, then the external audio is added.- Unknown arguments stop the process with an error.
- Missing argument values stop the process with an error.
- MXF output accepts
-aawhen replacement or source-audio deletion is enabled.
proresencoder -if input_folder -ef mov -q 422hq -o output_folderBatch mode writes one output per supported input file.
Bounce an XML timeline to MOV:
proresencoder -xml timeline.xml -o output_folderConvert supported timeline documents:
proresencoder -i timeline.xml -trans AAF -o sequence.aaf
proresencoder -i sequence.aaf -trans XML -o sequence.xmlAdd a media relink path:
proresencoder -i sequence.aaf -trans XML \
--media-search-path /path/to/media \
-o sequence.xmlGenerate one linked AAF for an MXF encode:
proresencoder -i input.mov -ef op1a -q 422hq --export-aaf -o output_dirGenerate one linked AAF per clip in batch mode:
proresencoder -if input_folder -ef opatom -q 422hq --export-aaf-all -o output_dir- The CLI prints explicit errors for unsafe argument combinations.
-aris replacement mode, not an additive mix mode.- MOV replacement output should contain only the replacement audio stream plus video and timecode/metadata tracks.
- Generated files and bundled dependency files retain their own notices.