FFmpeg’s concat demuxer can present compatible prerecorded podcast files in sequence as one virtual input. It does not make that sequence infinite or guarantee a nonstop YouTube stream: you still need to plan what happens when the list ends and test the full path from files to YouTube.
This guide shows how to build a concat list, check the inputs and timestamps, and test the stream. The examples assume you are comfortable running FFmpeg from a terminal; if you are not, use them as a checklist when asking someone to prepare the sequence.
Understand what the concat demuxer does
A concat file is a small text playlist that FFmpeg reads through its concat demuxer. Instead of opening each listed media file as a separate input, FFmpeg presents their packets in sequence as one virtual input. For compatible files, this can avoid decoding and re-encoding merely to join them.
The demuxer is not a YouTube playlist, a looping control or a hosting service. When FFmpeg reaches the end of the last listed file, the input is exhausted. A command or separate process must deliberately arrange repetition, and repetition still does not recover a failed encoder, broken connection or disconnected machine.
The distinction matters because “concat” can mean different things in FFmpeg. The demuxer reads a list of files and joins packet sequences. The concat filter joins decoded streams and is the documented choice when you need to re-encode. The concat protocol joins at the file level and only applies where the container format supports that type of joining. The FFmpeg FAQ on concatenating media explains these separate approaches. Choose based on your files and the processing you need, not on the word concat alone.
| Method | Use it when | Main constraint |
|---|---|---|
| Concat demuxer | Inputs have compatible streams and you want to join packets without re-encoding | Stream layouts, codecs, time bases and durations need to work together |
| Concat filter | You need to re-encode, normalise or process streams as part of joining | FFmpeg has to decode and encode the media |
| Concat protocol | The container permits file-level concatenation | It does not work for every container or file |
If a station needs an ongoing rotation rather than a one-time sequence, decide how the program will repeat before building the stream command. A practical comparison of rotation approaches appears in this guide to software for playing prerecorded videos continuously. That is a separate decision from whether the files can be joined by the demuxer.
Check file compatibility before joining
The demuxer does not repair differences between episodes. FFmpeg’s documentation states that “All files must have the same streams (same codecs, same time base, etc.).” In practice, compare the streams in each file: does every episode have the same video and audio streams, with matching codecs and compatible time bases? A file with a missing audio track or a different video stream can make a packet-level join fail or produce a sequence that behaves differently at the transition.
Use FFmpeg’s probing tools or a media inspector to record the streams, codecs, time bases, dimensions, frame rates and audio properties for every input. Pay attention to files exported from different editing projects or recording devices. Two MP4 files are not necessarily compatible just because they share a filename extension. A podcast with a static cover image may still have video, audio and timing parameters that need checking.
If the streams differ, do not try to solve that by adding more playlist entries or casually switching on an unsafe option. Prepare consistent files first, or use the concat filter and re-encode to a deliberate common format. Re-encoding takes more processing and creates a new encoded version; it also gives you a chance to normalise audio or other properties. The right choice depends on the source files, your processing capacity and how much consistency the programme requires.
Keep an inventory of the files you intend to use and check that each one plays from beginning to end. A truncated recording can appear in a list just like a complete episode, but its actual duration and ending may not match your plan. Preserve a known-good copy of source media and any final encoded versions so you can restore the sequence if an edit or conversion introduces a problem.
Create a clear concat list
A minimal list looks like this, with one file directive per line:
ffconcat version 1.0
file 'episode-01.mp4'
file 'episode-02.mp4'
file 'episode-03.mp4'
Save it as a plain-text file alongside the episodes, or use paths that correctly point to their location. The ffconcat version 1.0 declaration must be the very first line for automatic format recognition: do not put a blank line, leading spaces or a byte-order mark before it. Arrange the file entries in the order listeners should hear them. In this basic example, FFmpeg reads the first episode, then the second, then the third.
Relative paths and simple filenames make the list easier to move between folders. FFmpeg’s concat demuxer uses safe mode by default; in that mode paths must be relative and use the portable character set. Names containing spaces or special characters need the quoting or escaping described in the FFmpeg concat demuxer documentation. Test the exact list you will use, rather than assuming a path that works in a file browser will also parse correctly.
Avoid treating -safe 0 as a routine fix for a rejected path. It disables the default safety checks and permits arbitrary filenames and paths. Only consider it when you control and trust the playlist and understand why a path is being rejected. If another person supplies a list, inspect every directive and referenced file before using it.
A concat list is plain text, so it can be backed up, reviewed and versioned alongside your episode schedule. Give files unambiguous names and keep the order deliberate. If you update the list while a stream is running, do not assume the active FFmpeg process will adopt the change; stop and restart the input in a controlled way, then check the resulting sequence before relying on it.
Verify durations and timestamps
The demuxer adjusts timestamps so the first file starts at zero and each following file starts when the previous file is expected to end. That expectation depends on duration information. If FFmpeg reads an inaccurate duration, or if a file is truncated, timestamps at the transition can be misplaced. You may hear a gap, overlap, abrupt cut or other artefact even though the list itself parses.
Inspect each episode’s actual duration and compare it with the file’s reported metadata. Listen or watch near the end and beginning of adjacent files, not just at the start of each one. For a podcast, also consider editorial continuity: a clean technical join can still sound abrupt if one episode ends mid-sentence or the following episode starts at a different loudness.
When a duration needs to be specified explicitly, the concat demuxer supports a duration directive after a file entry. Use it only when you have a reliable value and understand the effect on subsequent timestamps. Do not copy a duration from an edit timeline without checking the rendered output; the encoded file may end earlier or later than the project estimate. An incorrect override can make timestamp placement worse rather than better.
Keep a simple check sheet with the filename, inspected duration, expected next file and any transition notes. Re-run the check after replacing an episode or making a new export. If FFmpeg reports timestamp warnings or the local test reveals a transition problem, resolve the source or timing issue before sending the sequence to YouTube. Changing the output bitrate will not correct an incorrect input duration.
Test the whole sequence locally
Before connecting to YouTube, use the concat list as a local FFmpeg input and play or create a short test output. A basic probe command is:
ffmpeg -f concat -i podcast.ffconcat -f null -
This asks FFmpeg to read through the sequence without creating a playable output file. It is useful for catching list syntax errors, missing files and some stream problems. It is not a substitute for listening to the joined output: review transitions, audio level, sync, black frames or unexpected silence. If the full programme is long, test every boundary in a local output rather than sampling only the first few minutes.
For a local preview file, choose an output format and encoding appropriate to your playback software. If you need to re-encode to make the files consistent, use the concat filter workflow documented by FFmpeg rather than assuming the demuxer will transcode incompatible streams. Keep the original concat list and test command with the preview so you can reproduce what you checked.
Run the test from the same working directory and with the same paths you plan to use for the live command. This catches common differences such as a file being available on your desktop but not on the machine that will run the stream. Check available disk space if you create a preview, and confirm that the local archive or output is complete before treating it as a reliable copy.
A sequence that works once locally is only one part of readiness. You have not yet tested YouTube ingest, available upload bandwidth, the stream key, or what happens if the encoder exits. For a longer-running setup, compare the operating approaches in how to schedule prerecorded videos for a nonstop live stream; scheduling, repetition and input compatibility are distinct jobs.
Send the output to YouTube Live
Once local playback is sound, configure FFmpeg’s output for YouTube Live and your intended video and audio formats. Keep the input side and output side conceptually separate: the concat demuxer reads and sequences the files, while the encoder settings shape the stream sent to YouTube. Your command must also be configured to publish to the correct live destination using the current stream key and supported ingest method.
YouTube’s live encoder settings guidance lists RTMP and RTMPS streaming, supported video codecs and recommended settings by codec, resolution and frame rate. For H.264 at 1080p30, its listed bitrate recommendation is 14 Mbps, with a 5 Mbps minimum; those figures apply to that specific configuration, not to every podcast stream. Match the table row to your actual codec, resolution and frame rate rather than copying a number from another setup.
YouTube’s guidance recommends a two-second keyframe interval and says not to exceed four seconds; it also lists constant bitrate encoding. These are encoder configuration points, not remedies for an incompatible concat input. A lower-resolution static-cover podcast may have different needs from a programme with full-motion video. Check the official settings for the actual ingestion configuration and test the chosen settings against the upload connection available where the encoder runs.
YouTube recommends leaving 20% bandwidth headroom beyond the total stream bitrate. That margin is intended to help account for variation in available upload capacity; it cannot prevent a router, provider or encoder failure. If the internet connection is shared, account for other traffic too. The YouTube streaming tips also recommend testing ahead of the event, checking the preview and watching stream health.
You can run FFmpeg on a computer you control, but that means the computer, process and connection all become part of the delivery path. If the programme needs to run while your computer is off, StreamNeo removes that particular burden: you upload the video and provide the YouTube stream key, then the stream runs without your local computer. That does not change the need to prepare compatible media, confirm the channel settings and check YouTube’s current guidance.
Monitor playback and failure points
Treat the concat file, FFmpeg process, network path and YouTube ingest as separate potential failure points. A well-formed list cannot restart a process that has exited, restore a lost connection or resolve a rejected stream configuration. Decide who will notice a failure and what they will check before leaving a channel to run unattended.
During a test, watch YouTube’s preview and stream-health indicators while listening to the actual output. Check that the correct programme appears, audio is present, the image is stable and transitions do not create unexpected silence or sync drift. If the stream-health view reports a problem, compare its information with the local FFmpeg log and your input checks; do not assume that the playlist is the cause or the solution.
For a computer-run setup, consider what happens after a restart, a power interruption, a software crash or loss of internet. A restart mechanism can relaunch a process, but it does not automatically prove that the playlist is healthy, the key remains current or the connection has recovered. Test any backup encoder or recovery procedure in advance, as YouTube’s streaming tips recommend, and keep a clear record of the steps needed to resume delivery.
Keep an intact local copy of the source files and verify any archive you intend to use for recovery. Review the stream periodically rather than relying on a successful launch as proof of continued delivery. When the broadcast is established, live analytics can help you understand what is happening over time; this guide to reading analytics for a stream that never ends covers that separate monitoring question.
If the goal is a genuinely continuous channel, plan the repeat or replacement sequence explicitly. You can create a longer sequence, arrange a separate loop in the playback workflow, or use a managed approach that suits your need to run without a local machine. None removes the need to test transitions, monitor the live preview and have a recovery plan. The concat demuxer is one tool in the programme path, not an uptime mechanism.
Before committing, compare the operating options on the pricing page. When the file and channel are ready, start free — 24-hour trial, no card.
FAQ
Does an FFmpeg concat file loop forever?
No. It lists files for the concat demuxer to present in sequence, and the sequence ends when the last listed input is exhausted. Repetition requires a separate playback arrangement, and that still does not guarantee that the encoder or network will keep delivering.
Can I use files with different codecs or stream layouts?
Do not assume they will work with the concat demuxer. Its inputs need matching streams, including codecs and time bases; inspect the files first and use a re-encoding workflow such as the concat filter when you need to make them consistent.
What does the duration directive do?
It supplies an explicit duration for a listed file, which can influence where FFmpeg places the next file’s timestamps. Use it only with a reliable duration and test the resulting transition, because a wrong value can create timestamp problems.
Does a successful local test prove the YouTube stream will stay live?
No. Local testing checks the sequence and output you tested, not the full live path or future failures. Test the YouTube preview and stream health, check available upload bandwidth, and decide how you will respond if the process or connection drops.