Skip to content
streamneo.
Troubleshooting13 min read

How to Set Up systemd to Restart a Church FFmpeg YouTube Stream

Configure systemd to launch FFmpeg at boot, restart failed processes and check logs, while verifying YouTube stream health separately.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

systemd can start an FFmpeg stream when your Linux host boots and relaunch the process after certain failures. It cannot tell you, by itself, that YouTube has accepted the feed or that viewers can see and hear it.

The setup below is a template for a church stream that runs FFmpeg in the foreground. Adapt the account, paths, input, output and encoding settings to your host, then test both the process recovery and the broadcast before relying on it during a service.

What systemd can and cannot recover

systemd supervises a process. With a suitable restart policy, it can start FFmpeg at boot and launch it again when FFmpeg exits in a way that qualifies for a restart. That is useful if the encoder crashes or exits with an error while the host and its operating system remain available.

A process coming back is not the same as a broadcast coming back. FFmpeg might restart but fail to read the camera or media file, be unable to reach the ingest endpoint, use a rejected stream key, or send a feed with a problem that Live Control Room reports. The unit can show as active even when the content is wrong or the picture is not reaching YouTube.

There are several layers to consider. A camera or network interruption may be handled by FFmpeg without its process exiting, depending on the input, output, protocol and FFmpeg build. If FFmpeg does exit, systemd may start another process. If the replacement process starts but cannot make a valid connection, systemd has no inherent way to judge the health of the YouTube broadcast.

This distinction is especially important for a church service. A restart loop will not correct a persistent input failure or a bad key; it may simply repeat the same failure. Keep the recovery claim narrow: systemd supervises the process according to its configured rules. You still need to inspect FFmpeg’s output and YouTube’s stream health.

If your stream stops repeatedly, first identify whether the cause is the source, encoder, output connection or YouTube’s response. The diagnostic questions in why a YouTube radio livestream keeps stopping may help you organise that investigation, though your FFmpeg logs and Live Control Room remain the evidence for this particular setup.

Prepare FFmpeg and its service account

Before writing a unit file, run the exact FFmpeg command successfully from a terminal under the account that will own the service. Keep FFmpeg in the foreground rather than launching it in the background: systemd needs to supervise the process it starts. Check that the account can read the video or camera input, access any required audio devices, and write any local logs or temporary files the command needs.

The following command is deliberately illustrative, not a tested, ready-to-run church configuration:

/usr/bin/ffmpeg -i INPUT -c:v libx264 -c:a aac -f flv 'OUTPUT_WITH_STREAM_KEY'

Replace /usr/bin/ffmpeg with the executable path on your machine. Replace INPUT with the actual media or capture input and the output placeholder with the RTMP or RTMPS destination and stream key from YouTube Live Control Room. Confirm that the codecs, pixel format, frame rate and other options match the source and your intended broadcast; this short example is not a complete encoder tuning guide.

Treat the stream key as a credential. Avoid posting it in examples, screenshots, public support threads or a broadly accessible script. Limit access to the unit and any file holding the key to the people and processes that need it. YouTube explains that the key identifies where the encoder sends its feed; if you think it has been exposed, consult YouTube’s guidance on stream keys and use Live Control Room to manage the key.

An example account name in a unit is not a special system account created by systemd. You or your administrator must create and configure the account, then grant it only the necessary access to the stream source and other files. If you use a camera device, verify permissions while logged in as that account; a command that works only as root may fail when systemd starts it as a less-privileged user.

Write down the exact command that worked, including required options, but store credentials carefully. Avoid putting the key in a shell command that you plan to paste into a public issue or save in a world-readable file. A unit file is generally readable by administrators, but the permissions and access to credential-bearing configuration still matter. Check the installed systemd documentation for the behaviour of directives on your distribution.

Create the systemd unit

Create a service file at /etc/systemd/system/church-stream.service. Use an editor with administrative privileges, for example sudo nano /etc/systemd/system/church-stream.service. A starting template is:

[Unit]
Description=Church FFmpeg YouTube stream
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=stream
ExecStart=/usr/bin/ffmpeg -i INPUT -c:v libx264 -c:a aac -f flv 'OUTPUT_WITH_STREAM_KEY'
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

The stream user, command path, input and output are placeholders. Change them to the account and working command you prepared. If the full command requires shell features such as pipes, do not assume systemd will interpret the ExecStart line as an interactive shell would. Prefer a direct executable and arguments; for complex setups, use a carefully permissioned wrapper script and test it under the service account.

