Skip to content
streamneo.
Troubleshooting13 min read

How to Keep FFmpeg Streaming to YouTube After a Video Ends

Learn when to loop a file, how FFmpeg HTTP reconnect flags work, and why input recovery does not restore YouTube publishing.

sn.
StreamNeoPublished 3 October 2026
Worth sharing?

A finite video makes FFmpeg exit when it reaches the end unless you tell FFmpeg to loop that input. For a local file intended to repeat, use -stream_loop -1 before the relevant -i, and use -re so the file is read at its normal frame rate for live output.

That fix is different from reconnecting a network input. FFmpeg’s HTTP reconnect options apply to the current HTTP input only; they do not restore every kind of source, repair YouTube publishing, or make a stopped live event continue by themselves.

Determine which connection disconnected

Start by finding out what actually stopped. “The stream ended” can describe several different events, and each needs a different response.

If FFmpeg runs until roughly the duration of a local MP4 and then exits normally, the input reached end-of-file. Nothing disconnected. The process finished because it had no more packets to read. In that case, a reconnect flag is the wrong tool. You need to repeat the file, prepare a sequence of files, or end the broadcast as planned.

If FFmpeg is still running but reports that an HTTP input cannot be read, the source connection may have failed. HTTP reconnect options may help with that particular input, depending on the protocol and the failure. They are not a general restart system for the whole command.

If FFmpeg reports a write error, a broken publishing connection, an encoder error, an invalid stream, or an interruption while sending to YouTube, investigate the output side separately. A file loop can keep generating frames while the YouTube connection is already gone. Conversely, reconnecting an HTTP source does not make YouTube accept an incompatible or incomplete output.

Look at the last meaningful lines in the FFmpeg log rather than relying on whether the terminal window is open. An orderly end after the input duration points towards end-of-file. A protocol, read, write, timestamp, or encoder error points towards a different fault. The distinction matters before you change a command that may already be working as designed.

Loop a finite file when repetition is intended

For a local file that should continue from its beginning, the basic shape is:

ffmpeg -re -stream_loop -1 -i input.mp4 [your existing mapping and encoding options] -f flv "$YOUTUBE_RTMP_URL/$STREAM_KEY"

This is a template, not a complete command for every channel. Keep the mapping, codecs, output options, server URL, and stream key that match your setup. Keep the key private, including when sharing a screenshot or asking for help.

-stream_loop -1 tells FFmpeg to loop the input indefinitely. -stream_loop 0 means no loop. Both options belong to the input, so they need to appear before the -i they affect. The FFmpeg documentation describes the loop values and the distinction between an ordinary input and an infinite loop.

-re makes FFmpeg read the file at its native frame rate, also described by FFmpeg as reading at the equivalent of -readrate 1. That pacing is useful when a file is being used as a live source. Without it, a file-based command may read as quickly as the machine and storage allow, which is not the behaviour you want for a real-time broadcast.

Do not add a low read rate to a real camera or another source that is already live. FFmpeg warns that reducing the reading rate on an actual capture input can cause packet loss. The option is useful here because a normal file has to be paced; it is not a universal live-input repair.

With more than one input, place the loop and pacing options before the corresponding -i. For example, a file used as background content may need these options while a separate microphone or camera input should be handled according to its own timing and failure behaviour.

A loop is an editorial decision as well as a technical one. Check that repeating the content is intended and that you have the necessary rights or permission to keep showing it. YouTube’s live-streaming tips also recommend testing the result and checking the preview, stream health, audio, and video before relying on it.

Understand what HTTP reconnect options do

HTTP reconnect options are for an HTTP input that temporarily fails or reaches a condition where FFmpeg can try the same HTTP resource again. They do not turn a finite file into an infinite source, and they do not apply automatically to every input type in your command.

The important scope is the current HTTP input. If your command reads a remote media URL with HTTP, options such as -reconnect, -reconnect_streamed, -reconnect_on_network_error, -reconnect_max_retries, and -reconnect_delay_max may be relevant, subject to the FFmpeg version and the behaviour of that server. Read the FFmpeg manual installed alongside the build you are using, because protocol options and support can vary between versions.

A reconnect attempt means FFmpeg tries to establish or continue that input connection. It does not mean that FFmpeg refreshes an expiring media URL, obtains a new authorisation token, recreates a playlist session, or understands an application-specific API. If the address itself has expired or the remote service requires a new URL, a retry of the old request may simply repeat the same failure.

