Skip to content
streamneo.
Streaming Settings11 min read

How to Loop MP4 Videos in FFmpeg for a Continuous YouTube Live Stream

Place FFmpeg’s loop and pacing options correctly, configure YouTube ingest, and test the feed without assuming looping ensures uptime.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

To loop an MP4 into a YouTube Live stream, put -stream_loop -1 before that file’s -i option, then use -re before the input so FFmpeg reads the file at its normal rate. You still need a supported output, the stream URL and key from YouTube Studio, and a way to check the feed; looping by itself does not keep a broadcast healthy around the clock.

The command below is a starting pattern, not a tested, ready-to-run guarantee. Replace the output destination with the exact details YouTube gives you, choose settings for your file and upload connection, and test the loop boundary before relying on it.

What continuous looping means in FFmpeg

An MP4 file normally reaches its end and stops producing frames. FFmpeg’s -stream_loop -1 tells it to repeat the input indefinitely, so the encoder can keep receiving media from that file. The option applies to an input, rather than creating a new video or making a finished upload repeat on YouTube by itself.

“Indefinitely” describes the requested input behaviour, not the health of the whole broadcast. FFmpeg can encounter a decode error, lose its connection to YouTube, run out of processing capacity, or send material that does not meet the selected output settings. A repeated file can also have an audible or visible jump at the join. Treat the loop as one part of a live encoding workflow, then validate the resulting stream.

This guide covers one MP4. A playlist with changing files has more constraints: the clips may need compatible stream layouts and timing, and a concat workflow is a separate configuration problem. If you are deciding whether a single computer should run unattended, the trade-offs of running a prerecorded channel from a home computer are relevant too.

Put -stream_loop -1 before the input

FFmpeg options are positional. Input options apply to the input that follows them, so place the loop option before the matching -i. For one file, the essential pattern is:

ffmpeg -stream_loop -1 -i input.mp4 ...

Here, input.mp4 is the file to repeat. The -1 value requests infinite looping; omitting it or putting the option after the input can produce a different result from the one intended. FFmpeg documents its command-line options and input handling in the FFmpeg documentation.

If your command has several inputs, keep each input’s options immediately before its own -i. Do not assume an option written later will change how FFmpeg reads a file it has already opened. When diagnosing a command, check the order from left to right: options, input, output options, output.

Looping does not automatically repair the source. An MP4 can contain streams, timestamps, or audio layouts that need attention. If FFmpeg reports errors at the end of the file, note whether they recur at each repeat and inspect the input rather than hiding the message. For audio-heavy material, a repeated join deserves a listen: a small click or abrupt room-tone change can become conspicuous after hours.

Use -re to pace a file input

A file can be read faster than real time unless you tell FFmpeg to limit its reading pace. Put -re before the file’s -i to read it at its native frame rate, making the file behave more like a live feed for encoding. With loop and pacing together:

ffmpeg -stream_loop -1 -re -i input.mp4 ...

Both options precede the input because both describe how FFmpeg should read that file. The loop requests another pass when the input ends; pacing stops FFmpeg from racing through repeated passes as quickly as it can. The two options do different jobs.

Do not put -re on an actual live input. A camera or other live source already arrives in real time; adding file-style pacing can constrain it incorrectly. The distinction matters if you later adapt a command that combines prerecorded material with a live source. FFmpeg’s guidance on realtime input reading is in its command-line documentation.

Pacing also does not make an underpowered computer capable of encoding the chosen output. If processing takes longer than the media being read, the outgoing feed can fall behind or fail. Watch FFmpeg’s console output during a test, especially its reported speed and errors, and reduce the workload or use a more suitable encoding path if it cannot keep up.

Get the YouTube stream URL and key

In YouTube Studio, create or select an encoder stream and copy the server URL and stream key shown for it. The encoder sends video to the server URL using the key as the stream’s credential. YouTube’s encoder setup instructions describe that process; follow the current Studio workflow rather than relying on an old saved endpoint.

Treat the key like a password. Do not post it in a public command, screenshot, support forum, or source repository. If it is exposed, replace or reset it through Studio. A command pasted into a public article or shared log should always use a placeholder, not a real key.

Before configuring FFmpeg, confirm the channel can stream live. YouTube’s live streaming eligibility and setup guidance says channel verification is required and that restrictions on live streaming in the preceding 90 days affect eligibility. Check that official page for current requirements; do not assume an encoder command can overcome a channel restriction.

YouTube may provide RTMP or RTMPS details for the stream. Its encoder settings guidance recommends RTMPS, so use the secure endpoint when it is supplied for your stream. Do not copy the example destination in a blog post as though it were necessarily the right one for your account: use the exact server URL and key arrangement that Studio presents.

Configure a supported live output

For a broadly compatible baseline, the example below re-encodes video as H.264 and audio as AAC, then sends an FLV live output. It is an illustrative 30 fps pattern, assembled from documented options; it has not been run against your source file or account:

ffmpeg -stream_loop -1 -re -i input.mp4 \
  -c:v libx264 -preset veryfast -b:v 4500k -maxrate 4500k -bufsize 9000k \
  -g 60 -keyint_min 60 -sc_threshold 0 \
  -c:a aac -b:a 128k -ar 44100 \
  -f flv "rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY"

The destination shown is a placeholder pattern, not a substitute for the URL from Live Control Room. Replace it with the endpoint YouTube provides and put the key in the form expected by your encoder. Keep it private. The example’s bitrate is not a universal recommendation: it must be chosen for your actual resolution, frame rate, codec, and dependable upload capacity.