Type=simple tells systemd to treat the process launched by ExecStart as the service process. This is why FFmpeg should not daemonise or fork away from the supervisor. Wants= and After= express a relationship with the network-online target, but they do not prove that the internet route, DNS, ingest connection or camera is usable. Host network managers also differ in what “online” means. A delayed first attempt or an FFmpeg-level failure can still occur.

The service name is the filename without the .service suffix, so later commands refer to church-stream.service. Keep one clear unit for the stream rather than starting a second copy by hand while the managed process is running. Two encoders sending to the same channel can create confusing results and may conflict over the same source or destination.

For broader context on a hosted approach that does not depend on a church computer remaining on, see how to run a 24/7 YouTube stream with a prebuilt cloud streaming service. The trade-off is operational: a local systemd service depends on your Linux host, power, network and source; a managed service changes which parts you operate yourself. Neither choice removes the need to verify the live feed.

Choose restart and boot behaviour

Restart=on-failure is a reasonable starting policy for an encoder that should be retried after an unsuccessful exit. The systemd service manual describes it as covering non-zero exits and specified failure conditions such as qualifying signals, timeouts and watchdog failures. It is different from Restart=always, which also covers successful exits, and from the default Restart=no, which does not automatically restart the process.

The distinction matters if your FFmpeg command ends normally. With on-failure, a clean exit is not treated like a crash. That is often preferable to restarting a process that was deliberately made to finish, but a continuous channel may need investigation if FFmpeg exits successfully when you expected it to run indefinitely. Do not change to always without considering what a clean exit means in your setup.

RestartSec=5 in the example spaces attempts with a delay. It is a starting value, not a universal fix or a guarantee of recovery. systemd also applies start-rate limits to repeated attempts. If the input or key remains invalid, automatic retries can stop after repeated failures; inspect the unit’s rate-limit messages and the installed manual rather than trying to suppress every limit blindly.

An explicit systemctl stop church-stream.service is an intentional stop, and systemd does not use the restart policy to undo it. That lets an operator stop the stream for maintenance. Conversely, enabling the unit at boot and restarting it after an error are separate behaviours: Restart= concerns service exits, while the [Install] section and enable command arrange for startup through the selected boot target.

FFmpeg can also have protocol-level reconnect options, but they are not generic switches for every connection. The FFmpeg protocol documentation describes reconnect controls in the context of particular protocols and directions. Check that documentation against your installed FFmpeg version and the failing side of the connection before adding an option; HTTP input reconnect settings should not be presented as a general fix for RTMP or RTMPS output.

Recovery layer What triggers it What it can do What you still need to check
FFmpeg protocol handling A supported transport interruption, for the relevant protocol and direction Retry or reconnect without the FFmpeg process necessarily exiting Whether the input or output recovered and whether the feed is accepted
systemd service restart FFmpeg exits in a way allowed by Restart= Start a new FFmpeg process after the configured delay Whether the new process can read the source and send a healthy feed
Operator check A failed or uncertain broadcast, or a planned test Identify the fault and decide whether to correct, stop or retry Live Control Room status, picture, sound and the event’s actual source

Reload, enable and start the service

After saving the file, ask systemd to reload unit definitions. Then enable the unit for boot and start it now:

sudo systemctl daemon-reload
sudo systemctl enable --now church-stream.service

daemon-reload makes systemd read the unit file; it does not restart a process already running with the old definition. enable --now both arranges startup at the configured boot target and starts the service in the current session. If you later edit the unit, reload definitions again and deliberately restart the service to apply the changes:

sudo systemctl daemon-reload
sudo systemctl restart church-stream.service

Be careful when restarting during a live service: it terminates the current FFmpeg process before starting another, so there can be a break in the feed. Make changes and test them outside the service window where possible. If a start command reports an error, do not repeatedly retry without reading the message; correct the command, permissions or unit syntax first.

To stop the service intentionally, use sudo systemctl stop church-stream.service. If you do not want it launched on a future boot, disable it as well with sudo systemctl disable church-stream.service. The distinction is useful for maintenance: stopping affects the current run, while disabling changes the boot arrangement.

Inspect service status and logs

Start with:

systemctl status church-stream.service

The status output helps you see whether systemd considers the service active, when it was started, the main process identifier and recent journal lines. An active state only describes the service process from systemd’s perspective. It does not certify the ingest connection, the church programme’s picture or sound, or the viewer experience.

