Run FFmpeg in the foreground as a systemd service, then configure systemd to restart it after a failure. This keeps the encoder process supervised on a Hetzner Linux server, but it does not prove YouTube is receiving a healthy stream: confirm reception in YouTube Live Control Room as well.
What systemd can—and cannot—keep running
systemd can supervise FFmpeg as the service’s main process and restart it when that process exits unsuccessfully. Its documentation recommends Restart=on-failure for long-running services, with a considered delay between attempts; automatic restarts are still subject to start-rate limits. systemd service documentation
A running process is not the same as a healthy YouTube broadcast. FFmpeg may remain active while its input, encoding, or connection is stalled or invalid. Check service status and logs locally, then check YouTube’s stream health separately.
Prepare the server and YouTube ingest details
Use a dedicated service account
- Create a dedicated, unprivileged Linux account for the stream rather than running FFmpeg as root.
- Prepare an input and configuration location that account can read. Note the absolute path to the FFmpeg executable and the intended working directory; the unit file below uses example paths that must be replaced with paths on your server.
Get the correct YouTube destination
Use the ingestion address and stream name/key supplied for your YouTube Live stream. YouTube’s LiveStreams resource distinguishes primary and backup ingestion addresses and includes RTMP and RTMPS ingest types. A single-output FFmpeg service should use one destination; the existence of a backup address does not mean the service sends to both. YouTube LiveStreams API
#1 Best Overall
- Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (8GB RAM)
- Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
- CanaKit Turbine Black Case for the Raspberry Pi 5
- CanaKit Low Noise Bearing System Fan
- Mega Heat Sink - Black Anodized
Prefer RTMPS when your encoder and ingest endpoint support it. YouTube documents RTMPS as RTMP over TLS: connect to the ingestion server on port 443 and ensure TLS SNI uses the ingestion server hostname. YouTube RTMPS guide
| Choice | What it means | What to verify |
|---|---|---|
| RTMP | YouTube provides RTMP ingest addresses. | Use the exact address and stream name/key shown for your stream, and confirm your encoder supports the selected endpoint. |
| RTMPS | RTMP carried over TLS. | Use the RTMPS endpoint on port 443 and preserve the ingestion hostname for TLS SNI; verify your FFmpeg build and endpoint support it. |
Protect the stream key
Treat the stream key as a credential: do not put a real key in a public unit file, screenshot, or shell history. systemd warns that environment variables are not suitable for secrets because they may be exposed through D-Bus and passed to child processes. Consider a credential mechanism supported by the systemd version installed on your server, and restrict access to any file used to deliver the key. systemd execution documentation
Rank #2
- Includes Raspberry Pi 4 4GB Model B with 1.5GHz 64-bit quad-core CPU (4GB RAM)
- Includes Pre-Loaded 32GB EVO+ Micro SD Card (Class 10), USB MicroSD Card Reader
- CanaKit Premium High-Gloss Raspberry Pi 4 Case with Integrated Fan Mount, CanaKit Low Noise Bearing System Fan
- CanaKit 3.5A USB-C Raspberry Pi 4 Power Supply (US Plug) with Noise Filter, Set of Heat Sinks, Display Cable - 6 foot (Supports up to 4K60p)
- CanaKit USB-C PiSwitch (On/Off Power Switch for Raspberry Pi 4)
Create a foreground FFmpeg service
Keep FFmpeg in the foreground so systemd can track its process as the service’s main process. Do not daemonize FFmpeg behind systemd. This illustrative unit shows the structure only; the angle-bracket text is explanatory, not valid FFmpeg syntax. Replace it with your actual input and encoding options and YouTube ingest destination, and use a secure method to provide the stream key.
[Unit]
Description=FFmpeg YouTube live stream
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=stream
WorkingDirectory=/srv/stream
ExecStart=/usr/bin/ffmpeg <input-and-encoding-options> <youtube-ingest-url>
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
User=streamshould name the dedicated account you created.WorkingDirectory=/srv/streamand/usr/bin/ffmpegare examples; confirm the actual directory and binary path on your host.ExecStartmust be a foreground FFmpeg invocation with your actual input and output settings. This guide does not supply a tested FFmpeg command or validate particular encoding or reconnection flags.Restart=on-failureasks systemd to restart after a failure.RestartSec=5is an illustrative delay, not a universal recommendation; choose a delay appropriate to your service and account for systemd start-rate limits.
Do not assume a restart policy can repair an application-level stall where FFmpeg never exits. Nor does this unit establish Hetzner-specific firewall rules or server sizing; those depend on your deployment and should be checked against current provider documentation.
Free tools Windows power users keep installed
One-click scans. No signup required.
Load, enable, start, and inspect the service
- Save the unit as
/etc/systemd/system/ffmpeg-youtube.service, adjusting ownership and permissions so the service account can read its input and configuration without exposing the stream key. - Reload unit definitions:
sudo systemctl daemon-reload. - Enable startup at boot and start the service:
sudo systemctl enable --now ffmpeg-youtube.service. - Check its state:
sudo systemctl status ffmpeg-youtube.service. - Read recent service logs, including FFmpeg stderr when it is captured by the service:
sudo journalctl -u ffmpeg-youtube.service -n 100 --no-pager. To follow new entries, usesudo journalctl -u ffmpeg-youtube.service -f. - Open YouTube Live Control Room and confirm that YouTube is receiving the intended video and audio and reports a healthy stream. Do not treat an “active” systemd state as confirmation of successful ingest.
Troubleshoot process failures and unhealthy ingest
| Symptom | Likely area to check | Next action |
|---|---|---|
| The service exits or repeatedly restarts. | FFmpeg stderr in the journal; executable or input paths; permissions; whether the service account can read the input. | Correct the underlying error, then restart the unit. Restart=on-failure handles process failures and certain timeouts, not every application-level stall. |
| systemd says active, but YouTube shows no video or an unhealthy stream. | Input, encoding, or ingest; YouTube’s own status and health information. | Check YouTube Live Control Room and the LiveStreams resource’s active, inactive, error, or ready state and health data. An active local process alone does not establish that valid video reaches YouTube. YouTube LiveStreams API |
| RTMPS reports TLS or connection timeouts. | Scheme, endpoint, port, or TLS SNI hostname. | Confirm the supplied URL is RTMPS, the endpoint is valid, the connection uses port 443, and TLS SNI identifies the ingestion hostname. YouTube RTMPS guide |
| Restarts stop after repeated failures. | systemd start-rate limits and manager or unit logs. | Inspect the logs, fix the failure causing the restart cycle, then reset the failed state and start the service if needed. Avoid an unlimited tight restart loop. systemd service documentation |
| YouTube reports a stream health warning. | Incoming audio/video configuration or insufficient data. | Read the issue category: YouTube health messages can identify bitrate, codec, frame rate, GOP length, or insufficient video. Correct the applicable input or encoding problem and check health again. YouTube health status reference |
Or let it run in the cloud
If you want a YouTube channel to loop uploaded recordings without maintaining an FFmpeg process on a Hetzner server, StreamNeo is a separate cloud option: upload a video or build a playlist, add your YouTube stream key, and go live. Nothing has to stay on at home; each slot streams uploads as made, up to 4K 60fps, at one flat price per slot. StreamNeo automatically recovers if YouTube drops the stream. The first day is free with no card, one free day per account. Monthly pricing is $9.99 per month. StreamNeo is for YouTube and uploaded videos, not camera-based broadcasting. See StreamNeo, or start your free day.
Quick Recap
Best Value
- Includes Raspberry Pi 5 16GB with 2.4Ghz 64-bit quad-core CPU (16GB RAM)
- Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
- CanaKit Turbine Black Case for the Raspberry Pi 5
- CanaKit Low Noise Bearing System Fan
- Mega Heat Sink - Black Anodized
Rank #4
- Broadcom BCM2711, quad-core Cortex-A72 (ARM v8) 64-bit SoC @ 1. 5GHz
- 2. 4 GHz and 5. 0 GHz IEEE 802. 11b/g/n/ac wireless LAN, Bluetooth 5. 0, BLE
- 2 × USB 3. 0 ports, 2 x USB 2. 0 Ports
- 2 × micro HDMI ports supproting up to 4Kp60 video resolution
- Micro SD card slot for loading operating system and data storage
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

