Skip to content
streamneo.
Setup Guides12 min read

How to Set Up FFmpeg on Ubuntu Hetzner Cloud for a Nonstop YouTube Stream in India

Set up a file-based YouTube Live stream with FFmpeg on Ubuntu, then check RTMPS, bitrate, supervision and recovery before leaving it unattended.

sn.
StreamNeoPublished 5 October 2026
Worth sharing?

To send a video file from an Ubuntu instance on Hetzner Cloud to YouTube Live, create an encoder stream, copy its RTMPS address and key, then run FFmpeg with an appropriate input and output. To leave it running unattended, supervise the process and test the stream, restart behaviour and server reboot before relying on it.

This guide is for creators serving viewers in India, but that audience does not establish which Hetzner location or network route is best. The ingest connection from your instance to YouTube and the playback connection from YouTube to viewers are separate paths; measure and observe both rather than choosing a region by assumption.

Create an encoder stream in YouTube Live

Open YouTube Studio and choose Create > Go Live. Create or schedule a stream that uses streaming software, then open its stream settings. YouTube’s encoder setup guidance describes the process and the settings available in Live Control Room. The labels can change, so follow the current interface rather than a screenshot from an older guide.

Set the stream’s title, visibility and other details in the control room. Decide whether you are preparing a scheduled event or a stream that can be started when the encoder connects. For a continuous channel, plan the presentation and how viewers will encounter it, but do not treat the FFmpeg process itself as a substitute for checking the stream in YouTube’s interface.

The Ubuntu file-source path below assumes the media is already available on the instance, for example at /srv/stream/source.mp4. A cloud instance does not have an attached camera just because FFmpeg is installed. If your source is a live camera, a playlist that changes over time, or several items requiring transitions, the input and playout design are different. A useful contrast is this Kannada podcast archive workflow from a laptop, which has a different source and operating arrangement.

Copy the RTMPS URL and protect the key

In the stream settings, reveal and copy the server URL and stream key. Prefer the encrypted RTMPS option supplied by Live Control Room; do not construct an address from memory or substitute a plain RTMP URL simply because an example on the web uses one. YouTube describes RTMPS as encrypted RTMP and recommends it in its encoder settings documentation. Check that the copied address begins with rtmps.

Treat the stream key like a password. Do not paste it into a public issue, screenshot, source repository, shared terminal transcript or command that will be kept in shell history. If another person can read your service configuration or logs, assume they may be able to obtain any key stored there. Use a protected configuration file or the service’s credential mechanism, restrict access to it, and avoid logging the full output URL.

For example, a shell session might load two protected values into environment variables named YOUTUBE_RTMPS_URL and YOUTUBE_STREAM_KEY, but the exact method depends on how you administer the instance. Avoid typing the actual key as part of the FFmpeg command. If you believe the key has been exposed, use YouTube’s current reset flow; its stream key instructions explain where channel owners and managers can manage keys. After a reset, update the protected configuration before restarting the encoder.

Keep the URL shape supplied by the control room in mind when assembling the output destination. The common workflow appends the key to the server URL, but validate the exact copied URL and FFmpeg protocol syntax on the installed build before launching a long-running process. Never publish a real key in an article, shell example or support request.

Check Ubuntu and FFmpeg protocol support

First identify the actual release and the installed binary. For example, lsb_release -a or cat /etc/os-release reports the operating system release, while ffmpeg -version identifies the build and configuration. Package availability and build options can differ across Ubuntu releases, repositories and installation methods, so do not treat a command copied from another release as proof that your instance has the same capabilities.

Check whether FFmpeg recognises the RTMPS protocol and the H.264 encoder you intend to use. ffmpeg -protocols lists protocols compiled into that binary; look for rtmps in the output. ffmpeg -encoders lists available encoders; look for libx264 if your planned command uses it. You can also ask FFmpeg to show details for an encoder with ffmpeg -h encoder=libx264. These checks confirm what the local binary advertises, not that a complete connection to YouTube will succeed.

Install FFmpeg through a package source appropriate to the chosen Ubuntu release, then repeat these checks against the binary that will actually run under the service. If RTMPS or libx264 is absent, choose a build that provides the required support or adjust the encoding plan. A command that falls back to a different encoder can change CPU load and output behaviour; do not assume the fallback is equivalent.