For the current service log, follow the journal while the stream starts:

journalctl -u church-stream.service -f

To review earlier entries, use journalctl -u church-stream.service and read the timestamps around a failure. Look for the first meaningful FFmpeg error, not just later retry messages. A missing input file, device permission denial, invalid option or failed connection points to a different remedy. If the unit repeatedly starts and exits, systemd’s own rate-limit messages may also explain why another attempt did not occur.

A practical troubleshooting sequence is to compare three things: the FFmpeg command as run by the service account, the unit’s status and journal, and Live Control Room’s view of the incoming feed. If the command works manually but not as a service, compare environment, permissions, working directory and device access. If FFmpeg stays up but YouTube does not show a healthy feed, investigate the output destination, key, protocol and network rather than assuming a restart policy is missing.

For a planned check, you can test the process policy outside the service window. Confirm the service starts, note its journal output, then stop it deliberately and observe that an explicit stop remains stopped. To check the failure path, arrange a controlled unsuccessful exit in a safe test setting, then inspect whether systemd makes another attempt. This verifies process supervision; it does not verify that YouTube receives the replacement feed.

Verify YouTube stream health separately

Open YouTube Live Control Room and check that the intended stream is receiving data and that its health indicators and messages are acceptable. Then check the actual programme: confirm the expected video is present, audio can be heard, and the feed remains stable through the part of the service that matters. If viewers can help with a private or unlisted rehearsal, have someone check playback from a separate connection rather than relying only on the encoder machine.

YouTube’s live encoder settings guidance lists protocol, codec, keyframe and bitrate recommendations. Use the current table row for your selected codec, resolution and frame rate rather than copying values from an unrelated setup. For example, the guidance accessed in 2026 lists H.264 720p at 30 fps with a 3 Mbps minimum and 8 Mbps recommended, and H.264 1080p at 30 fps with a 5 Mbps minimum and 14 Mbps recommended. These are YouTube’s published settings, not a promise that a particular church uplink can sustain them.

The same YouTube guidance recommends a two-second keyframe frequency and says it should not exceed four seconds. Its networking guidance recommends upload headroom; the research notes cite 20% headroom. Treat those as planning guidance, not a guarantee that your connection will avoid disruption. Measure the actual upload available during the hours you intend to stream, account for other devices using the connection, and choose settings that match the source and current YouTube recommendations.

A useful pre-service rehearsal includes the same camera or file source, audio path and encoder command you intend to use. YouTube’s guidance says, “Make sure to test before you start your live stream.” A test that only checks whether the FFmpeg process can launch misses source and ingest problems. After any controlled restart test, repeat the separate health check in Live Control Room; do not infer a restored broadcast from systemctl status alone.

If you decide the main risk is the local computer being left on, consider the operational alternatives as well as tuning the unit. A devotional channel that rotates a prepared set of videos has different source and maintenance needs from a live camera feed; planning a playlist for a 24/7 YouTube stream is relevant if that is your format. StreamNeo removes the specific burden of keeping this FFmpeg host running by turning an uploaded video into a YouTube live stream from the cloud, while you still need to prepare the file, provide the stream key and check YouTube’s broadcast health.

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

Will systemd reconnect my YouTube stream after FFmpeg crashes?

It can start a new FFmpeg process after an exit covered by the unit’s restart policy. That does not prove YouTube accepted the new connection or that viewers see a healthy picture and sound. Confirm the result in Live Control Room and inspect the journal.

Why is the service active when the stream is not visible?

Systemd reports on the process it supervises, not on the quality of the YouTube broadcast. FFmpeg may remain alive while the input is missing, the destination is wrong or the feed is not healthy. Compare FFmpeg’s logs with Live Control Room’s status.

Should I use Restart=always instead of on-failure?

Use a policy that matches what a normal FFmpeg exit means for your command. on-failure is a sensible starting point when only unsuccessful exits should trigger a retry; always also restarts after a successful exit. Check the systemd manual for your installed release and test the behaviour before relying on it.

Do FFmpeg reconnect flags replace systemd?

No. Protocol-level reconnect options may help with a documented transport interruption while FFmpeg remains running, whereas systemd responds to qualifying process exits. Their behaviour depends on the protocol, direction and installed FFmpeg build, so use the relevant documentation and verify the resulting YouTube feed.

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 ↗