This is also why you should not paste HTTP reconnect flags into a command merely because the destination is YouTube. An RTMP or RTMPS publishing connection is an output in the usual YouTube command shape. The HTTP input options describe the source being read, not a universal setting for all network traffic in the process.

For a local file, there is no HTTP source to reconnect. Use -stream_loop -1 instead. For a live camera, diagnose the camera and capture path. For an incoming stream, identify its protocol and whether the source provider supports resuming. Classifying the input first prevents a plausible-looking option from solving the wrong problem.

Place reconnect flags before the input URL

Input options must be associated with the input they are meant to control. Put the relevant HTTP options before that input’s -i and URL, not after the YouTube output destination.

A command shape might look like this:

ffmpeg [HTTP input reconnect options] -i "https://example.invalid/media" [mapping and encoding options] -f flv "$YOUTUBE_RTMP_URL/$STREAM_KEY"

The address above is only a placeholder. Use the real source URL, and do not expose a signed URL or stream key in a public post. The example shows placement, not a guaranteed combination for a particular provider.

If the command has two inputs, keep each input’s options with its own URL. A reconnect setting intended for the first HTTP source should not be assumed to control a second input, a local file, or the output. Keeping the command grouped in this way also makes later diagnosis easier.

The same placement principle explains the local-file form:

ffmpeg -re -stream_loop -1 -i input.mp4 [options] -f flv "$YOUTUBE_RTMP_URL/$STREAM_KEY"

Do not move -stream_loop -1 after -i input.mp4 and assume it still describes that file. If you change the order while troubleshooting, inspect the startup log and confirm that FFmpeg has applied the option to the intended input.

YouTube requires the server URL and stream key for an encoder connection. Its encoder workflow explains how those values are used and says that ending a stream involves stopping the content sent from the encoder. Treat the key as a credential rather than as harmless example text. If it has been exposed, rotate it in YouTube Live Control Room.

Bound the retry count and delay

An unattended command should not retry forever without a policy. A bounded retry pattern gives you a defined number of attempts or a defined retry window, followed by a clear failure that an operator or supervisor can act on.

For HTTP inputs, the relevant FFmpeg options include a maximum retry count and a maximum reconnect delay. The exact option names and accepted values should be checked in the manual for your installed build. A conceptual command shape is:

ffmpeg -reconnect 1 \
  -reconnect_on_network_error 1 \
  -reconnect_max_retries <retry-count> \
  -reconnect_delay_max <delay-seconds> \
  -i "https://example.invalid/media" \
  [your existing output options]

The angle-bracket values are deliberate. Choose them from the failure you are trying to tolerate and verify the syntax against your local FFmpeg documentation. Do not copy a retry count as though it were a guarantee that a provider will recover within that time.

A short delay may be suitable for a brief network interruption but can create repeated requests while the remote service is unavailable. A longer delay gives the source more time to return but also leaves the output without fresh media for longer. More retries increase the time before a definite failure, not the likelihood that an expired URL or unavailable service will become valid.

If your policy is “try for a while, then stop and alert me”, use the options that bound attempts or total delay where your FFmpeg build supports them. If your policy is “keep the process alive indefinitely”, understand that this is a different operational choice and can hide a broken input for hours. An open process is not evidence that YouTube is receiving a valid broadcast.

For a finite local file, retry limits are beside the point. At the end of the file, the correct action is either to loop it or to move to the next planned item. Adding HTTP reconnect options to a local-file command does not create another pass through the file.

Test with the actual input type

Test the same input type, command structure, and output settings that you will use overnight. A short test with a local file can confirm that the loop option is placed correctly, but it cannot prove that a remote HTTP source will resume or that a YouTube publishing connection will survive a separate interruption.

For a file loop, watch the transition from the end back to the beginning. Confirm that both video and audio continue. Some files have timestamp, container, or codec characteristics that make the join less clean than expected. If you hear a pop, see a black frame, or notice a pause, investigate the media rather than assuming the loop option is defective. The guide on loop seams, black frames and audio pops covers that transition as a separate problem.

Use a private or unlisted test where appropriate. Open YouTube Live Control Room and check the preview and stream health, not only the FFmpeg terminal. The current YouTube encoder settings should be checked for the target resolution, frame rate, codecs, keyframe interval, and bitrate. Those settings support compatibility and quality, but they do not replace looping the input.

