Skip to content
streamneo.
Setup Guides13 min read

How to Stream a Playlist of Videos 24/7 to YouTube Using FFmpeg

A practical FFmpeg guide to looping a compatible video playlist on YouTube, with pacing, encoding, testing and failure recovery steps.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

FFmpeg can read a playlist, repeat it indefinitely and send the result to a YouTube Live event. The basic pattern is a concat playlist as input, -re for real-time pacing, -stream_loop -1 for repetition, and an RTMP or RTMPS output.

That command starting successfully does not prove that the process, upload connection or YouTube event will remain healthy overnight. Treat the example as a template to test and adapt, not as a guarantee of continuous streaming or automatic recovery.

What the loop command does

A practical starting point looks like this:

ffmpeg -re -stream_loop -1 -f concat -safe 0 -i playlist.txt \\
  -map 0:v:0 -map 0:a:0? \\
  -c:v libx264 -preset medium -b:v 5M -maxrate 5M -bufsize 10M \\
  -r 30 -g 60 -keyint_min 60 \\
  -c:a aac -b:a 128k -ar 44100 -ac 2 \\
  -f flv 'rtmps://YOUR_YOUTUBE_INGEST_URL/YOUR_STREAM_KEY'

The line is split with backslashes so you can see the job of each group. On Windows Command Prompt, the line-continuation syntax is different, so you may need to place the command on one line or use the conventions of your shell.

The input begins with -re, then -stream_loop -1, followed by the concat demuxer and the playlist file. The -map options select the first video stream and, when present, the first audio stream. The output section encodes the video and audio, sets a frame rate and keyframe interval, and sends an FLV stream to YouTube.

This is not a universal best setting. The 5M video bitrate suits the example's intended 1080p30 H.264 profile according to YouTube's current recommendation, but your resolution, frame rate, source material and upload line may call for a different choice. Check YouTube's live encoder settings before publishing and test the result with your own files.

Prepare the playlist and source files

Create a plain text file called playlist.txt in a location that FFmpeg can read. Each source needs one file entry:

file '/media/bhajan-01.mp4'
file '/media/bhajan-02.mp4'
file '/media/bhajan-03.mp4'

The concat demuxer reads the first file, then the next, and adjusts timestamps as it moves through the list. FFmpeg's concat demuxer documentation states that the files should have the same streams, codecs and time bases. In practical terms, matching dimensions, frame rates, audio layouts and stream counts makes the transition more predictable.

A playlist containing a 1920×1080 H.264 video with stereo audio, a 1280×720 file with no audio and a vertical phone recording is not a dependable one-command workload. The files may open individually but still produce timestamp problems, missing audio or an output that YouTube does not accept as expected.

Inspect the sources before building the loop. This command prints the main properties of a file:

ffprobe -v error -show_streams -show_format 'media/bhajan-01.mp4'

Compare the output for every item. If they differ, create normalised copies first. A common target might be 1920×1080, 30 frames per second, H.264 video and stereo AAC audio, but that target should follow your material and the output you actually intend to send. Re-encoding takes processing capacity, so measure the workload on the computer that will run the stream.

If a source has a wrong or unusual duration, the concat demuxer can produce a gap or an abrupt transition. FFmpeg's playlist format includes a duration directive for cases where the stored duration needs to be overridden, but use it only when you have checked the real duration. Do not add guessed timings merely to make a list look consistent.

For a playlist of devotional videos, for example, check not only the picture size but also whether each item has the same audio arrangement. A missing audio stream in one file can make -map 0:a:0? continue without audio for that item, while a strict audio map may cause the command to fail. Decide whether silent items should be fixed before streaming or deliberately handled in the output workflow.

If you are preparing mixed files for OBS rather than FFmpeg, the guide on making playlist videos consistent covers the same underlying media problem from a different angle.

Set the input path and pacing

The -i playlist.txt part points FFmpeg at the concat playlist. With -f concat, FFmpeg knows that this is a list of files rather than a single video container. -safe 0 permits entries such as absolute paths. Without it, some builds reject paths that are considered unsafe by the concat demuxer.

Use paths that are valid on the computer running FFmpeg. On Linux, /home/channel/media/playlist.txt and /media/bhajan-01.mp4 are typical absolute paths. On Windows, use the path format accepted by your FFmpeg build and shell, and test one item before assembling the full list. If a path contains spaces, quote it in the playlist using the concat demuxer's syntax rather than relying on a file manager's display name.

The -re option tells FFmpeg to read the input at approximately its native rate instead of consuming the files as quickly as the computer can decode them. Without real-time pacing, a prerecorded playlist can be read faster than it should be, causing the output to reach its end before the intended broadcast schedule.

