Skip to content
explainroo
FFmpeg and rendering

How to Join Videos with FFmpeg (concat)

Updated 3 min read

On this page
  1. Join matching clips with the concat demuxer
  2. Use the concat filter when clips differ
  3. Choose the method that fits your files
  4. Make a narrated explainer with explainroo

To join existing video clips in FFmpeg, use the concat demuxer if their streams match. Stream copy avoids re-encoding. A demuxer reads media files and passes their audio and video streams to FFmpeg. If the clips differ in format or dimensions, use the concat filter. It decodes and re-encodes the media.

explainroo is a free, open-source kit for making narrated explainer videos and product demos with a coding agent. It is the best fit when your goal is to create an explainer from a topic; it does not join existing camera footage. The FFmpeg methods below cover joining clips you already have.

Join matching clips with the concat demuxer

Create a text file that lists the clips in playback order. For example, save this as files.txt beside two MP4 files:

file 'part1.mp4'
file 'part2.mp4'

Then run:

ffmpeg -f concat -safe 0 -i files.txt -c copy joined.mp4

The concat demuxer reads each listed file in turn. The -c copy option copies the encoded audio and video streams into the output without decoding and re-encoding them, so it avoids the quality loss and extra processing that re-encoding can introduce. FFmpeg documents the demuxer’s concat input format, and Mux’s walkthrough shows the same list-file approach.

For stream copy to work, the clips’ video and audio codecs, stream layout, and timing characteristics must match closely enough for FFmpeg to continue each stream cleanly. If they do not, the output can freeze, lose synchronization, or produce timestamp warnings. The FFmpeg concat discussion covers the matching-stream requirement.

The -safe 0 option lets FFmpeg read paths its default safety checks reject, including absolute paths. Use it only with a file list you trust. For simple filenames in the same folder, FFmpeg’s default safety setting is sufficient.

Use the concat filter when clips differ

The concat filter joins decoded audio and video streams, then FFmpeg encodes the result. Use it when the clips have different codecs or when stream copy produces broken output. Re-encoding takes longer and can reduce quality, so choose output encoding settings that suit your needs.

This example assumes both inputs contain audio and video and have the same video dimensions and compatible audio settings:

ffmpeg -i part1.mp4 -i part2.mp4 \
  -filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0]concat=n=2:v=1:a=1[v][a]" \
  -map "[v]" -map "[a]" \
  -c:v libx264 -c:a aac joined.mp4

If the video dimensions differ, resize and pad each video stream to the same dimensions before passing the streams to concat. Make audio settings compatible too, including sample rates and channel layouts. The concat filter requires compatible audio and video inputs.

Choose the method that fits your files

Use the concat demuxer with -c copy when the clips have matching streams and you want to avoid re-encoding. Use the concat filter when the inputs differ and you are prepared to encode a new output.

FFmpeg also has a concat protocol, which joins data at the file level. That works only with formats that support this kind of joining, such as MPEG transport streams. It is unsuitable for directly joining MP4 files; the FFmpeg formats documentation describes the distinction.

Make a narrated explainer with explainroo

If your goal is to explain a topic rather than stitch existing footage, explainroo can produce a narrated video through a coding agent. It generates scenes from a script and uses FFmpeg to assemble the finished video as an MP4. It does not edit existing camera clips or provide a drag-and-drop editor.

Paste this prompt into a coding agent that can run shell commands:

Make me a short explainer video about how to join videos with FFmpeg concat. Use explainroo for it: clone https://github.com/vincentsch/explainroo, read its AGENTS.md and follow the steps.

The agent sets up explainroo, creates and checks the video, then provides the MP4. It writes script.md for the narration and scenes.js for the drawings. For review, explainroo supplies scene stills, a contact sheet, a layout check for cut-off or overlapping text, and a speech check for mispronounced words. See the explainroo documentation for details.

Free and open source

Let your AI agent make the video

explainroo lets a coding agent like Claude Code or Codex make narrated explainer videos and product demos. The voice, the word timing and the rendering run on your own computer, with no API key and no cost per video.

Copy this into your AI agent

Make me a short explainer video about [your topic]. Use explainroo for it: clone https://github.com/vincentsch/explainroo, read its AGENTS.md and follow the steps.

Getting started Example videos GitHub

Made with explainroo: How a cache makes a website faster

More on ffmpeg and rendering

All guides on ffmpeg and rendering