A folder of videos can be streamed continuously to YouTube with FFmpeg, but FFmpeg needs an explicit playlist rather than an assumed folder order. The usual approach is to create a concat playlist, loop it, encode or copy the compatible files, and send the output to the YouTube Live ingest address.
This works only while the computer, FFmpeg process, files, and network connection keep running. Continuous output does not mean YouTube will retain one live event indefinitely, so you still need to watch the Live Control Room and plan how the broadcast will be managed.
Inspect the files and decide the order
Start by deciding what viewers should see and in what order. A folder listing is not a reliable programme schedule: operating systems and shell commands may sort names differently, and a newly added file may appear in an unexpected position. An explicit playlist makes the sequence visible and easy to change.
For a devotional channel, you might want an opening title, several bhajans, a short station ident, and then the same material again. For a study channel, you might place a longer ambience video first and shorter breaks after it. Write that order down before building the FFmpeg command.
Check each file for at least these characteristics:
- video and audio streams present
- video codec and dimensions
- frame rate and time base
- audio codec, sample rate, and channel layout
- duration and whether the file plays cleanly from beginning to end
FFmpeg can inspect a file with ffprobe, which is normally installed with FFmpeg:
ffprobe -v error -show_entries stream=index,codec_name,codec_type,width,height,r_frame_rate,time_base,sample_rate,channels -show_entries format=duration -of default=noprint_wrappers=1 "videos/first.mp4"
Run this against more than one file, not just the first item in the folder. A collection that looks uniform in a media player may contain different audio layouts, frame rates, or damaged duration metadata. Those differences matter when FFmpeg joins the files.
If the files need preparation before streaming, the guide on preparing video files for a 24/7 YouTube stream on a low-end PC covers why simpler, consistent media is easier to operate overnight.
Also confirm that you have the right to broadcast the material. A technical playlist does not change copyright ownership or YouTube's policies. For music channels, keep a record of licences and review music sources for 24/7 streams that are less likely to create claims.
Create an explicit concat playlist
Create a plain text file called playlist.txt. Each entry begins with file and points to one source file. The order of the lines is the playback order:
file 'videos/opening.mp4'
file 'videos/bhajan-01.mp4'
file 'videos/bhajan-02.mp4'
file 'videos/station-ident.mp4'
The concat demuxer reads this script and advances the timestamps from one file to the next. It is a playlist reader, not a general-purpose converter. The FFmpeg documentation states that the files used by this method need the same streams, codecs, and time bases.
Paths with spaces or special characters need careful quoting or escaping. For example:
file 'videos/Morning Prayer.mp4'
file 'videos/Delhi - Evening Loop.mp4'
The quoting rules depend on the playlist format and the characters in the path. Keep file names simple where possible: letters, numbers, hyphens, and underscores reduce the chance of a shell or playlist parsing problem. If you use Windows paths, test the format with the FFmpeg build on that machine rather than copying a Linux example unchanged.
The concat demuxer uses a safety check for file paths. The safe option defaults to 1, which rejects paths it considers unsafe. A trusted playlist with ordinary relative paths may work without changing it. If you need absolute paths or another path that is rejected, -safe 0 can disable that check for this playlist:
ffmpeg -f concat -safe 0 -i playlist.txt -c copy preview.mp4
Only use that setting for a playlist you created or inspected. It does not make an unknown playlist safe, and it does not repair unsuitable media.
Keep playlist.txt beside the media folder while testing. Relative paths are easier to move between machines than a script full of machine-specific absolute paths. Before adding the loop, play a short non-looped output and confirm that the first file, transitions, and final file are all present.
Check whether the sources are compatible
The simple concat path assumes that the files have matching stream layouts and compatible technical properties. In practical terms, that normally means the same number and type of streams, compatible codecs, matching time bases, and audio and video that can be joined without a format change.
A random folder containing an H.264 MP4, an HEVC file, a file with no audio, and a screen recording with a different frame rate is not guaranteed to work with -c copy. The files may play individually but fail at the transition, produce timestamp warnings, or create a broken output.
There is another timing issue. The demuxer uses each file's duration when calculating where the next file begins. If a file contains inaccurate duration metadata, the next item may start too early or too late. Unequal stream lengths can also produce a gap or an unexpected continuation of one stream. The FFmpeg FAQ explains the distinction between joining compatible files without re-encoding and concatenating material that needs conversion.
A useful test is to concatenate two or three representative files first. Include the shortest file, the file with the most movement, and any item that looks technically different. Do not test only the easiest pair and assume the full folder will behave the same way.
There are two broad choices:
| Situation | Better approach | Main trade-off |
|---|---|---|
| Files have matching streams and suitable timestamps | Concat demuxer with stream copy | Low CPU use and no generation loss, but strict compatibility requirements |
| Files differ but can be converted to one common format | Normalise each file, then use the concat demuxer | More preparation and encoding time, but simpler long-running playback |
| Files need different per-input handling during one command | Concat filter | Flexible and suitable for re-encoding, but uses more CPU and needs a more complex filter graph |
If the stream is important enough to run overnight, normalising the library before the first live broadcast is often easier to troubleshoot than discovering a bad transition after several hours.
Loop the playlist with FFmpeg
YouTube gives you an ingest URL and a stream name or key through the Live Control Room. Treat those values as private. The YouTube Live Streaming API documentation describes the stream URL and name fields and notes that they may be used together as STREAM_URL/STREAM_NAME.
The following is an illustrative command. Replace the paths, output address, and encoder settings after checking your files and installed FFmpeg version:
ffmpeg -re -stream_loop -1 \
-f concat -safe 0 -i playlist.txt \
-c:v libx264 -preset veryfast -pix_fmt yuv420p \
-r 30 -g 60 -keyint_min 60 -sc_threshold 0 \
-b:v 10M -maxrate 10M -bufsize 20M \
-c:a aac -b:a 128k -ar 44100 \
-f flv "rtmps://YOUR_INGEST_URL/YOUR_STREAM_NAME"
-stream_loop -1 tells FFmpeg to repeat the input indefinitely. -re reads the file at approximately its normal playback rate rather than sending it as quickly as the computer can process it. The concat input and its options need to match the FFmpeg version and shell you are using, so test the command with a short playlist before leaving it unattended.
The example re-encodes the output. That is deliberate: it gives you a way to produce one consistent video and audio stream even when the source files have been normalised first. It also consumes CPU. If the sources are already compatible and meet the required output format, you may test a lower-CPU stream-copy command instead:
ffmpeg -re -stream_loop -1 \
-f concat -safe 0 -i playlist.txt \
-c copy -f flv "rtmps://YOUR_INGEST_URL/YOUR_STREAM_NAME"
Do not assume that -c copy is automatically the better choice. It avoids re-encoding, but it preserves the source properties and may expose incompatible timestamps or an output format YouTube does not accept as expected. Re-encoding gives you more control, while increasing processing load and potentially changing quality.
Do not paste a real stream key into a public tutorial, screenshot, script repository, or support request. If a key is exposed, replace it in YouTube's Live Control Room. Store the command securely, and be aware that command lines can appear in shell history or process listings.
Normalise mixed files or use the concat filter
Normalisation means converting every source to a common set of properties before creating the final playlist. For example, you might choose one frame size, frame rate, pixel format, video codec, audio codec, sample rate, and channel layout for the whole library. The precise values should reflect your source material, encoding support, and upload capacity.
A normalisation command might look like this:
ffmpeg -i "input.mp4" \
-c:v libx264 -preset medium -pix_fmt yuv420p \
-vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2" \
-r 30 -c:a aac -ar 44100 -ac 2 -b:a 128k \
"normalised/input.mp4"
This is a template, not a universal conversion recipe. A vertical video, a low-resolution image loop, or a source with unusual audio may need a different scale, padding, frame rate, or bitrate. Inspect the result and compare its audio before adding it to the live playlist.
After all files have the same intended properties, create a new concat playlist pointing to the normalised copies. Keep the originals untouched so that you can revise the conversion later.
The concat filter is useful when you need to re-encode and handle several inputs in one filter graph. A simplified example for two files is:
ffmpeg -i first.mp4 -i second.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 -pix_fmt yuv420p -c:a aac output.mp4
The filter expects each input to provide the streams being selected and still needs suitable handling for dimensions, frame rates, and audio layouts. A real folder with many files requires a generated filter graph or a preparation script, so the concat demuxer with pre-normalised files is often easier to maintain.
Use the demuxer when avoiding re-encoding is the main requirement and the inputs genuinely match. Use normalisation or the concat filter when reliability across mixed sources matters more than keeping the original encoded streams.
Set YouTube-guided output and test samples
Use YouTube's current encoder settings and bitrate guidance as the reference for the event you create. The guidance covers supported transport and codec choices, constant bitrate operation, frame rates, audio, and keyframe intervals. YouTube recommends RTMPS for encrypted transport.
YouTube's current guidance lists 10 Mbps as a recommended H.264 bitrate for 1080p at 30 frames per second. That is a recommendation for that combination, not a universal minimum for every channel. A lower resolution, a different codec, a different frame rate, or limited upload capacity changes the sensible setting.
The example uses a two-second keyframe interval at 30 frames per second with -g 60. YouTube says the keyframe interval should be two seconds and should not exceed four seconds in its encoder guidance. Treat these as output targets to verify, not as a reason to force every source into 1080p.
Test with representative material before starting the real event. Include speech, music, quiet sections, fast movement, dark scenes, still images, and transitions between files. Watch the local FFmpeg output for timestamp warnings, dropped frames, encoder overload, and audio errors.
Then run a private or otherwise controlled YouTube test event if your channel setup allows it. Check whether the picture remains smooth, audio stays in sync, and the first transition happens as expected. Test the network at the time and location where the channel will normally run, especially if the connection is shared with other users.
You can also compare this method with streaming a single video file to YouTube Live without OBS. The underlying questions remain the same: who keeps the process running, what happens when the network drops, and how will you restart it without manually rebuilding the event?
Watch stream health and plan recovery
Leave YouTube's Live Control Room open during the first long test. Read its stream-health messages rather than relying only on the fact that FFmpeg has not exited. FFmpeg can continue reading files while the upload is unstable, while YouTube may report insufficient bitrate, dropped frames, encoder problems, or an interruption in the incoming stream.
Look at both ends of the connection:
- FFmpeg's terminal output for reconnects, packet errors, timestamp problems, and encoder overload
- YouTube's preview and stream-health messages for delivery and processing issues
- CPU and memory use on the computer doing the encoding
- available disk space if logs or temporary files are being written
- upload stability during the hours when the channel is unattended
A continuous command is not the same as a self-healing service. If the computer sleeps, reboots, loses its network route, or stops the FFmpeg process, the broadcast stops. Use operating-system settings that prevent sleep, keep the media drive connected, and decide who will receive an alert or restart the process.
Consider what should happen after a failure. If the same YouTube event can be resumed, use the current Live Control Room workflow and confirm the event state. If it cannot, you may need to create or schedule another event. Do not assume that reconnecting FFmpeg will preserve a live event or its replay exactly as before.
A local FFmpeg setup gives you direct control, but it also leaves the computer and connection as part of the operating plan. If the specific pain is having to keep that computer switched on and restart a dropped process, StreamNeo removes that part by taking an uploaded video, your YouTube stream key, and the continuous broadcast process out of the local machine, with monitoring and automatic restart built into the hosted workflow. It is YouTube-only, so it does not replace a distribution plan.
For channels that need a timetable rather than one process running forever, read about scheduling start and stop times for a 24/7 YouTube streaming service. A schedule can make planned maintenance clearer, but it still does not remove the need to monitor the event and check YouTube's current rules.
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 stream every video in a folder without a playlist?
Not reliably in a chosen order. Create a text playlist with one file entry per video so the sequence is explicit and repeatable.
Will the concat demuxer join mixed MP4 files?
The file extension does not tell you whether the streams are compatible. Different codecs, stream layouts, time bases, durations, or audio properties may require normalisation, re-encoding, or the concat filter instead of unchanged stream copying.
Does -stream_loop -1 make YouTube keep the live event forever?
No. It makes FFmpeg repeat its input while the process continues. YouTube's live-event state and replay retention are separate concerns, so monitor the Live Control Room and do not treat continuous local output as a guarantee of indefinite archiving.
Should I use RTMPS or HLS for this folder loop?
For this FFmpeg workflow, use the ingest method and settings supplied for the YouTube event, with RTMPS as the usual low-complexity path. HLS is a separate YouTube ingest workflow with segment-based delivery and higher latency than RTMP, so it should be chosen deliberately rather than substituted into the command above.