Pacing is different from looping. -re controls how fast FFmpeg reads the input. It does not repeat the playlist. It also does not repair a slow upload connection or force YouTube to accept a malformed stream. If the process is already spending more capacity encoding than the computer can provide, real-time input pacing will not solve that bottleneck.

The placement of options matters in FFmpeg. Input options normally belong before the input they describe, while output options belong after the input. Keep -re, -stream_loop, -f concat and -safe 0 before -i playlist.txt in this template. Keep codec, bitrate, frame rate and output format options after it.

Add infinite input looping

-stream_loop -1 asks FFmpeg to repeat the input indefinitely. In this arrangement, the concat playlist is treated as the input, so FFmpeg proceeds through the listed files and then starts the playlist again.

The value -1 means an unlimited number of loops. A positive value can be used when you want a finite number of repeats for a test, but it is not a 24/7 schedule. Looping only affects the input sequence. It does not restart FFmpeg after a crash, reconnect after every network failure or create a new YouTube event when the event ends.

Transitions deserve attention. If one item ends at an unusual timestamp or its audio and video lengths do not align, the loop may contain a pause, a jump or an audio change at that point. Watch at least one complete pass of a short test playlist and inspect the transition back to the first file. A command can remain running while the programme contains a fault that viewers will notice.

A long playlist also makes diagnosis harder. Start with two or three representative files: one with ordinary motion, one with the most demanding picture and one with the audio arrangement you expect to use. Once that works, add the rest and test the complete list. Keep a copy of the playlist outside the media folder so an accidental file move is easier to detect.

Choose encoding and output settings

The example re-encodes the output with H.264 and AAC. That is deliberate: a consistent output is easier to validate than passing through a playlist whose files may have different codecs or timestamps. Re-encoding uses CPU or hardware-encoder capacity, and no single computer model can be recommended without knowing the files, resolution and operating requirements.

The important groups are:

Option Purpose What to check
-c:v libx264 Encodes video as H.264 Whether the computer can encode the chosen format in real time
-b:v, -maxrate, -bufsize Controls the video rate and rate-control buffer Whether the total upload rate suits the connection
-r 30 Requests 30 frames per second Whether the source and intended YouTube format are 30 fps
-g 60 -keyint_min 60 Targets a keyframe every 60 frames at 30 fps Whether this produces the intended two-second interval
-c:a aac -b:a 128k Encodes stereo audio as AAC Whether the source has usable audio and the rate is appropriate
-f flv Selects the output container used for the ingest stream Whether the YouTube ingest instructions match the selected protocol

YouTube's current guidance recommends CBR, a keyframe interval of two seconds and no more than four seconds, with supported video and audio codecs including H.264 and AAC. At 30 fps, a two-second interval is represented by 60 frames, which explains the example's -g 60. If you choose 25 or 60 fps, recalculate the keyframe settings rather than copying them unchanged.

YouTube's published H.264 examples include 5 Mbps for 1080p30, 6 Mbps for 1080p60, 3 Mbps for 720p30 and 8 Mbps for 720p60. These are platform recommendations, not a promise that every source or connection will behave well at those values. The current YouTube bitrate table should be your reference when you select the resolution and frame rate.

The -b:v 5M -maxrate 5M -bufsize 10M combination is one possible CBR-style arrangement, not proof that the output will be perfectly constant in every situation. Confirm the encoder's messages and YouTube's stream-health indicators. Leave spare upload capacity for the rest of the connection rather than selecting a bitrate that consumes the line's full measured speed.

Stream copying is another route:

-c:v copy -c:a copy

It avoids re-encoding, but only use it when the source streams, timestamps and output requirements are already compatible. It is not a shortcut for a mixed playlist. If the files use different codecs, dimensions or audio layouts, normalise them or encode a deliberate common output instead.

Insert the YouTube ingest destination

Create or select the broadcast in YouTube Studio's Live Control Room. YouTube provides the ingest server URL and stream key there. Put the values into the final output portion of the command, for example:

-f flv 'rtmps://the-ingest-address-from-youtube/live2/your-key'

Use the exact address shown for your event. Do not copy the placeholder above as a real destination, and do not publish a genuine key in a tutorial, screenshot or shared script. Treat the stream key like a password. If you believe it has been exposed, replace or reset it in YouTube Studio before testing again.

YouTube currently recommends RTMP or RTMPS for encoder ingest. RTMPS encrypts the transmission to Google's service, but it does not make the stream key safe to share or remove the need to protect the computer running FFmpeg. Avoid storing the complete command in a public paste, support ticket or screen recording.

