systemd can start an FFmpeg playlist stream when Ubuntu boots, restart the FFmpeg process according to a policy you choose, and give you a place to inspect its logs. It supervises a process; it does not guarantee a continuous viewer-facing broadcast or repair a bad playlist, invalid credentials, lost network access or a YouTube event that is not live.
The reliable sequence is to test the exact command in the foreground first, then run that known-working command as a system service. After enabling it, check both Ubuntu’s journal and YouTube Live Control Room: those show different parts of the stream’s health.
What systemd supervises—and what it does not
A system-level systemd service gives the operating system a named process to manage. You can ask systemd to start it at boot, define whether it should be restarted after an exit, set a delay before a restart attempt and request its current status. The journal can collect FFmpeg’s standard output and error so you have something to examine when the broadcast stops.
That scope matters. A process can remain alive while producing an output YouTube does not accept, or exit because an input has disappeared. A restart policy responds to a process exit; it is not a test of picture, sound, playlist progress or the live status viewers see. Nor does systemd update a stream key or make an event live in YouTube.
Think of this as one layer in a chain: local media and the FFmpeg command feed a process; the process sends a stream over a working network connection; YouTube receives it under the event and ingestion settings you selected. systemd can supervise the process layer. You still need to check the other layers independently.
If your immediate problem is that a remote shell closing kills the command, compare the distinction with keeping a stream running after an SSH disconnect. A managed service can outlive an interactive shell, but the service itself still needs a valid command and a reachable destination.
Prepare and test the playlist-backed command
Use a dedicated Linux account where practical, and put the playlist and media in a directory that account can read. Check directory permissions as well as file permissions: the service user must be able to traverse every parent directory on the path. A command that works as your administrator account may fail when systemd starts it under a less privileged account.
Confirm that FFmpeg is installed, then inspect the protocols compiled into that particular executable:
ffmpeg -protocols
FFmpeg’s protocol documentation describes sequence-reading protocols such as concat and concatf. Availability depends on the installed build, so do not assume an example using one protocol will work on every Ubuntu installation. If FFmpeg reports an unknown protocol, first check the actual command, executable and build rather than adding restart attempts.
A playlist can be an input to FFmpeg, but the exact syntax depends on how the files are arranged and which input method you choose. The sample below illustrates the shape of a command using a concat-format input; it is not a universal, tested recipe. Replace the placeholder paths, confirm the protocol is present, and use output settings appropriate to your files and YouTube’s current ingestion setup.
/usr/bin/ffmpeg -re -f concat -safe 0 \
-i /srv/live/playlist.txt \
-c:v libx264 -c:a aac \
-f flv 'rtmp://YOUR_CURRENT_YOUTUBE_INGEST_URL/YOUR_STREAM_KEY'
Do not paste a real stream key into a publicly readable unit file, a shared support request or a log. Treat it as a credential and restrict access according to your host’s permissions model. This placeholder also does not establish that RTMP is the right output for your event; select the protocol and current URL in Live Control Room and match FFmpeg’s output to it.
Run the complete command in a terminal as the account you plan to use for the service. Check that FFmpeg opens every file, advances through the playlist in the expected order and reports no input or encoding errors. Confirm receipt in Live Control Room before proceeding. If playback stops at the end instead of repeating, fix the playlist or loop behaviour first; this guide to an FFmpeg loop that ends instead of repeating addresses that separate input and command problem.
Compare input approaches before settling on one. A concat-style list gives you an explicit ordered file list that is easy to edit, but its syntax and handling of differing media streams need checking. Other sequence protocols may suit a different workflow, but require support in your installed FFmpeg build. No input method removes the need to test the actual files and order.
| Choice to check | What it changes | What to verify |
|---|---|---|
| Playlist input method | How FFmpeg reads successive local files | Protocol support in this build, file order, paths and permissions |
| Media in the list | What FFmpeg has to decode and encode | Compatible stream parameters, codecs and successful playback between items |
| YouTube output protocol | How encoded output is delivered | Current event settings, required format and FFmpeg output support |
YouTube’s HLS ingestion instructions are specifically for HLS, not for the RTMP-shaped example above. YouTube specifies HTTPS, TS segments, segment durations from one to four seconds and a rolling playlist with no more than five outstanding segments for that setup; it also describes HLS as higher-latency than continuous RTMP ingestion. If you choose HLS, follow the current HLS requirements and build a command for them rather than borrowing RTMP flags. These platform requirements describe configuration, not a guarantee of performance.
Create a system service unit
Once the command works by hand, create a system service file, for example /etc/systemd/system/ffmpeg-playlist.service. A system service is appropriate when the stream should start without a user logging in. The following is illustrative: verify directive behaviour against the systemd.service manual installed for your Ubuntu release, and adapt paths, account and output configuration before use.
[Unit]
Description=FFmpeg YouTube playlist stream
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=streamer
Group=streamer
WorkingDirectory=/srv/live
ExecStart=/usr/bin/ffmpeg -re -f concat -safe 0 -i /srv/live/playlist.txt -c:v libx264 -c:a aac -f flv rtmp://YOUR_CURRENT_INGEST_URL/YOUR_STREAM_KEY
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
The User and Group fields should name the account that can read the media and execute FFmpeg. WorkingDirectory makes relative paths less surprising, although absolute paths in the command and playlist are easier to reason about. ExecStart should contain the exact command you tested, adjusted for the unit’s account and environment. systemd does not interpret a shell command line in the same way as an interactive shell; avoid shell-only constructs such as pipes or variable expansion unless you deliberately invoke a shell and understand the implications.
Do not treat this illustrative line containing a placeholder key as a recommendation to store a real key there. Unit files may be readable more widely than intended, and command details can surface in diagnostic output. Use a permissions-controlled method appropriate to your host for providing secrets, and confirm what can be read by other users and what appears in logs. The research for this guide does not establish one universal secret-handling mechanism for all Ubuntu releases, so check the installed systemd documentation and your host’s access model.
The [Unit] section describes ordering and relationships; the [Service] section describes the process; [Install] provides the target used when enabling it at boot. network-online.target expresses an ordering intention, not proof that YouTube is reachable or DNS and credentials are correct. Network readiness varies by system configuration, and the service can still start into a later connection failure.
Choose restart behaviour and dependencies
Restart=on-failure expresses a common intention for a long-running encoder: retry after an abnormal exit, but do not automatically relaunch after a clean exit. That differs from a service configured to restart after every exit, including a command that finishes successfully. Select behaviour based on what a clean exit means in your workflow. If a completed playlist is meant to stop, restarting it may be wrong; if a successful exit is unexpected for a continuous stream, a different policy may be appropriate.
RestartSec sets a pause before a restart attempt. A delay gives the host a moment before trying again and can make repeated failures easier to diagnose. It does not correct the cause of failure. Check the installed systemd.service manual for the exact directives, supported values and any start-rate limiting behaviour on your Ubuntu release; the unit above is not a substitute for release-specific documentation.
Dependencies and ordering also need modest expectations. After=network-online.target orders this unit relative to a target, while Wants= requests that target. Neither directive validates a route to YouTube, waits for a particular remote endpoint in every setup nor confirms that the broadcast is accepted. A service that starts before a usable connection may still fail and be restarted, depending on the policy.
Plan for maintenance as well as crashes. Ubuntu’s documentation says that beginning with Ubuntu 24.04 LTS, needrestart automatically restarts affected services by default following unattended upgrades; administrators can change the behaviour or exclude a critical service. That is version-sensitive, so consult Ubuntu’s automatic updates documentation for your release and decide how upgrades should affect a live process. A restart during maintenance is a service event to plan and observe, not a promise of uninterrupted output.
Enable and start the service
After saving the unit, tell systemd to reload its unit definitions, then enable it for boot and start it now:
sudo systemctl daemon-reload
sudo systemctl enable --now ffmpeg-playlist.service
enable arranges for the service to be started through its configured install target on subsequent boots. --now also asks systemd to start it immediately. These actions do not certify that the command is valid: a service may enter a failed state as soon as FFmpeg exits, or stay active while YouTube is not receiving the expected programme.
Check the first start before relying on boot behaviour. Use the status and logs below, and verify the incoming stream and event state in Live Control Room. If you change the unit later, reload systemd again; then restart the service to apply the new command or settings. Keep a note of what you changed so an unexpected exit can be tied to a configuration change rather than guessed at.
For a cautious recovery test, first choose a time when a brief interruption is acceptable. Stop or deliberately terminate the FFmpeg process in a controlled way, observe whether the configured policy acts as intended, and check that the new process actually reconnects and that YouTube receives it. A process coming back is only evidence of process recovery. It is not evidence that the event remained live or that viewers saw no interruption.
Inspect service status and journal logs
Use systemctl status for a concise view of whether systemd considers the unit active, its recent result and a few recent log lines:
sudo systemctl status ffmpeg-playlist.service
For more of the service’s journal output, query the unit directly:
sudo journalctl -u ffmpeg-playlist.service
To follow new entries while the service runs, add -f. To narrow the view to recent entries, use the journal’s time filters supported on your system. Read the first meaningful FFmpeg error as well as the final systemd result: repeated retries can make the most recent line less informative than the original failure.
A service reported as active (running) means systemd sees a running process. It does not mean the playlist is advancing, that the audio and video are suitable, or that the intended YouTube event is accepting the feed. Look for FFmpeg input and output messages, then verify the preview, stream health and live status in YouTube’s own control room. This cross-check is essential because local supervision and platform reception are separate observations.
When investigating a failure, note the time, the unit state and the relevant journal lines before changing several things at once. Check for permission errors, missing files, unsupported protocols, decoder or encoder errors, and connection failures. If a restart policy is active, distinguish the initial error from later retries. A fast sequence of exits often points to a cause that restarting alone cannot remove.
Diagnose failures systemd cannot fix
If FFmpeg exits immediately, first run the same command in the foreground as the service account. Compare its executable path, working directory, file access and environment with the unit. A typo, unreadable playlist or unsupported protocol is easier to identify from the direct error than from a succession of automatic restarts.
If the playlist opens but the programme stops between files, inspect the list syntax, paths, permissions and the media streams themselves. Files that differ in codec, resolution, frame rate or audio layout may need preparation or an encoding approach that handles those differences. A service manager cannot make incompatible media compatible. For streams built from long archives, avoiding the same video repeating in a sermon stream is also a playlist-design question, not a restart setting.
If FFmpeg reports a connection or authentication issue, verify that the host can reach the selected YouTube ingest address, that the event is configured for the protocol used by the command, and that the current stream key is the one associated with that event. Protect the key while checking it; do not copy it into public logs or publish it in a forum. Restarting with unchanged credentials or blocked network access simply repeats the same failure.
If FFmpeg remains active but YouTube does not show the expected incoming stream, check output protocol and encoder settings against the event configuration, then inspect Live Control Room. YouTube event scheduling, stream status and ingestion are outside systemd’s view. Use YouTube’s current live streaming setup guidance and the relevant protocol-specific instructions rather than inferring platform state from systemctl alone.
Keep a restart policy proportional to the problem. It can help when a process occasionally exits for a transient reason, but repeated failures may create a loop of identical attempts and obscure the useful first error. Once you identify a recurring failure, pause or adjust the service as appropriate, correct the input, credentials, network or event settings, and then test again in the foreground before restoring automatic start.
If you would rather avoid maintaining a host and system service for a file-based channel, StreamNeo removes the need to keep your own computer running by taking an uploaded video and stream key and carrying the broadcast as a 24/7 YouTube stream; it does not replace checking your YouTube event and content settings.
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 keep the YouTube stream live if FFmpeg crashes?
It can restart the FFmpeg process according to the policy in the unit, but that is not the same as restoring every part of the broadcast. Check the cause of the exit, confirm FFmpeg reconnects and verify the event in Live Control Room. A restart cannot repair an invalid playlist, credentials or network access.
Should I use Restart=always or Restart=on-failure?
Choose based on what a clean FFmpeg exit means for your setup. on-failure expresses that a normal exit should remain stopped, while a policy covering all exits expresses a different intent. Check the installed systemd manual for directive semantics and consider what happens if the command exits immediately each time.
Does network-online.target guarantee access to YouTube?
No. It provides an ordering relationship in the service configuration, not a check that a remote address, DNS resolution, firewall rule or stream credential is usable. Confirm the host’s connection and inspect FFmpeg’s output, then verify reception in YouTube Live Control Room.
Can I use the RTMP command example for YouTube HLS?
No. The example illustrates an RTMP-shaped output and does not implement YouTube’s HLS requirements. HLS uses its own URL, key and segment configuration; follow YouTube’s current HLS documentation and verify that your FFmpeg build can produce the required output.