For a prerecorded MP4 with video and audio, a practical starting point for looping it to YouTube Live is FFmpeg with -stream_loop -1 and -re before the input file. Those options repeat the file and pace its reading for live output, but they do not guarantee a gapless loop, a successful ingest or automatic recovery after a failure.
The command below is a template, not a universally best setting. Match its bitrate and keyframe interval to the actual output and the connection, use the ingest details shown in YouTube Live Control Room, and test the file before relying on it overnight.
What this command is designed to do
This example reads one MP4, encodes its video as H.264 and audio as AAC, then sends the output to YouTube over RTMPS. The input is repeated indefinitely by FFmpeg. Replace input.mp4 with your file and YOUR_STREAM_KEY with the key for the intended YouTube live stream.
ffmpeg -re -stream_loop -1 -i input.mp4 \\
-c:v libx264 -preset veryfast \\
-b:v 10M -maxrate 10M -bufsize 20M \\
-g 60 -keyint_min 60 -sc_threshold 0 \\
-c:a aac -b:a 128k -ar 44100 \\
-f flv "rtmps://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY"
This is a straightforward starting point for a single prerecorded file, not a promise that every FFmpeg build, MP4, operating system or channel will accept it as written. The command does not force resolution or frame rate: those generally follow the source and encoder behaviour. Nor does it add a second file, a playlist, a fallback image or process supervision.
The example assumes libx264 is available in your FFmpeg build. If it is missing, or cannot encode at the required pace on the machine, select an encoder available to you and verify how it handles bitrate and keyframes. FFmpeg's installed help and build configuration are relevant; do not assume options behave identically across encoders.
For a playlist of separate files, the input and transition problem is different from repeating one MP4. The guide to looping multiple MP4 files on a 24/7 YouTube livestream covers that separate case. If your aim is one continuous ambience file, first make sure the source itself has a usable beginning and end.
Repeat the input with -stream_loop -1
-stream_loop is an input option. FFmpeg documents -1 as repeating the input indefinitely; the option applies to the file that follows it. In the sample, it is placed before -i input.mp4, so FFmpeg reopens and reads that input again when it reaches its end.
“Indefinitely” describes repetition, not the perceived smoothness of the join. If a rain recording ends with a sudden cut, that cut will recur on every pass. A soft room tone may still have a noticeable change in background noise, and a soundtrack may click if its first and last audio samples do not meet cleanly. Inspect and listen across the join in the actual source before broadcasting it for hours.
A single-file loop is easier to reason about than a folder of clips, but it also repeats any defect in the file. Check that audio and video both decode to the end, that the intended duration is correct, and that the final frame and sound lead naturally back to the opening. FFmpeg's loop option establishes replay; it does not edit or crossfade the boundary for you.
The 24/7 study playlist example using FFmpeg is useful if you are deciding whether one long asset or a playlist fits your channel. Whatever the format, create a deliberate test rather than assuming an export that plays in a media player will behave identically when read and looped by a live encoder.
Pace the file with -re
A file can be read much faster than its recorded playback duration when a program processes it offline. -re tells FFmpeg to read at the input's native rate. That pacing is useful when sending a file as a live stream, because the encoder should deliver media in time with playback rather than racing through the whole recording.
The sample puts -re before -i, next to the loop option, so it controls reading of input.mp4. It does not create a live camera feed, improve the source quality or guarantee that output timestamps and network delivery will suit every source. It is also not a substitute for watching the live ingest: connection fluctuations and encoder load remain operational concerns.
Keep the source's native frame rate and dimensions unless you have a clear reason to convert them. If you do scale or change frame rate, make that decision explicitly and then recheck the output settings, bitrate and keyframe interval. A 25 fps file and a 30 fps file do not have the same frame count over a two-second interval, even though each interval lasts the same time.
For quiet ambience, “native rate” matters to timing as well as picture. Listen for pauses, sudden level changes and any mismatch between the visual loop and the audio loop. A 24/7 rain sounds stream on a Raspberry Pi raises the additional question of whether the chosen machine can sustain encoding and network work continuously; do not infer that capability from the command alone.
Why both options come before -i
FFmpeg's command line is organised around inputs and outputs. Input options apply to the next input file, while output options apply to an output. Therefore -re -stream_loop -1 -i input.mp4 associates both options with that MP4. Moving them after -i changes their position in relation to the input and can cause FFmpeg to interpret them differently or report that an option is being used in the wrong context.
This placement is not cosmetic. In a command with several inputs, the position tells FFmpeg which source to pace or repeat. If you later add a separate audio file, for example, decide deliberately whether it too should repeat and at what rate. Do not copy the two options to the end of a longer command and assume they still refer to the video file.
The same boundary helps when reading the rest of the command. -i input.mp4 identifies the source. Codec, bitrate, audio and output muxing options follow it and configure the output sent to YouTube. The destination is last. When diagnosing an error, check option placement as well as spelling and quoting, especially if a shell command has been adapted or wrapped in a script.
The FFmpeg documentation describes command-line options and the input-specific behaviour of -stream_loop and -re. It is the right reference when adding inputs or changing syntax; this article's command should not be treated as a verified invocation for every version or build.
Review the video and audio settings
YouTube's encoder settings guidance covers supported ingest protocols, codecs, bitrate recommendations, keyframes and audio. For an RTMP(S) workflow it recommends RTMPS, lists H.264, H.265 and AV1 video options, and recommends a two-second keyframe interval, with no more than four seconds between keyframes. Use the settings for the actual format and check the Live Control Room rather than assuming the sample is right for your channel.
| Setting in the example | What it means | What to check |
|---|---|---|
-c:v libx264 |
Encodes video with H.264 using the x264 encoder | Confirm your FFmpeg build includes it and that the chosen encoder can sustain the output rate |
-b:v 10M -maxrate 10M |
Sets a 10 Mbps target and a matching maximum rate | Compare the intended resolution and frame rate with YouTube's guidance and the reliable upload capacity |
-bufsize 20M |
Sets the encoder's rate-control buffer | Verify the rate-control behaviour for your encoder and build; this is not a promise of constant delivery |
-g 60 -keyint_min 60 -sc_threshold 0 |
Requests a 60-frame GOP and limits keyframe changes tied to scene detection | Relate frame count to the output frame rate and inspect the resulting stream configuration |
-c:a aac -b:a 128k -ar 44100 |
Encodes AAC audio at 128 kbps and 44.1 kHz | Check channel layout and audio level as well as codec and sample rate |
-f flv and RTMPS URL |
Packages output for the RTMP(S) destination | Use the ingest address and stream key provided for the live event |
The 10 Mbps video target is a reasonable 1080p30 H.264 starting value, not a universal recommendation. YouTube Help lists 5 Mbps minimum and 14 Mbps recommended for 1080p30 H.264; for 1080p60 it lists 6 Mbps minimum and 17 Mbps recommended, and for 720p30, 3 Mbps minimum and 8 Mbps recommended. These are ingest guidance figures, not guarantees of visible quality or of what your internet connection can carry.
The GOP values deserve particular attention. -g 60 means 60 frames, not two seconds by itself. It corresponds to two seconds at 30 fps; at 25 fps, a value around 50 frames corresponds to that interval. Match the setting to the actual output frame rate, then confirm the stream rather than relying on the input file's metadata or a copied number.
The audio options convert the source audio to AAC rather than passing its original codec through unchanged. YouTube's advanced audio guidance recommends stereo AAC at 128 kbps and 44.1 kHz. If the file is mono, has multiple tracks or contains audio you do not want, inspect those properties before encoding; the short command does not select tracks or repair levels.
CBR is YouTube's recommendation for rate control. Matching -b:v and -maxrate is a practical approximation in this example, but actual encoder behaviour depends on the build and settings. Choose a sustainable output based on a reliable upload connection and test the upload bitrate. A nominal broadband speed or a short successful run does not establish that the connection will remain stable through a long broadcast.
Connect to YouTube Live using the channel's details
Create or open the intended live stream in YouTube Live Control Room and use the ingest address and stream key it supplies. The sample shows YouTube's RTMPS endpoint form, but the precise settings displayed for your stream are the reference. YouTube recommends RTMPS, a secure extension to RTMP, for this workflow.
Treat the stream key as a credential. Do not put a real key in a public tutorial, screenshot, shared script or support message. If a key is exposed, use YouTube's controls to replace it and update the command that needs it. Keep shell history and process logs in mind when deciding where to store it; a command that contains the key may be visible to other users of the machine.
The output format -f flv is part of this RTMP-style example. YouTube also documents HLS ingestion, but its HLS workflow uses playlists and M2TS segments with specified packaging and HTTPS requirements. It is not a matter of changing the URL in this command. Compare protocol support and workflow needs before changing ingest methods, and follow the official HLS ingestion documentation if that is the path you need.
If managing a machine and a long-running FFmpeg process is the part that makes this setup fragile, StreamNeo removes that specific burden for a prerecorded file: you upload it once, provide the YouTube stream key, and the broadcast can continue with your own computer switched off, with monitoring and automatic restarts if it drops. It is YouTube-only, and it does not remove the need to check your content, stream settings and live health.
Test the stream before relying on the loop
First run a short private or otherwise suitable test with representative sound and picture movement. Watch it in YouTube Live Control Room and check stream health and any messages, as YouTube advises. A static thumbnail or a few seconds of playback cannot show every issue in a long file, so also inspect the output near the end and across the point where it returns to the beginning.
Listen on headphones for a click, abrupt change in room tone, clipped sound or an unexpected silence at the loop boundary. Watch for a jump in image, a black frame, a timing discontinuity or an error when the input repeats. If there is a defect, fix the source or choose a suitable editing approach; the loop flag will repeat the defect as faithfully as it repeats the rest of the file.
Observe whether the encoder keeps up and whether YouTube continues to report a healthy ingest. If the source is high resolution, the machine is under load, or the upload connection is shared, test under conditions close to the planned broadcast. Adjust the bitrate or output format only after identifying the constraint, and retest. Lowering a bitrate may help an upload bottleneck but cannot fix a broken source file or an unavailable encoder.
A loop is not process supervision. If FFmpeg exits after an error, -stream_loop -1 does not launch it again; if the network drops, the option does not restore the connection. For a channel where continuity matters, plan how the process will be observed and restarted, and how you will notice a loss of ingest. The guide to restarting a 24/7 YouTube stream after disconnection explains why recovery is a separate operational problem from making an input repeat.
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
Does -stream_loop -1 make the loop gapless?
No. It tells FFmpeg to repeat the input indefinitely, but does not guarantee a smooth audible or visual join. Inspect the source at its end and beginning, and test the repeated output for clicks, abrupt ambience changes or picture jumps.
Why is -re before -i?
It is an input option that paces reading of the following input at its native rate. Putting it before -i input.mp4 makes clear that it applies to that file; it is useful when sending prerecorded media as live output.
Is -g 60 always a two-second keyframe interval?
No. It specifies a frame count, so it is two seconds only at 30 fps. YouTube recommends a two-second interval and says it should not exceed four seconds; calculate the frame count for the actual output rate and verify the stream.
Will this command restart after a crash or network outage?
No. The loop option repeats the input while FFmpeg is running; it does not supervise or restart the process or recover a dropped connection. Test the ingest and arrange separate monitoring and recovery if continuous availability matters.