Start the broadcast configuration before running the command and check which event it is attached to. A valid FFmpeg process can still be sending to the wrong event if an old key was pasted. If YouTube reports a rejected publish or invalid key, the troubleshooting guide for YouTube stream-key errors can help you separate an ingest-credential problem from an encoding problem.

Test the command before leaving it unattended

Run the command with a short playlist first. Watch the FFmpeg console for input errors, repeated reconnect attempts, timestamp warnings, encoder speed and output progress. A healthy-looking first minute is useful, but it does not test the end of the playlist or the transition back to its beginning.

Open the Live Control Room preview and check four things: the picture is the intended size, the audio is present and in sync, the output frame rate and bitrate are sensible, and the stream-health messages remain acceptable while the files change. Test from the same network and computer that you expect to use for the real broadcast.

Let the test reach a playlist boundary. This is where duration metadata, mismatched time bases and missing streams are most likely to become visible. Also test the most demanding file rather than testing only a low-motion clip. A devotional loop with a static image may use less encoding capacity than a local-news segment with movement, text overlays and several audio changes.

If the output is rejected, simplify the diagnosis. Test one known-good file, then the concat list, then the loop, and finally the full encoding settings. Read the first meaningful error rather than treating every later warning as the root cause. Keep the original source files unchanged while you prepare normalised versions, so you can return to the known inputs.

YouTube recommends testing before relying on a live stream and monitoring messages and stream health during the event. That advice matters more for an unattended channel because a command window can remain open while the ingest has stopped being useful.

A 24/7 broadcast also needs an archive plan. YouTube says that if a stream exceeds 12 hours, it may not be captured at all. If the programme must be preserved, record it locally as well and check that the recording is actually being written. Do not treat the YouTube replay as your only copy of a continuous broadcast.

Monitor and recover failures

A looping command is not a monitoring system. The process may stop because the computer restarts, a source file becomes unavailable, the disk fills, the encoder falls behind, the upload drops or the YouTube event changes state. It may also continue running while the output has no audio or contains repeated timestamp errors.

Before running overnight, decide what you will observe and what action you will take. At a minimum, check the FFmpeg process, CPU or encoder load, available disk space if recording locally, network status and YouTube's stream-health messages. Keep the console output available for diagnosis and note the time of any interruption.

Recovery depends on the failure. A temporary network interruption may require a retry or a fresh publish. An invalid key requires the current YouTube credentials. A missing media file requires correcting the playlist. A computer restart requires starting the process again. Do not describe any of these as automatic merely because the command contains -stream_loop -1.

If you build a restart wrapper or operating-system service, test it separately with a harmless short playlist. The correct configuration depends on your operating system, shell, permissions and how YouTube handles the reconnect. There is no single restart command that is safe to recommend for every host.

This is also where the choice between running FFmpeg yourself and using a managed workflow becomes practical. Self-hosted FFmpeg gives you direct control over files, encoding and logs, but you remain responsible for the computer, connection and recovery process. A cloud workflow removes the need to keep your own computer running for the broadcast; StreamNeo is designed for the specific pain of uploading a file once, supplying the YouTube key and having the broadcast monitored and restarted without installing software on your computer.

For a broader comparison of those operating models, see FFmpeg or OBS for prerecorded 24/7 streaming. If your main concern is whether a long-running channel can make credible uptime claims, read what uptime can and cannot be promised. The useful question is not which method sounds simplest, but which failure modes you can test and respond to.

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 loop several videos forever?

Yes. Put the files in a concat playlist and use -stream_loop -1 with that input. The files still need compatible streams, codecs and time bases, and the loop does not restart FFmpeg if the process itself stops.

Should I use -re for a YouTube playlist?

For prerecorded input, -re tells FFmpeg to read at approximately the media's native rate instead of sending it as quickly as possible. It controls input pacing, not upload reliability or YouTube event health, so confirm the behaviour with your installed FFmpeg build and test files.

Can I use stream copy instead of encoding?

You can use -c:v copy -c:a copy when every source and the ingest output are already compatible. For mixed resolutions, codecs, frame rates or audio layouts, re-encode the files to a common format or use a deliberate output encoding workflow.

Will YouTube keep a 24-hour archive of the stream?

Do not rely on it. YouTube's guidance says a stream exceeding 12 hours may not be captured at all, so keep a local recording if the broadcast needs to be preserved and check that the recording is being written.

YOU’VE REACHED THE END

Keep the ideas coming.

More guides, useful tools and a little help for your next broadcast.

Back to the journal ↗
YOUR NEXT READ

A little more to explore.

More Setup Guides guides ↗ · All topics ↗