YouTube’s current encoder guidance accepts multiple video codecs, including H.264, H.265/HEVC, and AV1, and lists AAC or MP3 audio. H.264 with AAC is used here to keep the sample straightforward, not because it is the only accepted combination. Use YouTube’s published encoder settings to select settings for the output you intend to send.

This sample re-encodes so the output bitrate, keyframe behaviour, and audio codec can be specified. That takes processing capacity. A stream-copy experiment using -c copy avoids re-encoding, but only makes sense when the input codecs, container handling, and timestamps are compatible with the destination. Copying does not let FFmpeg reshape the stream to meet a chosen bitrate or keyframe interval, and loop-boundary timestamps may still cause trouble. It is a test to run against a suitable file, not a universal shortcut.

If the command fails, first check that the file path exists, the key and URL are correct, and the output codecs and format are supported. Then read the complete FFmpeg error output. A re-encoded baseline can help isolate a copy-related problem, but it cannot guarantee a fix for a damaged source, network interruption, or any other fault.

Set the keyframe interval and bitrate mode

YouTube recommends constant bitrate encoding and a keyframe interval of two seconds, not exceeding four seconds. In the sample, -g 60 and -keyint_min 60 target a two-second group of pictures at 30 frames per second; they are not magic values for every frame rate. For a different frame rate, choose a GOP length that corresponds to the target interval, and check the encoder output rather than blindly retaining 60.

The -b:v value sets the target video bitrate in this example; -maxrate and -bufsize help constrain rate behaviour for the encoder. The command uses equal target and maximum values as a simple CBR-oriented setup, but you should confirm the encoder’s actual behaviour and use the settings YouTube currently recommends for your output. The keyframe and bitrate guidance is YouTube’s, while FFmpeg option effects depend on the encoder and command.

Choose a bitrate against resolution and frame rate, then against the upload connection you can sustain. YouTube’s current H.264 recommendations include 8 Mbps for 720p at 30 fps, 10 Mbps for 1080p at 30 fps, and 17 Mbps for 1080p at 60 fps; it recommends 128 Kbps for stereo audio. These are platform recommendations, not guarantees that a particular connection or encoder will work. The sample’s 4500k video value therefore should not be mistaken for a YouTube recommendation for those output sizes.

Output example YouTube H.264 video recommendation What to check
720p at 30 fps 8 Mbps Whether the source and planned output are actually 720p and 30 fps
1080p at 30 fps 10 Mbps Whether dependable upload capacity can sustain the stream
1080p at 60 fps 17 Mbps Whether both encoder capacity and upload can support the higher frame rate
Stereo audio 128 Kbps Whether the source audio is stereo and sounds clean at the repeat point

Use the row matching the format you plan to send, and consult the full YouTube encoder bitrate table for other combinations and current details. A lower output that stays stable in your test is more useful than a nominally sharper setting that repeatedly overloads the connection. If the central question is constant versus variable rate behaviour, the discussion of CBR and VBR for prerecorded YouTube streams helps frame that decision.

Test the stream and watch its health

Test with the same file, command, output settings, and internet connection you will use for the intended channel. Watch the preview in Live Control Room where the stream workflow provides one, and check YouTube’s stream health messages while FFmpeg is running. Listen to audio across the file’s end and restart point; inspect whether motion or the picture jumps there. A command starting without error is not proof that the audience receives a stable, intelligible feed.

For an event or an unattended channel, test long enough to encounter the repeat boundary and to see whether the local connection and encoder continue to behave. If the source is long, a brief start-up check will not tell you how its ending behaves. Note the FFmpeg version, the command with the key removed, the console error, the input’s stream information, and whether the issue happens at the boundary. Those details make troubleshooting more concrete than “it stopped looping”.

If video is present but the sound drifts, breaks, or jumps at each repeat, inspect the audio stream and timestamps rather than only changing the bitrate. For a long ambient feed, steps for diagnosing audio that drifts out of sync can help distinguish a source or timing problem from a network fault. If the connection drops after running for a while, compare the symptoms with RTMP timeout troubleshooting; a loop option does not reconnect by itself.

YouTube says streams under 12 hours are automatically archived, according to its encoder setup guidance. That statement is about archiving, not a promise that an encoder can run indefinitely or that a particular stream will remain available. Confirm the current platform behaviour and decide how you will handle a dropped connection, an interrupted source, or a need to start a new broadcast. If you need a file to run while your own computer is off, StreamNeo removes that specific need to keep your computer broadcasting by turning an uploaded video into a YouTube live stream that it monitors and restarts if it drops.

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 alone make a 24/7 YouTube stream?

No. It asks FFmpeg to repeat an input indefinitely, but it does not provide YouTube’s destination and key, encode supported output, maintain a network connection, or repair a source error. Test the whole path and plan how you will detect a failure.

Where do -stream_loop -1 and -re go?

For a prerecorded MP4, put both before the matching -i, as in ffmpeg -stream_loop -1 -re -i input.mp4 .... The loop option repeats that input; -re paces the file at its native rate. Do not use -re to pace an actual live input.

Can I use -c copy instead of re-encoding?

Sometimes, if the input streams and timestamps are compatible and the output does not need a different codec, bitrate, or keyframe pattern. Copying uses less encoding work, but does not normalise media and can fail at the loop boundary. Test it, and try a re-encoded baseline if the copy output breaks.

Does a repeated MP4 always join seamlessly?

No. The file may have an abrupt visual or audio ending, or timestamp behaviour that causes a playback discontinuity. Inspect and listen to the transition in the actual YouTube preview, then adjust or replace the source if the join is distracting.

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 Streaming Settings guides ↗ · All topics ↗