Sora 2
OpenAI's video model without the API plumbing
- frameImages
- video
OpenAI's Sora 2 is a closed model. You can't download the weights, you can't quantize it, and no amount of VRAM will ever run it locally. So if you want Sora footage inside a ComfyUI workflow, your only option is an API - and that's precisely the job this node does. It turns Sora 2 into a single node that takes a prompt and hands you a VIDEO tensor on the other end, no OpenAI SDK, no signing code, no upload step.
This is the appeal of the whole Runware pack in miniature. You're not generating locally; the node ships your request to Runware's cloud, Sora renders there, and the result comes back as a native ComfyUI video. Your GPU sits idle the whole time. For a model like Sora 2 that's not a compromise - it's the only way.
How it works
Under the hood, Runware_openai_sora_2 is a thin generated wrapper. The pack's base node class sends a videoInference request (model AIR openai:3@1) over REST via the runware-sdk, downloads the returned video file, and wraps it in ComfyUI's VIDEO type. Any IMAGE you wire into frameImages gets base64-encoded and sent as starting frames. You're watching an API call from inside the node graph, and that's the whole trick.
The inputs that matter
Only one thing is required, and it's the obvious one:
positivePrompt- the text describing what to generate. This is Sora, so it can also express camera moves, cuts, and pacing ("slow push-in on a rain-soaked street" works far better than in most models).
The rest of the widget set is where you'll actually spend time:
duration- a dropdown from 4 to 20 seconds, or(default). Total frames = duration × the model's fps, so longer is not just longer, it's costlier per run.frameImages- wire in anIMAGEto start generation from existing frames (image-to-video or a lead-in).videoId- paste the ID of a video you already generated to remix or extend it. This is how you do continuation chains.width/height- defaults to 1024×1024; the model likes the common ratios, so don't go exotic unless you have a reason.numberResults- 1 to 4, each a variation on a different seed.
The safety.* toggles and outputFormat (MP4/WEBM/MOV) with outputQuality are self-explanatory; leave them alone until you need them.
Installing it
You don't install Sora 2 - you install the pack that hosts it. In ComfyUI Manager, search Runware, install, restart. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/Runware/ComfyUI-Runware
pip install -r ComfyUI-Runware/requirements.txt
Then create a key at runware.ai/api-keys and paste it into ComfyUI Settings → Runware API key (or set RUNWARE_API_KEY). No model files download - Sora 2 lives entirely in Runware's cloud.
Where people get burned
- No key, no run. The node fails with "No Runware API key" if you forget this step.
- It costs money, every run. The node title bar shows a per-run cost after each generation - this is metered cloud inference, not local sampling. A 20-second Sora render is not free.
- Latency. A video takes real time in the cloud. Don't queue 20 variations and wonder why your graph looks hung; it's not hung, it's waiting on Sora.
- Old ComfyUI versions may hand you a file path instead of a
VIDEOobject - update ComfyUI if the output socket looks wrong.
If you want Sora 2 but a lower price point for drafts, the same pack's Runware_openai_sora_2_pro is the bigger, more expensive tier. For everything else, this is the node.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| positivePrompt | STRING | Text prompt describing elements to include in the generated output. | |
| frameImagesopt | IMAGE | — | |
| sizeopt | COMBO | 720p (16:9) | Output size. Only one of resolution or dimensions is sent. |
| durationopt | COMBO | (default) | Length of the generated video in seconds. The total number of frames produced is determined by duration multiplied by the model's frame rate (fps). |
| numberResultsopt | INT | 11–4 | Number of results to generate. Each result uses a different seed, producing variations of the same parameters. |
| videoIdopt | STRING | ID of a previously generated video. Used for remixing or extending. | |
| safetyopt | BOOLEAN | false | Enable to set safety. Off uses the model's default. |
| safety.checkContentopt | BOOLEAN | false | Enable or disable content safety checking. |
| safety.modeopt | COMBO | fast | Safety checking mode for video generation. |
| ttlopt | BOOLEAN | false | Enable to set ttl. Off uses the model's default. |
| ttl_valueopt | INT | 60 | Time-to-live (TTL) in seconds for generated content. Only applies when `outputType` is `URL`. |
| outputFormatopt | COMBO | MP4 | File format for the generated video. |
| outputQualityopt | INT | 9520–99 | Compression quality of the output. Higher values preserve quality but increase file size. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| video | VIDEO | — |