Skip to main content

Merge

Combine several inputs into one output — concatenate videos, stitch audio, or build an image slideshow. merge() accepts 2–10 inputs; each unique file is uploaded once.

Audio formats

Accepted
audio/aac · audio/flac · audio/mpeg · audio/ogg · audio/wavStable

🔴 merge does NOT accept audio/mp4, though compress and convert both do. That is the clearest case of why the audio sets are per-operation rather than global: a file you can compress is not necessarily one you can merge. Call getSchema() for the authoritative set at runtime.

File-first — combine in order

files([...]).merge(...) is the shortest path: the list is the set of inputs being combined, and array order is play order.

const result = await client
.files(['./intro.mp4', './body.mp4', './outro.mp4'])
.merge({ transition: 'crossfade', crossfadeDuration: 0.5 })
.run({ maxWait: '10m' });

await result.toFile('full-video.mp4');

Chain operations after merge() and they run on the single merged output in the same job. For large clips, use submit() to upload and create the workflow without blocking on the encode — it returns a handle you wait on later.

Image merge (slideshow)

Image merges build a video or GIF and require an output type:

const result = await client
.files(['./1.jpg', './2.jpg', './3.jpg'])
.merge({ mediaKind: 'image', output: 'video', durationPerImage: 2.0, fps: 24 })
.run({ maxWait: '10m' });

Image merges also accept loopCount and, for GIF output, a frame delay (milliseconds between frames). Video merges accept reEncodeMode ('auto' / 'always' / 'never') and targetResolution ('WxH', e.g. '1920x1080') in addition to codec / crf / preset — those re-encode knobs are only honoured when the worker re-encodes (auto / always), and the server validates that dependency.

Options that do not apply to the resolved media kind are dropped automatically.

See also

  • Archive — bundle files into a zip instead of merging them.
  • Errors — handling failures.