Video editing proxy generation

Edit proxies for browser video editors

Turn heavy masters into small, scrub-friendly MP4 proxies with one API call. Pick the size and the keyframe interval; Xora runs the encode and tells you when it's done.

Why Browser Timelines Lag

Standard video codecs (like H.264/MP4) use temporal compression. To save space, they only store full image frames (Keyframes or I-frames) every few seconds, representing intermediate frames as differences between them (P-frames and B-frames).

When a user scrubs back and forth on a web-based video editing timeline, the browser’s video decoder has to decode multiple preceding frames just to render a single frame. This creates noticeable timeline lag, dropped frames, and a frustrating editing experience.

Standard Compression vs. Editing Proxies

Standard H.264 (Temporal)

Keyframe (I) Diff (P) Diff (P) Keyframe (I)

Laggy scrubbing: Decoders must recalculate differences between I-frames.

Xora Proxy Recipe (gop: "all_intra")

I-Frame I-Frame I-Frame I-Frame

Frame-accurate scrubbing: every frame is a keyframe, so the decoder never has to rebuild it from earlier frames.

Xora's Editing Proxy Recipe

The proxy recipe always re-encodes, and gives you the three settings that matter for editing.

  1. Keyframe interval

    The default is one keyframe per second (gop: "per_second"). Set gop: "all_intra" to make every frame a keyframe (-g 1) for frame-accurate seeking. Files get larger.

  2. Size and quality

    Set scaleDown with a height such as 480 or 720, then tune crf (default 32) or a target bitrateKbps. Or keep full resolution.

  3. Clip while you encode

    Add startSeconds and durationSeconds to build a proxy of just the section your editor needs. Output is always MP4.

FFmpeg Arguments Decoded

The recipe is a shortcut, not a ceiling. If you want full control, send the FFmpeg args yourself in ffmpeg mode — this is roughly what an all-intra 480p proxy looks like.

  • -g 1 / -keyint_min 1: Forces every frame to be a keyframe (intra-frame).
  • -vf "scale=-2:480": Downscales to 480p and keeps the aspect ratio.
  • -pix_fmt yuv420p: Ensures pixel format compatibility with HTML5 canvas and video elements.
  • -movflags +faststart: Relocates index metadata to the front of the file.
Manual FFmpeg mode equivalent
{
"mode": "ffmpeg",
"input_files": { "in_1": "https://example.com/master.mov" },
"output_files": { "out_1": "proxy.mp4" },
"ffmpeg": {
"args": [
"-i", "{{in_1}}",
"-vf", "scale=-2:480",
"-c:v", "libx264",
"-g", "1",
"-keyint_min", "1",
"-pix_fmt", "yuv420p",
"-crf", "26",
"-movflags", "+faststart",
"{{out_1}}"
]
}
}

Trigger a proxy from your upload handler

Call the proxy recipe when an upload lands, and take a webhook when the job reaches a terminal state.

Node.js upload webhook handler
const triggerProxyJob = async (videoUrl) => {
const response = await fetch('https://api.xora.sh/v1/jobs', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
mode: 'recipe',
input: { url: videoUrl },
output: { format: 'mp4' },
recipe: {
name: 'proxy',
scaleDown: true,
height: 480,
gop: 'all_intra'
},
webhookUrl: 'https://your-app.com/webhooks/xora'
})
});
return await response.json();
};

Ready to optimize your video timeline?

Start free — 25 credits a month, no credit card. A real 78-minute proxy job used about 21 credits.

Frequently asked questions

What is a video editing proxy?

A smaller copy of the original video that an editor uses in place of the master while you cut. It has a lower resolution and more keyframes, so the timeline scrubs smoothly. The final export still uses the original file.

Why do proxies need more keyframes?

To show a frame, a decoder must start from the keyframe before it. With one keyframe every few seconds, each jump on the timeline decodes many frames first. With all-intra proxies (every frame a keyframe) or one keyframe per second, seeking is fast.

How do I generate proxies with an API?

Send the master URL to Xora with the proxy recipe, for example scaleDown true, height 480 and gop all_intra. Add a webhookUrl to know when the proxy is ready, and startSeconds and durationSeconds to make a proxy of one part of the file.

Are all-intra proxies large?

Larger than proxies with one keyframe per second at the same quality. Use all_intra for frame-accurate editing and per_second for review and rough cuts. A lower height and a higher CRF keep the size down.