The media path and network path also need separate consideration. A public YouTube push normally needs outbound access to the ingest endpoint; a private cloud network is not automatically necessary. Hetzner documents native cloud-init auto-configuration for Cloud Networks on Ubuntu 22.04 or later in its Cloud Networks documentation. That describes network configuration, not streaming performance, a suitable server size or a good route to YouTube for viewers in India.

Build a command for the actual media source

For a file, FFmpeg’s real-time input pacing option -re is a useful starting point so the file is read at its intended rate rather than as fast as the storage can supply it. FFmpeg’s protocol documentation shows a real-time file-to-RTMP pattern. The YouTube destination in your case must use the RTMPS URL and key obtained from Live Control Room, and the installed build must support that protocol.

The following is an example shape for a file intended to loop, not a verified universal command. It assumes 30 frames per second and an H.264 encoder; confirm the source, encoder availability, output size, keyframe interval and URL format before using it:

ffmpeg -re -stream_loop -1 -i /srv/stream/source.mp4 \\
  -c:v libx264 -preset veryfast -b:v 4500k -maxrate 4500k -bufsize 9000k \\
  -g 60 -keyint_min 60 -sc_threshold 0 -pix_fmt yuv420p \\
  -c:a aac -b:a 128k -ar 44100 \\
  -f flv "$YOUTUBE_RTMPS_URL/$YOUTUBE_STREAM_KEY"

The values above are illustrative rather than a claim about the best settings for your source, server or route. In this example, a GOP length of 60 frames corresponds to two seconds only if the output is actually 30 fps. If the source or output frame rate differs, recalculate the interval and confirm it in the actual output. The loop option repeats a file, but it cannot remove an edit point: if the last frame and audio do not connect naturally to the beginning, viewers can see or hear a break.

YouTube lists H.264, H.265/HEVC and AV1 as ingest codecs, but H.264 with libx264 is a straightforward CPU-encoding default when that encoder exists in your build. YouTube recommends constant bitrate and a two-second keyframe interval, with a maximum interval of four seconds. Its current encoder guidance lists recommended H.264 rates of 10 Mbps for 1080p30 and 6 Mbps for 720p30. Those are recommendations, not a promise that your instance or route will sustain them. Check YouTube’s current video format and bitrate table before choosing a target.

The example’s 4,500 kbps video rate is not presented as a YouTube recommendation. It is an illustration of a lower target that may be appropriate only after checking resolution, source frame rate, audio needs, instance CPU and measured upload stability. If your machine cannot encode reliably at the chosen resolution, or the outbound path cannot sustain the total stream with headroom, reduce the output target and test again. Do not assume a larger server resolves a poor network route, or that a good route resolves an encoder bottleneck.

For a continuously changing playlist, rotation, overlays or transitions, a single -stream_loop -1 input is not a complete playout system. Plan how an item ends, what happens if a file is missing and how the next item starts. This FFmpeg concat guide for local media is relevant if your channel needs a sequence rather than one looping file; inspect its assumptions before adapting any command to a different host or current FFmpeg build.

Run and supervise the encoder process

An SSH terminal is useful for a first foreground test, but closing the session can terminate a process tied to that terminal. A system service manager such as systemd can start FFmpeg at boot, keep its process state visible and attempt to restart it after an exit. This is an operational pattern, not a guarantee that the stream itself remains healthy. Service configuration varies with the chosen Ubuntu release, permissions and credential storage; check those details locally before enabling a unit.

A service should run as a restricted account with access only to the media and configuration it needs. Avoid placing the key directly in a unit file that is readable to other users. Configure the service to read protected credentials, set the working directory explicitly, and make logs available without printing secrets. The exact directives and credential approach should be reviewed against the systemd version and local security requirements on your instance.

Set a restart policy deliberately. Restarting after a process failure can recover from a transient exit, but it can also create a repeated failure loop if the input path is wrong, the URL is malformed, an encoder is missing or YouTube rejects the connection. A restart delay and log review help you distinguish recovery from repeated unsuccessful starts. Do not treat a “running” service state as proof that viewers are receiving a valid picture and sound.

Once you have created and enabled the service, use systemctl status your-stream.service to inspect state and journalctl -u your-stream.service to review its logs. Substitute the actual unit name. Use systemctl stop your-stream.service for a deliberate stop, and document the commands for whoever is expected to manage the channel. Avoid dumping environment variables or command lines if they contain the stream key.

If you prefer to understand service supervision separately, the systemd restart guide for a church FFmpeg stream covers the same operational concern in a different setting. Adapt rather than copy: the media path, user permissions, key handling, FFmpeg build and restart behaviour still need to match your instance.

