To loop MP4 files to YouTube Live, place them in an ffconcat playlist, then pass that playlist to FFmpeg with real-time pacing and YouTube’s current ingest details. The important condition comes first: the concat demuxer does not make different streams compatible, so stream copy is only appropriate when the files’ streams, codecs and time bases match.
If they do not match, prepare consistent inputs or concatenate and re-encode with FFmpeg’s concat filter. Test the whole sequence, including a file transition, before making the broadcast public; a playlist that parses successfully is not proof that the live output will remain clean.
Prepare the playlist in playback order
Create a plain-text file called playlist.ffconcat in the folder containing your MP4s. Put the files in the order you want viewers to see them, one file directive per line. The first line must be exactly ffconcat version 1.0 for FFmpeg to recognise the file automatically:
ffconcat version 1.0
file 'clip-01.mp4'
file 'clip-02.mp4'
file 'clip-03.mp4'
Use paths relative to the playlist where possible. That makes the playlist easier to move and avoids relying on a particular machine’s folder structure. If a filename contains spaces or punctuation, quote it as shown. If you use absolute paths or files outside the concat demuxer’s safe subset, FFmpeg may require -safe 0; only use that setting for paths you trust. It relaxes path handling, not media compatibility.
The playlist is an instruction to read the inputs one after another. It is not a new media file and does not rewrite the streams inside the MP4s. The demuxer adjusts timestamps so a following file can start after the previous one, but this depends on stream and timing assumptions that need to hold across the inputs. If the listed duration of a file is inaccurate, timestamp placement may be wrong and produce a gap or artefact at a transition. The FFmpeg concat demuxer documentation describes the playlist format and its constraints.
Keep a copy of the playlist and note which source files it refers to. When you add, replace or rename an MP4, update the playlist deliberately rather than assuming FFmpeg will find the intended content. For a longer devotional, study or ambience channel, playback order affects the viewing experience as much as the encoding does: a quiet introduction followed by a sudden loud clip can be technically valid but still sound abrupt.
Check that the MP4 streams are compatible
Before choosing -c copy, inspect each MP4. You need to compare the streams present, their codecs and their time bases, not just the filenames or the fact that every file ends in .mp4. Two files can both be MP4 containers and still differ in ways that prevent clean concatenation or make the output unsuitable for the chosen live format.
Check whether every file has the same stream layout: for example, one video stream and one audio stream in each, with no extra stream in one file that is absent from another. Compare video and audio codec, dimensions, frame rate, pixel format, sample rate and channel layout as applicable. The concat demuxer’s core requirement is matching streams, codecs and time bases; differences in resolution, frame rate or audio format are warning signs that a stream-copy workflow may not behave as intended.
Use a local inspection method you understand, such as FFprobe, and record the results for each source. A compact inspection command can help, though the exact output depends on the FFmpeg build:
ffprobe -hide_banner -show_streams -show_format clip-01.mp4
Repeat it for every file rather than checking only the first. If you are not comfortable interpreting the output, treat materially different stream details as a reason to normalise or re-encode before a public stream. For a more focused walkthrough of one common mismatch, see how to handle different frame rates in an FFmpeg playlist.
Do not infer compatibility from a short successful test alone. Some files may play through and only show a problem at a boundary, where timestamps, audio continuity or decoder expectations change. Incorrect duration metadata can also shift where the next input begins. FFmpeg’s concat format supports a duration directive to override a duration when you have a reliable value, but adding one should be a response to a verified duration issue, not a guess.
Choose stream copy or re-encoding
There are two practical routes. Stream copy avoids decoding and encoding the media again, which saves processing and avoids an additional lossy generation. It is the efficient choice only when the input streams match the concat demuxer’s requirements and are accepted by the output format. If they do not, -c copy cannot repair them.
The other route is to make the inputs consistent and encode a single output. That may mean normalising files in advance or using the concat filter, which works on decoded media and is the FFmpeg FAQ’s recommended route when re-encoding is needed. Re-encoding gives you control over a common resolution, frame rate, audio layout and output codec, but it costs processing time and can reduce quality if you choose settings carelessly. The FFmpeg FAQ explains the distinction between demuxer concatenation and filter-based concatenation.
| Decision | Stream copy | Normalise or re-encode |
|---|---|---|
| Input condition | Matching streams, codecs and time bases | Inputs differ or need a common output format |
| Processing | No media re-encoding | Decoding and encoding required |
| Main risk | Mismatch or timestamp issue appears at a boundary | More processing and another encode to configure |
| Practical choice | Verify every input before use | Build a consistent output and test its transitions |
For mismatched files, do not try to solve the problem by adding -stream_loop, changing the playlist order or hoping YouTube will accept it. Those choices do not normalise the media. If your source videos vary in frame rate, use an approach that standardises them before delivery; the playlist guide for different frame rates covers that issue in more detail.
Configure FFmpeg for real-time playback
A file can be read faster than its intended playback duration unless FFmpeg is told to pace the input. The -re option reads the input at its native rate, helping a local file behave like a live programme rather than being sent as quickly as the computer can process it. -stream_loop -1 requests indefinite repetition of the input. Confirm the behaviour against the FFmpeg version installed on your system; flags and details should be checked for your build.
For a compatible playlist, this is an illustrative starting command, not a tested command for every file or installation:
ffmpeg -re -stream_loop -1 -f concat -safe 0 -i playlist.ffconcat \
-c copy -f flv "rtmps://INGESTION_URL/STREAM_NAME"
Replace the placeholder address with the exact RTMPS endpoint and stream name or key details shown in YouTube Live Control Room. Keep the quotes around the destination while testing. If your playlist uses safe relative paths, you may not need -safe 0; removing it is preferable where it works. The -f flv output format is used for this RTMP-family workflow, while -c copy is valid here only if the source streams are compatible with each other and accepted by the output.
If you need to re-encode, do not simply leave -c copy in the command. Choose video and audio encoders, dimensions, frame rate, bitrate and keyframe interval for the output you have prepared, and use the concat filter for inputs that need joining after decode. YouTube’s current guidance lists H.264, H.265/HEVC and AV1 video codecs for RTMP/RTMPS ingest, AAC or MP3 audio, CBR encoding and a two-second keyframe frequency, not exceeding four seconds. It also publishes settings by resolution and frame rate; for example, the table gives 5 Mbps minimum and 14 Mbps recommended for H.264 at 1080p30. Check YouTube’s live encoder settings before settling on an output profile, since the guidance may change.
Choose a bitrate that your actual upload connection can sustain rather than selecting the highest number available. If the line varies, a lower stable setting is usually more useful than an ambitious one that causes dropped frames. For a wider explanation of bitrate decisions for an always-on channel, see the 24/7 podcast bitrate guide.
Send output to YouTube’s ingest endpoint
In YouTube Live Control Room, create or select the stream event and copy the current ingestion address and stream name or key. Google’s LiveStreams API documentation distinguishes the ingestion address from the stream name, and YouTube’s RTMPS ingestion guide describes the secure ingest workflow. Use the exact current values provided for your event; do not reuse an address or key from an old note without checking.
The command’s destination combines the endpoint and stream name in the form YouTube specifies. Treat the key as a password: do not paste it into a public forum, screenshot or shared log. If you need another person to help debug, redact the secret and share the error text and non-sensitive settings instead.
RTMPS is YouTube’s recommended secure form of RTMP when available. A connection failure is not necessarily an FFmpeg media problem. Check for a copied character missing from the endpoint, a stale key, a mismatch between the selected protocol and URL, or a stream that has not been started or configured in Control Room. If YouTube reports no incoming signal, compare your destination string with the values currently shown there before changing codecs at random. For a related connection error path, see how to troubleshoot YouTube RTMP error 400 in OBS.
Test the transition between files
Test with the actual playlist and representative content before the intended broadcast. Include audio and movement in the video, not only a static opening frame. YouTube Help specifically advises: “Make sure to test before you start your live stream. Tests should include audio and movement in the video similar to what you'll be doing in the stream.” A private or unlisted test event lets you inspect the incoming signal without treating the first public run as a debugging session; use the appropriate visibility and event settings in Control Room.
Watch the moment where one file ends and the next begins. Check whether the picture freezes, jumps, changes aspect or colour, or whether audio clicks, drops out or changes level. Also check the stream health feedback in Live Control Room and confirm that the next item begins at the expected time. If the playlist runs for hours, test more than one boundary, especially the transition between files with the largest differences in content or duration.
When a transition fails, isolate the source of the fault. First compare the stream layouts, codecs and time bases. Then verify each file’s duration metadata and whether the playlist path points to the file you intended. If a boundary problem follows a particular pair of files, normalise or re-encode that pair rather than blindly changing the entire FFmpeg command. If the live signal itself never arrives, inspect the RTMPS destination and key separately from the media checks.
No-sound tests deserve their own check. Confirm that each MP4 actually contains an audio stream, that the playlist inputs all carry the expected layout, and that the selected output codec is accepted by YouTube. A video-only file mixed into a sequence with audio may require explicit mapping or prior preparation. YouTube lists AAC and MP3 for RTMP/RTMPS audio ingest, but source audio still needs to be handled consistently for the output you choose.
Loop the playlist and monitor the broadcast
Once a full pass and its transitions have behaved as expected, use the loop option and leave the process visible enough to monitor. -stream_loop -1 asks FFmpeg to repeat the input, but it does not promise that every build, playlist or source combination will loop exactly as you expect. Watch the point where the final listed file returns to the first one as carefully as the other transitions. A bad timestamp or incompatible stream can be exposed at the wraparound too.
For a channel intended to stay live overnight, consider what happens if the process exits, the network drops or the computer restarts. A terminal command on a laptop is not the same as a managed always-on workflow: the machine must remain powered, connected and able to run FFmpeg. A restart mechanism can help after a process failure, but it cannot correct a bad source file, a stale stream key or an unstable upload connection. If you are keeping an FFmpeg process alive on a remote machine, the guide to keeping a YouTube livestream running after an SSH session closes covers one operational concern.
If leaving your own computer on is the particular burden, StreamNeo removes that specific requirement by turning an uploaded video into a YouTube live stream that continues with your computer switched off. That does not change the need to prepare suitable media, confirm the channel details and check YouTube’s feedback. It is YouTube-only, so it is not a route for sending the same broadcast to another platform.
Keep a short operating note with the playlist filename, source file versions, output settings and the date you last tested a transition. When you change a clip, FFmpeg version, network or output profile, test again. YouTube’s ingest guidance and supported settings can change, so verify the current official page rather than relying on a command copied from an old tutorial.
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
Can I use -c copy when my MP4 files have different codecs?
Not safely as a general rule. The concat demuxer requires matching streams, codecs and time bases; stream copy does not convert mismatches into a common format. Prepare compatible files or use a concat-filter workflow that re-encodes the output.
Does the concat demuxer fix different frame rates or resolutions?
No. It joins inputs under compatibility requirements and adjusts timestamps; it does not normalise frame rates, dimensions or audio layouts. If the files differ in ways that affect the output, standardise them before joining or use the concat filter and encode a consistent output.
Why does the stream have a gap or glitch between clips?
Check stream compatibility and the duration metadata first, then inspect the exact pair of files where the problem occurs. An incorrect duration can affect timestamp placement, while mismatched streams or time bases can create a boundary problem. Test a corrected or normalised version before relying on it in a continuous broadcast.
What should I check if YouTube does not receive the stream?
Copy the current endpoint and stream name or key from Live Control Room, confirm you used RTMPS as intended, and keep the key private. Then check whether the event is configured and active, and read the Control Room stream-health messages. Separate connection troubleshooting from media troubleshooting: a bad destination and an incompatible playlist are different faults.