A rain video can be looped indefinitely with FFmpeg by placing -stream_loop -1 before the input file. Add -re before the file input when you want FFmpeg to read it at normal playback speed for a live broadcast rather than processing it as quickly as possible.
The command below is a starting pattern, not a tested universal recipe. You must replace the example ingest details, check the video and audio in your own file, and choose output settings that match YouTube’s current guidance and your upload connection.
What you need before starting
You need four things: a rain video you are allowed to broadcast, FFmpeg installed on the computer that will run the stream, a YouTube channel with live streaming available, and a stable upload connection. The computer must remain awake and connected for as long as FFmpeg is sending the broadcast.
Check the file before writing a command. Note its duration, frame rate, resolution, video codec and whether it contains an audio stream. A rain video may look complete in a media player while containing no audio at all. If the file is silent, adding -c:a aac does not create sound. You will need to provide an audio source, deliberately add silence, or choose a file that already contains suitable audio.
You should also inspect the start and end of the file. A loop flag repeats the file; it does not make the join seamless. If the final frame is a bright flash, the audio ends with a click, or the camera movement jumps at the boundary, viewers will notice the same problem every time the file repeats.
Keep the stream key private. Do not paste it into a public tutorial, screenshot, shared document or public shell history. The key gives software permission to send to your live event, so use placeholders while preparing the command and add the real value only when you are ready to run it.
If this is your first always-on channel, a written preflight is useful. The go-always-live checklist covers practical checks such as power, sleep settings, monitoring and the behaviour you expect when the source ends. It is easier to find a missing setting before a night-long broadcast than after the first interruption.
Finally, confirm that the visual and audio content can be used on your channel. A file found online may have restrictions even if it is easy to download. YouTube’s current live-stream policies and your own licence or permission are separate from the FFmpeg setup.
How the loop and real-time options work
The central option is:
-stream_loop -1
The -1 value means that FFmpeg should repeat the relevant input indefinitely. It is an input option, so it belongs before the -i that names the file it controls:
ffmpeg -stream_loop -1 -i rain.mp4 ...
This placement is important. FFmpeg options can apply to an input, an output, or both, and their position helps determine what they affect. Putting -stream_loop -1 after -i rain.mp4 is not the same command and may not produce the loop you intended.
The other important input option is -re:
-re -stream_loop -1 -i rain.mp4
For a file used as a live source, -re tells FFmpeg to read it at approximately its native playback rate. Without it, FFmpeg may read and encode the file faster than real time, which is useful for some file-processing jobs but not for sending a normal live programme. The option does not solve a slow connection, an unsuitable file or a broken source.
Together, the options mean: read the file at its normal pace, reach its end, start it again, and continue doing that. They do not mean that YouTube will accept every output, that the loop boundary will be invisible, or that the process will recover from every computer, network or application failure.
The same principle applies when you use separate audio. Looping the video input does not automatically give a separate audio input the same behaviour. Each input needs appropriate looping or duration logic, and you should use explicit mapping so that FFmpeg sends the intended video and audio streams. For a simple first test, a single file containing both streams is easier to reason about.
YouTube’s encoder guidance currently recommends RTMPS for live ingestion, supported codecs, constant bitrate operation and a keyframe interval of two seconds, with no more than four seconds. Read the current YouTube encoder settings before choosing final values because the published guidance can change.
Get the YouTube ingest URL and key
Open YouTube Studio and create or open the live event you intend to use. In the Live Control Room, YouTube provides the server or ingest address and a stream key for the encoder. The exact screen can differ depending on whether you are creating a new stream or reusing an existing setup, so use the current instructions shown in your account.
The ingest address and key are separate pieces of information. In a command, they are commonly joined into a destination resembling:
rtmps://YOUR_INGEST_URL/YOUR_STREAM_KEY
That line is only a placeholder. It is not a valid address, and you must not publish your real key in its place in an article, a screenshot or a support forum. Copy the values from your own YouTube Live Control Room and follow the format YouTube supplies.
Treat the key like a password for the encoder. If you think it has been exposed, reset or regenerate it in YouTube before broadcasting. If you are using a shared computer, consider whether the shell history, process list or saved scripts can reveal it. A private script with appropriate file permissions is safer than a public code snippet.
YouTube supports more than one ingestion approach. RTMP or RTMPS sends a continuous stream and is the simpler default for a basic FFmpeg rain loop. HLS is designed around segments and playlists and can be useful for particular codec or HDR requirements, but it adds configuration and latency. YouTube’s current HLS requirements are described in its HLS ingestion documentation.
For this setup, use the RTMPS destination shown for your event unless you have a specific reason to use HLS. The protocol choice does not remove the need to check stream health, audio, bitrate and the channel’s live-stream settings.
Build the FFmpeg command
Here is a copyable command skeleton:
ffmpeg -re -stream_loop -1 -i rain.mp4 \
-c:v libx264 -preset veryfast -b:v 4500k -maxrate 4500k -bufsize 9000k \
-pix_fmt yuv420p -g 60 \
-c:a aac -b:a 128k -ar 44100 \
-f flv 'rtmps://YOUR_INGEST_URL/YOUR_STREAM_KEY'
This is an illustrative pattern, not a tested command for every operating system, FFmpeg build, file or YouTube profile. The bitrate, frame rate assumptions and encoder availability must be checked against your source and destination.
The first line controls the file input. -re requests real-time reading, -stream_loop -1 requests indefinite repetition, and -i rain.mp4 names the source. Replace rain.mp4 with the actual path. If the path contains spaces, quote it, for example:
-i '/home/name/videos/rain at night.mp4'
The video options select H.264 through libx264, use the example preset veryfast, and request a video bitrate through -b:v. The -maxrate and -bufsize values are also examples of a constant-rate-style configuration. They are not a claim that 4,500 kilobits per second is correct for your resolution or frame rate.
The example uses -pix_fmt yuv420p, a broadly compatible pixel format, and -g 60, which requests a 60-frame GOP. At 30 frames per second, 60 frames represents a two-second keyframe interval. If your output is 25, 29.97, 50 or 60 frames per second, change the GOP value to match the intended interval rather than copying 60 automatically.
The audio options select AAC, request the example audio bitrate of 128k, and set the sample rate to 44100. These values are examples, not proof that the source contains audio or that the result suits every channel. If FFmpeg reports that the input has no audio stream, stop and decide how you want to provide or handle audio before attempting a live broadcast.
Finally, -f flv selects the container commonly used for RTMP-family output, and the quoted destination sends that output to YouTube. Do not remove the quotes if your shell needs them, and do not leave the placeholder destination in a real broadcast command.
Replace the example settings for your source
The sample video bitrate is deliberately not presented as optimal. Select a bitrate from YouTube’s current table for the resolution, frame rate and codec you intend to send, then check whether your upload connection can sustain the total output with some practical headroom. YouTube currently lists H.264 recommendations of 14 Mbps for 1080p30, 17 Mbps for 1080p60, and 8 Mbps for both 720p30 and 720p60 on its encoder settings page. These are YouTube-published configuration recommendations, not independent performance measurements, and they should be rechecked before use.
| Output profile | YouTube H.264 bitrate listed on the current help page | What to check before using it |
|---|---|---|
| 720p30 | 8 Mbps | Stable upload capacity and a matching frame rate |
| 720p60 | 8 Mbps | Whether the source genuinely benefits from 60 fps |
| 1080p30 | 14 Mbps | Upload capacity, source quality and encoder load |
| 1080p60 | 17 Mbps | Upload capacity and whether 60 fps is necessary |
The figures in the table are included to show why the command’s 4500k example must not be treated as a universal answer. A lower-resolution rain loop may not need the same output as a 1080p source, while a higher-resolution profile may require considerably more than the example. Match the output to the source instead of upscaling a small file merely to select a larger profile.
Frame rate is part of the decision. A static or gently moving rain scene may not need 60 fps. If the source is 30 fps, sending it as 60 fps can increase processing without adding real motion detail. Keep the output predictable and set -g for the selected frame rate and approximately two-second keyframe interval.
Resolution can be set explicitly when you need the output to match a chosen profile. For example, a scaling option might look like this:
-vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2"
That is another example, not a universal addition. Scaling changes the output dimensions and may add processing. Test it with your file, and avoid stretching a 16:9 rain scene into a different shape. If the source already has the desired dimensions, leaving out the filter may be simpler.
Check the encoder available in your FFmpeg build. libx264 may not be present in every installation, and hardware encoders use different names and controls. If you change codec or encoder, revisit YouTube’s supported formats and bitrate guidance instead of assuming that the H.264 values apply unchanged.
If you use a separate audio file, give it its own input and map it deliberately. A conceptual pattern could be:
ffmpeg -re -stream_loop -1 -i rain-video.mp4 \
-re -stream_loop -1 -i rain-audio.m4a \
-map 0:v:0 -map 1:a:0 ...
This is incomplete by design. The correct duration, codecs, channel layout and mapping depend on the files. Test the two loop points independently because the video and audio may have different lengths. For the first broadcast, one file containing the intended video and audio is less complicated.
Test playback and audio before broadcasting
Do not begin with a public all-night broadcast. First run the command with a placeholder destination removed or use a local output that lets you inspect the encoded result. The aim is to find source, timing and audio problems before YouTube receives the feed.
Start by viewing the file normally and identifying its exact end. Watch the transition from the final frame back to the first frame. Listen with headphones for a click, a sudden change in volume, a gap or a repeated sound that becomes distracting. A technically successful loop can still be unpleasant to watch.
You can also run FFmpeg with a short local test output, depending on your installation and preferred player. For example, writing a small test file lets you check that the selected encoder, pixel format and audio settings are accepted:
ffmpeg -re -stream_loop -1 -i rain.mp4 \
-t 120 -c:v libx264 -preset veryfast -b:v 4500k \
-pix_fmt yuv420p -g 60 -c:a aac -b:a 128k -ar 44100 \
test-output.mp4
The -t 120 value is only a two-minute test example. It does not test an entire overnight run, and it does not reproduce every property of YouTube ingestion. Use the output to check whether video and audio are present, whether the process reports errors and whether the loop boundary occurs as expected.
For a more realistic check, create an unlisted YouTube live event and send a short test using the same file, output profile and connection you plan to use. YouTube recommends testing with similar audio and movement, checking stream health and watching its messages during the broadcast. Unlisted visibility lets you inspect the result without immediately presenting it as a public channel programme, but it does not answer questions about content rights or channel policy.
Watch for a stable picture, continuous sound, correct aspect ratio, sensible volume and a clean repeat. Check the dashboard for warnings about bitrate, dropped frames, connection quality or encoding. If the dashboard reports trouble, reduce the complexity or output demand and test again rather than assuming the warning will disappear during a longer run.
Common failures have identifiable causes. If the file plays once and stops, check that -stream_loop -1 is before the correct -i. If the stream runs too quickly, check that -re is before the file input. If there is no sound, inspect the input streams and decide whether you need a real audio source or deliberate silence. If the image is unstable, compare the chosen bitrate with YouTube’s current profile guidance and your measured upload capacity.
For audio-specific problems, the guide on fixing audio out of sync in an OBS pre-recorded YouTube stream is useful even if your final encoder is FFmpeg. The underlying checks are similar: compare the source tracks, watch the repeat boundary and confirm that the output remains aligned over time.
Start the YouTube Live feed and keep it observable
When the test is acceptable, create or open the intended event, paste the private ingest details into the command and start FFmpeg. Keep the terminal visible during the first part of the broadcast. You should be able to see whether FFmpeg continues reading, encoding and sending rather than leaving the process unattended immediately.
In YouTube Studio, monitor stream health and the preview. Check the title, visibility, scheduled settings and description before making the stream public. If you plan to use an unlisted or members-only event, review the visibility choices for 24/7 streams before selecting the audience setting.
A computer-based FFmpeg stream depends on that computer, its power, its network and the process itself. Disable sleep and automatic shutdown, but do not assume those changes provide uninterrupted operation. A reboot, operating-system update, lost connection, process crash or changed YouTube event can still interrupt delivery. The loop flag only controls what FFmpeg does when it can read the file and send output.
If you need the file and stream to continue while your own computer is switched off, StreamNeo removes the specific burden of leaving FFmpeg running locally: upload the file, provide your YouTube stream key, and let the cloud broadcast handle the repeat with automatic monitoring and restart behaviour. It remains your responsibility to check the content, channel settings and YouTube’s current requirements.
For a longer-term channel, keep a simple record of the file version, command settings, event details and the last successful test. Do not record the actual stream key in that document. If you change the source, frame rate, audio track or network, repeat the pre-stream test instead of treating the previous result as proof that the new setup is sound.
A single rain file can be the beginning of a wider library, but variety is not automatically better. Several files with different lengths can make the programming less repetitive, while each extra input creates more opportunities for mismatched audio, rights questions and unclear monitoring. If you are building multiple channels, compare the workflow in the guide to running three or more niche loop channels from one library.
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
How do I loop a video with FFmpeg?
Put -stream_loop -1 before the input it should repeat, such as ffmpeg -stream_loop -1 -i rain.mp4. Add -re before the file input when the file is being used as a real-time live source. Test the file’s end-to-start transition because indefinite repetition does not create a seamless edit.
How do I loop a video on YouTube Live?
Use FFmpeg to read the file in real time, encode it in a YouTube-supported format and send it to the RTMPS ingest address and private key from your Live Control Room. Test first with an unlisted event or equivalent pre-stream workflow, and monitor YouTube’s stream-health messages. The command does not guarantee uninterrupted delivery if the computer, network or process fails.
How do I stream a pre-recorded video on YouTube Live?
Use a file with the intended video and audio, select output settings for its resolution and frame rate, and send the encoded stream to YouTube’s own ingest details. Check the current YouTube encoder guidance before choosing bitrate and keyframe settings. A pre-recorded file still needs live-style monitoring because encoding and network problems can affect the broadcast.
How do I make a rain video play continuously?
Use -stream_loop -1 before the rain video input and keep -re before that input for normal playback timing. Inspect the loop boundary for flashes, jumps, clicks or gaps, and replace or edit the source if the repeat is distracting. If you need the stream to continue without your computer running, use a suitable managed workflow and still check the resulting YouTube broadcast.