A file list lets FFmpeg play several local videos in sequence and send them as one continuous YouTube Live broadcast. For files with matching streams, codecs and time bases, the concat demuxer is usually the simpler path; when those properties differ, use a concat filter and re-encode to a consistent output.
The list is an input to FFmpeg, not a playlist that YouTube viewers can browse. You still need to select the ingest destination and stream key in YouTube Live Control Room, and choose output settings for the resolution, frame rate and codec you intend to send. YouTube’s guidance changes, so check its current live encoder settings before publishing.
Choose the right file-list workflow
There are two distinct ways to join files. The concat demuxer reads a script as a sequence of inputs and can avoid re-encoding when the files already have compatible streams. The concat filter joins decoded audio and video streams inside an FFmpeg filter graph; that gives you room to scale, change frame rate or otherwise normalise inputs, but it requires encoding the result.
| Workflow | Best fit | What to expect |
|---|---|---|
| Concat demuxer | Files with matching stream layout, codec and time base | Less processing when streams can be copied; mismatches may cause errors or poor joins |
| Concat filter | Files that need a common size, frame rate, pixel format or audio layout | More control through re-encoding, at the cost of encoding work and a generation of lossy quality if using lossy settings |
Do not choose the demuxer just because all the files have an .mp4 extension. Containers are packaging, not proof that their contents match. Inspect the actual streams first, especially if videos came from different phones, editors or download sources.
A file list also does not make a broadcast resilient by itself. FFmpeg must keep running, retain access to the files and reach YouTube’s ingest endpoint. If you use a local machine, its power, network and operating-system maintenance remain part of the setup; a 24/7 OBS stream interrupted by Windows updates is a useful reminder that a loop is only one part of continuous operation.
Check source compatibility before joining
The concat demuxer has a specific precondition: FFmpeg’s documentation says, “All files must have the same streams (same codecs, same time base, etc.).” Compare the number and types of streams, their codecs, time bases, and relevant video and audio parameters. Files that look alike in a media player can still differ in ways that matter when stitched together.
Use FFmpeg’s ffprobe on each source, or inspect the media properties in an editor that exposes stream details. Check that each video has the expected video and audio streams, and compare dimensions, frame rates, pixel format, sample rate and channel layout. The demuxer does not turn a variable collection of sources into a uniform broadcast format.
Timing needs attention too. The demuxer places later files after earlier ones using timestamps and duration information. If a file’s duration is missing or inaccurate, the next segment may start at the wrong time; differing stream lengths can also introduce gaps. When metadata is unreliable, verify the actual duration and consider explicit duration directives in the playlist, using values appropriate to the source rather than guessing.
If you are assembling a devotional channel, for example, a set of exported MP4 bhajans may appear consistent but still have different audio layouts or frame rates. Test the transitions between them, not just the first file. If you are preparing a lofi rotation, plan the order in the list deliberately; a file-list sequence repeats in the same order, so content rotation is not automatic. See this guide on avoiding overly frequent song repeats in a YouTube lofi stream for the editorial side of that problem.
Write the ffconcat playlist correctly
Create a plain-text file and put the videos in the order you want them played. With the explicit header, the first line must be exactly ffconcat version 1.0; do not add leading spaces, a blank line or a byte-order mark before it. Save the file in an encoding compatible with the extended-ASCII script format described by FFmpeg.
ffconcat version 1.0
file 'video-01.mp4'
file 'video-02.mp4'
file 'video-03.mp4'
Each file line identifies one input. Paths are interpreted in relation to the working directory unless you give a different path, so a relative path that works in your terminal may fail when a scheduled job starts from another directory. For a stable setup, place the playlist and media in a known location, use clear paths, and test the command from the same environment that will run the live stream.
Spaces and special characters in paths need correct escaping or quoting according to FFmpeg’s script syntax. Avoid experimenting with complex filenames just before going live: use simple names such as morning-prayer-01.mp4, or test the exact quoted path in a short run first. The list is not shell syntax, so shell quoting rules and the playlist’s own quoting rules are not interchangeable.
The -safe 0 option in the example command below allows paths that the demuxer’s safe-path checks might otherwise reject. Treat that as an explicit choice, not a harmless default: only point the playlist at files you control and intend to use. If you can keep the list and media in a safe, predictable path arrangement, you may not need to relax the check. FFmpeg’s concat demuxer documentation describes the supported script directives and safety behaviour; consult the current documentation for the FFmpeg version you have installed.
Loop the list for continuous playback
For a continuous file-based broadcast, FFmpeg needs to read the list repeatedly and pace file playback in real time. The following is an illustrative command structure, not a tested command for every operating system or FFmpeg build:
ffmpeg -re -stream_loop -1 -f concat -safe 0 -i playlist.ffconcat \\
-c:v libx264 -preset veryfast -b:v 4500k -maxrate 4500k -bufsize 9000k \\
-r 30 -g 60 -keyint_min 60 -sc_threshold 0 \\
-c:a aac -b:a 128k -ar 44100 \\
-f flv 'rtmps://YOUR_INGEST_ENDPOINT/YOUR_STREAM_KEY'
Replace the playlist path, destination and key with the values for your environment. The example’s video rate and GOP values assume a particular output profile and are present to show command shape, not as universal recommendations. The -g 60 setting corresponds to a two-second interval only when the output is 30 frames per second; if you change the frame rate, adjust the keyframe interval accordingly. Do not copy the example bitrate without checking YouTube’s current table for your selected codec, resolution and frame rate.
-stream_loop -1 tells FFmpeg to loop the input indefinitely, while -re reads the file input at its native pace instead of sending it as fast as the machine can process it. These are common FFmpeg options, but confirm their availability and syntax in your installed build. The output -f flv is used for the RTMP-family ingest path shown here; follow the destination and protocol supplied in YouTube Live Control Room.
Protect the stream key as you would a password. Do not post it in a screenshot, public configuration file or shared chat. YouTube explains how to manage stream keys and live stream settings; if the key is exposed, use YouTube’s current controls to replace or reset it before broadcasting.
Use concat filtering when the files differ
When the inputs do not meet the demuxer’s compatibility requirements, the reliable route is to decode, normalise and encode them. FFmpeg’s FAQ points to the concat filter for cases where re-encoding is needed. The filter works on decoded streams, which means you can bring each input to a common video and audio format before joining them.
Normalisation is a deliberate set of choices, not a magic compatibility switch. Decide the output dimensions, frame rate, pixel format, audio sample rate and channel layout first. Then make every segment conform to that target in the filter graph. For instance, if one source is portrait and another is landscape, scaling alone does not decide whether to crop, pad or preserve the original frame; that is a presentation choice you need to make.
A filter-based command can become long because each input needs its own chain and the concat filter needs matching labelled streams in the intended order. For a mixed collection, build and test the graph on a short sample before leaving it to run. Encoding also uses processor capacity continuously. On a small machine, a complex filter graph may not encode quickly enough in real time, so check that the system can keep up and watch for dropped frames or encoder overload.
Re-encoding gives you control but can alter quality. Choose a sensible output profile and avoid repeated lossy export cycles before the live encode. If your source files are already compatible, the demuxer may be preferable because it avoids that extra processing step. FFmpeg’s concat FAQ guidance explains the project’s recommended approach; verify syntax against the current FFmpeg documentation rather than relying on a filter graph copied from an unrelated media set.
Set YouTube output and encoder parameters
YouTube’s live encoder guidance recommends RTMPS for encrypted ingest and calls for constant bitrate (CBR) output with a two-second keyframe interval, not exceeding four seconds. It lists accepted ingest codecs and settings, with bitrate guidance tied to codec, resolution and frame rate. Those relationships matter: there is no single bitrate that suits every stream, and the illustrative values in a command should not override the current YouTube table.
Choose the output resolution and frame rate to suit both your content and the upload connection. A static devotional image with a subtle visualiser may not need the same output profile as a detailed local-news loop, but the decision should still be made against the current YouTube recommendations and your available upload capacity. A higher output resolution or frame rate affects the bitrate you need and the work performed by the encoder.
For a local setup, test upload speed under realistic conditions rather than relying on the advertised broadband rate. Leave headroom for other devices and normal variation, then use YouTube’s stream-health indicators during a private or unlisted test. If the connection cannot sustain the selected output, reduce the profile and check the table again rather than hoping the stream will recover on its own.
Keep the encoder and ingest settings aligned. Set a fixed frame rate for the output where appropriate, configure CBR as recommended, and set the keyframe interval from the actual output frame rate. Ensure the stream key and ingest destination came from the same active YouTube Live setup. For a wider view of network and encoder checks, see the OBS settings checklist for a YouTube live loop on JioFiber; its OBS-specific details are not a substitute for checking FFmpeg’s output or YouTube’s current requirements.
Test playback and troubleshoot before going live
Run a short test before you rely on the playlist overnight. Confirm the first video starts, every transition occurs in the intended order, the last file returns to the first, and audio remains present and at a consistent level. Watch a few joins rather than only the opening minutes. A stream can connect successfully while still having a timestamp gap, a silent segment or a badly cropped source.
If FFmpeg reports that streams do not match or the join looks wrong, inspect the stream layouts and time bases first. Then review duration metadata and any explicit duration entries. If the files genuinely differ, switch to a filter-and-re-encode workflow instead of trying to make the demuxer reconcile them.
If the local output looks correct but YouTube reports an ingest problem, check the protocol, destination and stream key, then compare codec, bitrate, frame rate and keyframe interval with YouTube’s current guidance. Use the stream-health panel and logs to distinguish a network interruption from an encoding or configuration issue. Do not assume that a connection test proves an overnight stream will remain uninterrupted.
For a long-running broadcast, consider how the process will be monitored and restarted after a failure, and who will notice if the source disk fills or the network drops. If keeping a computer powered and available is the pain point, StreamNeo removes that specific burden by letting you upload the video, provide your YouTube stream key and leave the broadcast running without your own computer switched on. That does not remove the need to prepare compatible material, check YouTube’s current guidance or protect the key.
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
Is the ffconcat list a YouTube playlist?
No. It is a text script that FFmpeg reads to join local files into a single output stream. YouTube receives that output as a live broadcast; it does not receive the list as a viewer-facing playlist.
Can I use different MP4 files in one concat-demuxer list?
Only if their streams meet the demuxer’s compatibility requirements. The same file extension does not guarantee matching codecs, stream layouts or time bases. Inspect the inputs, and use a concat filter with re-encoding if you need to normalise them.
Why does the next file start late or show a glitch?
Timestamp handling depends on stream timing and duration metadata, so inaccurate or missing duration information can affect where a segment begins. Check the actual durations and compare the streams; add appropriate duration directives only when you have reliable values. If the inputs differ structurally, normalise them rather than relying on the demuxer.
Which bitrate should I use for YouTube Live?
Use YouTube’s current encoder table for the output codec, resolution and frame rate you selected. Its recommendations are configuration-specific and may change, so check the official page before each setup rather than reusing a sample command’s bitrate.