Video Export
Writes EXR and GIF, and not one movie codec
- frames
- frames
- frame_count
- export_report
The first thing to know is what this node is not. It is not a video writer. The description says it outright: "No movie codecs: use a video writer node." So if you came here to make an MP4, you want ComfyUI's own Save Video / video combine node, or the pack's Write nodes - not this one.
What it does instead is the finishing half of a VFX-style pipeline: pass frames through, encode them to an HDR signal, write a 32-bit float EXR sequence, or spit out a small GIF preview.
The four modes
mode is the whole node:
passthrough- returns the frames. Useful as a labelled waypoint at the end of a graph.hdr_decode- runs the pack's Video HDR Decode internally (Reinhard tonemap, PQ out) and returns the HDR signal. Note the output is always PQ here: the tooltip forhdr_metadata_jsonsays itspeak_nitsandgamutare used, "the eotf key is ignored."exr_sequence- writes files. 32-bit float, values unchanged, named<prefix>_<6-digit frame>.exr.preview_gif- writes<prefix>_preview.gif, clamped to 0–1 display-referred, and overwritten on each run.
Only the last two touch disk. That's a small but important detail: passthrough and hdr_decode are free of side effects, so you can leave them in a graph.
The settings
output_folder - empty means ComfyUI's output folder.
filename_prefix (default radiance_video) - the file-name stem, not a path.
fps (default 24) - GIF playback rate only; the frame duration written is 1000 / fps ms. It has no effect on the EXR sequence, which has no frame rate at all.
frame_offset (default 0, EXR mode only) - added to the frame number in the file names. This is the widget that makes the node usable in a real pipeline: you're writing frames 1001–1050 of a shot, not frames 0–49, and every downstream conform expects the real numbers. Set it once and your sequence drops into a timeline.
hdr_metadata_json (default {"peak_nits":1000,"eotf":"PQ (ST.2084)"}) - read only in hdr_decode.
Outputs: frames, frame_count and export_report.
Why EXR float matters
An EXR sequence written here keeps its values exactly - the tooltip says the write is unchanged, no colour conversion. That's the whole point of the format in this context: if you've gone to the trouble of expanding an SDR frame to a linear signal with highlights above 1.0, an 8-bit PNG throws it away, and even a 16-bit integer format quietly clamps and quantises it. Float EXR is what a Nuke or Resolve handoff expects, and it's what the pack's own Write nodes and the wider colour-management ecosystem are built around.
The GIF, by contrast, is a review artifact and only that. 256 colours, clamped, one file overwritten each run. It's genuinely useful for pasting a clip into a chat window, and it is not an output.
One thing you will not get in the EXR files: embedded generation metadata. That's a PNG convention (ComfyUI writes the prompt and workflow into PNG text chunks, which is what makes sharing a "workflow included" image work at all), and it doesn't travel into EXR here. If your delivery needs provenance, keep the PNG or a sidecar.
Install
- ComfyUI Manager → search Radiance → Install → restart → refresh the browser.
- Or:
cd ComfyUI/custom_nodes
git clone https://github.com/fxtd-studios/radiance.git
cd radiance
python -m pip install -r requirements.txt
Windows portable users: run the pip line with python_embeded\python.exe. EXR writing is the reason the pack pulls in OpenEXR, OpenImageIO and tifffile, and its install.py checks the first two after a Manager install. On Python 3.14 there's no OpenEXR wheel, and EXR I/O falls back to OpenImageIO - which is a perfectly good path, but it explains why the dependency looks conditional in requirements.txt. RADIANCE_ALLOW_DOWNLOADS=0 disables model fetching generally; this node needs no models.
Gotchas
The GIF is silently replaced every run, so if you were keeping a few versions, you weren't. And with frame_offset at 0 your first frame is ..._000000.exr, which some tools will happily import at frame 0 and others will refuse to match to a 1001-based conform - set the offset and you never have that conversation.
Finally: EXR sequence plus a long clip equals a lot of disk. At 4K 32-bit float you're looking at tens of megabytes per frame, and the pack's own known-issues notes are candid that long clips hold many full-size buffers in RAM; plan the disk as well as the VRAM.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| frames | IMAGE | Decoded frames. EXR writes the values unchanged as 32-bit float; the GIF clamps to [0, 1] display-referred. | |
| mode | COMBO | passthrough | passthrough: return frames. hdr_decode: run RadianceVideoHDRDecode (Reinhard, PQ out) and return the HDR signal. exr_sequence / preview_gif: also write files. Only the last two write to disk. |
| hdr_metadata_jsonopt | STRING | {"peak_nits":1000,"eotf":"PQ (ST.2084)"} | hdr_decode only. Its peak_nits and gamut (BT.2020 if absent) are used; the eotf key is ignored, output is always PQ. |
| output_folderopt | STRING | Empty: ComfyUI's output folder. | |
| filename_prefixopt | STRING | radiance_video | File name start: <prefix>_<6-digit frame>.exr, or <prefix>_preview.gif (overwritten on each run). |
| fpsopt | FLOAT | 24.001–120 | GIF playback rate (frame duration 1000 / fps ms). preview_gif only. |
| frame_offsetopt | INT | 0 | Added to the frame number in EXR file names. exr_sequence only. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| frames | IMAGE | — |
| frame_count | INT | — |
| export_report | STRING | — |