Test bitrate, preview and health

A download speed test does not establish that a server can sustain an outbound live stream. Measure the outbound direction from the instance and observe whether it remains stable while FFmpeg is encoding and transmitting. Account for audio, protocol overhead and variation rather than setting the stream to consume every bit of available capacity. YouTube’s streaming tips recommend leaving 20% upload headroom and testing the stream before relying on it.

In Live Control Room, wait for the encoder preview and check the stream-health indicators. Confirm that picture and sound are present, the intended resolution and frame rate are reported, and there are no repeated warnings about bitrate or connection quality. If the preview is not correct, use the health feedback and FFmpeg logs to isolate whether the issue is source media, encoding load, credentials, protocol support or the network path.

YouTube’s recommended H.264 bitrate at 1080p30 is 10 Mbps, and at 720p30 it is 6 Mbps. The corresponding listed minimums are 5 Mbps and 3 Mbps. These figures are tied to YouTube’s guidance, not measurements of your Hetzner instance. Choose a target only after checking what your encoder can produce and what the outbound path sustains; a stable lower resolution is more useful than a nominally higher setting that continually drops or overloads the path.

Test while the instance is doing the real work: reading the intended media, encoding at the selected settings and sending to YouTube. Watch CPU use and logs as well as the control-room preview. If CPU saturation causes irregular encoding, reducing output complexity or choosing a codec the machine can encode efficiently may be necessary. If the preview reports connection trouble while CPU is comfortable, investigate outbound stability and the ingest connection instead.

A stream can reach YouTube successfully while viewers in India still experience a different playback path from the one you tested. Observe playback from the intended audience locations where practical, including the sound and continuity over time. Do not infer that a particular Hetzner region is best merely because the instance can connect to YouTube. For businesses or local news, a regional archive scheduling workflow may also help clarify what is being broadcast and when, but it does not measure route quality.

Verify recovery before unattended use

Before leaving the stream alone overnight, test how it behaves when FFmpeg exits. Stop the service cleanly, confirm that YouTube’s preview reflects the interruption as expected, then start it again and verify that the encoder reconnects and sends a valid stream. Review logs for repeated failure messages rather than relying only on a service showing as active.

Also test a server reboot during a planned maintenance window. Confirm that the service starts after boot, can read its source and protected credentials, and appears in Live Control Room with valid picture and sound. A process restart and a server reboot test different things: boot ordering, mount availability and credentials can fail even when a manual process launch works.

A restart policy only responds to the failure modes it can see. It will not fix a corrupt or exhausted source file, repair a bad key, ensure YouTube ingest is accepting the connection, or know that the picture has become stuck while FFmpeg remains alive. Make a simple check routine for service state, recent logs, preview and stream health, and decide who will act on an alert. For a 24/7 channel, the operating plan matters as much as the command.

Repeat the test after changing the Ubuntu release, FFmpeg build, source, output resolution, frame rate, encoder, server type or route. Keep a record of the working configuration without recording the secret key. The result is a reproducible setup for your circumstances, not evidence that the same values suit every instance or every Indian audience.

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 run FFmpeg 24/7 on Ubuntu?

Run FFmpeg under a service manager such as systemd rather than depending on an open SSH session. Configure protected access to the media and stream credentials, then test service start, restart, logs and reboot behaviour before unattended use. A service can restart a process, but it cannot prove that the YouTube stream is healthy.

How do I stream a video file to YouTube Live with FFmpeg?

Use -re to pace a file in real time, choose encoding settings that match the source and your available CPU, and send the output to the RTMPS address and key shown in Live Control Room. Verify that the installed FFmpeg build supports RTMPS and the selected encoder. Preview and health checks in YouTube are still necessary after FFmpeg starts.

How do I keep a YouTube live stream running after SSH disconnects?

An FFmpeg process attached to an interactive SSH session may stop when that session ends. A supervised service can run independently of the session and restart after some process exits, provided the service is configured correctly. Test it by disconnecting from SSH, then inspect the service and Live Control Room rather than assuming the broadcast continued.

Which Hetzner location is best for viewers in India?

The available sources do not establish a best location or prove a route from any location to YouTube ingest or Indian viewers. The server-to-YouTube ingest path and YouTube-to-viewer playback path are different. Compare candidate locations using your own outbound stream test and playback observations from the audience locations that matter.

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 ↗