A reliable FFmpeg playlist stream starts with an ordered file list and media that can be joined predictably. FFmpeg can then read the files in sequence and send one continuous output to YouTube, but the playlist command is not a cure for incompatible files, poor ingest settings, buffering, or an unsupervised computer.
The practical workflow is to prepare the files, check their streams, choose whether to copy or re-encode them, connect FFmpeg to YouTube, and test the complete cycle before leaving it running overnight. Recovery and monitoring are separate jobs from playlist playback, so plan those as well.
Prepare and order the local media files
Start with the content rather than the command. Put the videos in a directory that will remain available while FFmpeg is running, then decide the exact order in which they should play. This matters for devotional channels, news loops, study videos, and ambience stations where the sequence itself may be part of the viewing experience.
Create a UTF-8 text file called playlist.txt. Each line should identify one file:
file '/media/video-01.mp4'
file '/media/video-02.mp4'
file '/media/video-03.mp4'
The concat demuxer reads the entries in the order shown. It does not sort them by filename, creation date, or duration. If the order matters, write it explicitly rather than relying on names such as video-1, video-2, and video-10 being sorted as you expect.
Use full paths when the working directory may change. Check for spelling, capitalisation, spaces, and extensions. A playlist that works from an interactive terminal can fail under a scheduled task if it depends on a relative path or a mounted drive that is not available when the process starts.
The -safe 0 option is commonly used when the manifest contains paths that the concat demuxer would otherwise reject. It is not a security setting that makes arbitrary files safe. Use it only when you control the playlist and its contents. Do not allow an untrusted person or upload process to rewrite a manifest that your streaming account will execute.
Apostrophes and unusual characters need care because the manifest has its own quoting rules. If a filename contains an apostrophe, either rename the file to a simple name or create the correctly escaped manifest entry. Renaming a collection to predictable names is often easier to audit than troubleshooting a parser error at two in the morning.
Before starting the live feed, run through the list as a local media job. Confirm that every file opens, that the audio is present when expected, and that the final file does not stop early. Keep a copy of the manifest that was tested. If you change the order later, record that change so you know which version is currently on air.
For channels with a repeated schedule, consider generating the manifest from a small, controlled script or spreadsheet export, then inspect the resulting text file before using it. Automation can save time, but it should not remove the review step. A single missing item can alter the timing of the entire rotation.
Check compatibility across playlist items
The concat demuxer is not a general-purpose converter. Its inputs need compatible streams, codecs, and time bases, and inaccurate duration information can produce glitches, gaps, or unexpected transitions. Two files can both be MP4 files and still differ in ways that make direct joining unreliable.
Inspect each file with ffprobe, which is distributed with FFmpeg. For example:
ffprobe -v error -show_streams -show_format \
-of json '/media/video-01.mp4'
Look for the video codec, width, height, frame rate, pixel format, audio codec, sample rate, channel layout, and reported duration. Compare those values across the playlist. You do not need every file to have been produced by the same application, but the output must have a consistent shape if you want a simple continuous feed.
Pay particular attention to these differences:
| Property | Why it matters | Typical response |
|---|---|---|
| Video codec | Stream copying cannot join different codecs as one matching stream | Re-encode or normalise the files |
| Resolution | Changing dimensions can cause output changes or filter errors | Scale and pad to one output size |
| Frame rate | Variable or different frame rates can create timestamp problems | Normalise frame rate if required |
| Pixel format | Some encoders and devices expect a consistent format | Convert to the chosen output format |
| Audio codec and layout | Missing audio or different channel layouts can break assumptions | Add, remove, or re-encode audio consistently |
| Time base and duration | Incorrect timestamps can create pauses or artefacts | Remux or re-encode after checking the source |
This is where many overnight failures begin. The first two files may play correctly, while a later item introduces a timestamp discontinuity or an audio mismatch. Test the whole playlist, not just a short sample from its beginning.
If the files come from different cameras, editing applications, or download sources, normalise them before building the live command. A preparation pass takes additional storage and processing time, but it turns a collection of uncertain inputs into a more predictable source. Keep the original files separately so that you can return to them if a conversion decision needs changing.
The video compression walkthrough can help when your source files are too large for the computer or storage arrangement you are using. Compression is not the same as compatibility, however. A smaller file may still have a codec, frame rate, or audio layout that differs from the rest of the playlist.
Choose the concat approach carefully
There are two practical approaches for a local playlist. The first uses the concat demuxer and copies compatible streams where possible. The second uses the playlist as input but re-encodes the output into one consistent profile.
Stream copying reduces encoding work because FFmpeg does not decode and encode every frame. It is attractive when all files were deliberately produced with matching properties. Its limitation is that the files must actually meet the concat requirements. Copying streams does not repair a bad timestamp, add missing audio, or make different resolutions match.
Re-encoding uses more CPU, GPU, or both, depending on the encoder you choose. In return, you can establish one output resolution, frame rate, pixel format, video codec, audio codec, and bitrate. The exact profile should reflect YouTube's current guidance and the capacity of the machine doing the work.
| Workflow | Main benefit | Main risk | Suitable when |
|---|---|---|---|
| Concat with stream copy | Lower processing load | Sensitive to mismatched streams and timestamps | The files were made to the same technical profile |
| Concat with re-encoding | A consistent output can be created | Higher sustained processing load | The source files differ or the output needs normalising |
| Pre-normalised files plus concat | Easier live process to inspect | Requires a preparation stage and extra storage | You want the live machine to do less work |
A representative starting command for a re-encoded output is:
ffmpeg -re -stream_loop -1 -f concat -safe 0 -i playlist.txt \
-c:v libx264 -preset veryfast -pix_fmt yuv420p \
-c:a aac -b:a 128k \
-f flv "rtmp://YOUR_SERVER/YOUR_APP/YOUR_STREAM_KEY"
This is an illustrative composition, not a universal tested recipe for every FFmpeg build or file collection. -re asks FFmpeg to read prerecorded material at approximately its natural rate instead of sending it as fast as the computer can process it. That real-time pacing is important when a file source is being sent to a live endpoint.
-stream_loop -1 requests indefinite looping of the input. Pairing it with a concat input is a practical way to repeat a playlist, but check the behaviour of the FFmpeg version installed on your machine and test the complete command with your own manifest. Do not assume that an option combination behaves identically across old builds, operating systems, or input formats.
If you choose stream copy, replace the encoder settings only after confirming that the files have matching streams and timestamps. A command that works for one set of MP4 files may be unsuitable for a mixed collection. When in doubt, re-encode or normalise the source files before sending them live.
For an operational comparison, the Raspberry Pi 24/7 loop guide explains why sustained encoding load, cooling, and storage behaviour matter. The same concerns apply to a desktop or mini PC, even if the available processing capacity is greater.
Configure YouTube output and credentials
Open YouTube Studio, choose Create, then Go Live, and use the Stream tab to create or select the broadcast. YouTube provides the server URL and stream key that the encoder must use. Its official encoder instructions describe this workflow and the preview step.
Replace the placeholder output in the example with the current ingest address and key shown in Live Control Room. Keep the key private. Do not place a real key in a public repository, screenshot, shared tutorial, shell history that other users can inspect, or a log file that is uploaded elsewhere.
YouTube's instructions say to enter the server URL and stream key into the encoder. Treat those values as credentials for the broadcast, not as permanent constants that can be copied from an old setup without checking. If you reset the key or create a different stream configuration, update the process before starting it again.
For a scheduled broadcast, start FFmpeg and inspect the preview in Live Control Room. YouTube instructs creators to click Go live after the preview appears when using that workflow. Starting FFmpeg alone does not necessarily make a scheduled event public.
The conventional RTMP or RTMPS route is usually the simpler starting point for a file-based FFmpeg playlist. YouTube also documents HLS ingestion for particular formats and use cases. Its HLS live streaming guidance describes segment and HTTPS requirements and notes that HLS has higher latency than RTMP. Choose HLS because your format requires it, not because changing protocols will solve an unrelated playlist or network problem.
The stream key troubleshooting guide is useful when the output is rejected before media health can be evaluated. Separate credential errors from codec errors: a valid key cannot make an unsupported or malformed output acceptable.
Test transitions and the continuous feed
Do not schedule the public broadcast immediately after seeing the first video appear. Let the playlist pass through every item at least once in a controlled test. Watch the exact points where one file ends and the next begins, including video, audio, subtitles if present, and any change in aspect ratio.
During the test, watch FFmpeg's terminal output. The reported speed should remain close to real time rather than falling persistently behind. Look for messages about invalid timestamps, non-monotonic DTS, missing streams, encoder overload, broken pipes, or output errors. A warning that appears once may deserve investigation even if YouTube still shows a picture.
Check the first transition, a transition between dissimilar files, and the transition back to the first file. The loop boundary is especially important because a playlist can work through its middle entries and still fail when the input is opened again. If the command stops when the last item ends, verify that the loop option is being applied as intended by the installed build.
Use a private or unlisted test broadcast if that fits your channel workflow. Confirm that the Live Control Room preview remains active while a transition takes place. Then inspect the watch page from another connection if possible. A local FFmpeg process can appear healthy while the public playback path is delayed or unavailable.
Test with the computer in the state in which it will operate. If the display will be locked, the user session will be unattended, or the machine will run on a different network connection, reproduce that condition. Check that the media drive remains mounted and that the process can read every path without a prompt.
Do not interpret one successful transition as proof that a 24/7 feed will never buffer. Buffering can result from network stability, ingest conditions, encoding load, player behaviour, or YouTube-side status. The test gives you evidence about this particular file set and machine; it does not guarantee every future combination.
Monitor FFmpeg and YouTube separately
A continuous stream has two health views. FFmpeg tells you whether the local process is reading, encoding, and writing. YouTube tells you whether the service is receiving and processing the feed as expected. You need both views because one can look normal while the other reports a problem.
At the FFmpeg level, watch speed, frame progress, output size, and error messages. A process that is running but consistently slower than real time will eventually fall behind. Rising CPU use, thermal throttling, disk read errors, or a full output queue can also appear before the broadcast visibly fails.
At the YouTube level, check the preview, stream health, and any warnings in Live Control Room. The YouTube Live API documentation describes health states including good, ok, bad, and noData. These labels are operational signals, not a promise that a stream will remain available without intervention.
For a longer deployment, send process output to a rotating log and record the start time, playlist version, and FFmpeg build. Avoid logging the complete output URL if it contains the stream key. A useful log lets you distinguish an input failure from a network disconnect or an ingest rejection after the fact.
Check the network path as a separate component. The monthly bandwidth guide explains why a continuous upload should be considered in your connection and data-use planning. Available bandwidth is not the same as stable bandwidth, and a speed test taken during the day does not describe every overnight condition.
If you need an alert, monitor for process exit, repeated output errors, a sustained drop in processing speed, or a YouTube health change. Choose thresholds that you can investigate rather than creating alerts for every harmless warning. The purpose is to shorten the time between a fault and a useful action.
Plan recovery and source-file checks
A playlist process can stop because of a corrupt input, a timestamp discontinuity, a missing drive, an operating-system restart, encoder overload, or a network/output failure. Each cause needs a different response. Restarting FFmpeg may restore a disconnected output, but it will not repair a bad file or an incorrect ingest setting.
Use a process supervisor appropriate to your operating system. It should start FFmpeg after a reboot, retain useful logs, apply a restart policy, and notify you when repeated restarts occur. Avoid a blind loop that launches many copies at once. Two processes using the same stream key can create a second problem while hiding the first one.
Before enabling automatic restart, decide where the process should resume. Restarting at the beginning is simple but repeats the first item. Resuming from the failed item requires more state and may be difficult if the failure happened during a transition. Either approach can be reasonable if it is documented and visible to the person responsible for the channel.
FFmpeg's FIFO muxer has recovery-related options for certain output failures. Its documented RTMP example includes real-time pacing, H.264 and AAC output, FLV, packet-overflow handling, and recovery attempts. Options such as dropping packets during queue overflow trade completeness for continued processing. They do not guarantee an uninterrupted YouTube broadcast, and they do not replace process supervision, alerting, or stable networking.
Treat source-file validation as its own check. When you add a new video, open it, run ffprobe, compare it with the existing profile, and test the relevant transition. Do not add an untested file to a live manifest simply because it plays in a desktop media player.
If maintaining an always-on computer is the main difficulty, StreamNeo removes the need to keep your own playback machine running: you upload the file, provide the YouTube stream key, and the cloud feed handles continuous playback with automatic monitoring and restart. It remains YouTube-only, so you still need to prepare suitable media and check the channel's YouTube status.
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 FFmpeg play videos one after another?
Yes. The concat demuxer can read a manifest containing one file directive per video and process the entries in order. The files still need compatible streams, codecs, and time bases, so playing one after another is not the same as joining any arbitrary collection without preparation.
Can I loop the playlist indefinitely?
-stream_loop -1 requests indefinite input looping and can be used with a concat input as a practical playlist pattern. Check the behaviour with your installed FFmpeg build and test the loop boundary before going live. If the process stops because an input is invalid, looping does not repair that input.
Why does YouTube show buffering even though FFmpeg is running?
FFmpeg may still be running while encoding is slower than real time, the network is unstable, the output queue is failing, or YouTube is reporting an ingest problem. Compare FFmpeg's speed and errors with the preview and stream-health information in Live Control Room. A restart can help with a temporary output failure, but it cannot fix incompatible media or incorrect ingest settings.
Will YouTube keep one 24/7 archive of the whole stream?
YouTube says streams under 12 hours are automatically archived. That statement does not establish a guarantee that a single uninterrupted 24/7 broadcast will produce one continuous archive, so check the current official Live guidance if archive continuity matters to your channel.