For an HTTP source, test the source under the conditions that caused the failure if you can reproduce them safely. Confirm from the logs whether FFmpeg attempted a reconnect, whether the source returned media afterwards, and whether the output remained healthy. A reconnect option that never activates is not evidence that the input is stable; it may simply mean the test did not trigger the relevant failure.

If the source is a live camera or incoming feed, do not use -stream_loop as a substitute for diagnosing it. There is no completed file to repeat. Check capture permissions, device availability, source timestamps, transport errors, and the provider’s own session rules.

Check what reconnect does not restore

There are several failures that a source reconnect cannot repair.

It does not refresh a YouTube media URL or replace an expired signed HTTP address. It does not reconnect every input type. It does not automatically restore YouTube publishing or recreate the live event after the output has stopped. It does not fix an encoder crash, unsupported media, a damaged file, a wrong stream key, or an output format that YouTube cannot process.

It also does not make a live event’s settings change on their own. YouTube’s auto-start and auto-stop controls are separate from FFmpeg’s file-loop setting. YouTube’s help for stream settings should be checked for the current behaviour of the event you are using.

A useful diagnostic table is:

Symptom Likely area to inspect First action
FFmpeg exits when the file duration is reached Local input reached end-of-file Add -stream_loop -1 before that file’s -i, if repetition is intended
HTTP source read fails while FFmpeg continues handling the command Current HTTP input Check the source URL, protocol options, logs, and bounded retry policy
FFmpeg reports a write or publishing error Output connection or YouTube ingest Check network delivery, key, destination, and stream health
FFmpeg stays open but YouTube receives no valid media Output, encoding, or event state Inspect logs and Live Control Room rather than the process state alone
Camera or incoming feed stops producing data Live source or capture path Diagnose the device, transport, timestamps, and source provider
File repeats with a visible or audible break Media boundary and timestamps Test the transition and prepare the file or playlist for a cleaner join

This separation is particularly important for a 24/7 channel. A process that remains alive can create false confidence while the viewer sees a stopped, frozen, or invalid broadcast. For broader recovery planning, compare the ideas in how 24/7 live stream auto-restart should actually work, while keeping source recovery and output recovery as separate jobs.

Monitor the output separately

Once the input is configured, watch the YouTube side independently. Confirm that the preview receives both picture and sound, that the stream health indicators remain normal, and that the event is in the state you expect. FFmpeg’s lack of an exit message only tells you that the process has not ended; it does not prove that the platform is accepting the stream.

Keep the command’s logs available for diagnosis. Record whether the process exited, whether it reported a read or write error, and whether the failure happened at a file boundary or during an unrelated interruption. Avoid relying only on a desktop terminal that may close or become inaccessible overnight.

A local file can loop indefinitely while still showing a poor join, silent audio, an unsuitable aspect ratio, or timestamps that cause trouble. Check a complete transition before committing the channel to a long run. If you are comparing encoding choices for a long broadcast, use the practical bitrate comparison for long-run streams and then verify the current YouTube guidance rather than treating any older setting as permanent.

If your main requirement is that an uploaded file keep running while your own computer is switched off, StreamNeo removes the need to maintain this particular local FFmpeg process: upload the video, provide the YouTube stream key, and let the cloud broadcast handle the continuous run. You still need to check the content, YouTube event, and stream health, and you should not treat that as a promise that every unrelated publishing failure is repaired.

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

Should I use -stream_loop -1 or HTTP reconnect flags for a local MP4?

Use -stream_loop -1 when the local file should repeat. HTTP reconnect flags apply to an HTTP input and do not make a local file start again after end-of-file. Add -re before the file input when it is being paced as live output.

Will reconnect flags keep YouTube live after FFmpeg loses the output connection?

Not necessarily. The flags discussed here concern the current HTTP input, not automatic restoration of YouTube publishing or the live event. Check the FFmpeg output log, network connection, stream key, encoding settings, and YouTube Live Control Room separately.

Can I use -stream_loop -1 with a live camera?

No, not as a general recovery method. A camera is already a live input rather than a finite file, so repeating it is not the right diagnosis. Investigate the device, capture path, source timestamps, and transport instead.

Why is FFmpeg still running when YouTube has stopped receiving the stream?

The input and output are separate parts of the command. FFmpeg may still be reading or retrying an input while the publishing connection has failed, or it may be producing media that YouTube cannot accept. Use the logs and YouTube’s preview and stream health to determine which side has stopped working.

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