To run FFmpeg in the background on Debian without it suspending while waiting for console input, add -nostdin. For a stream that should survive logout and be manageable after a reboot, run FFmpeg as a systemd service and use journalctl to inspect its output.
This guide shows the setup and the checks that matter. Debian releases can ship different FFmpeg builds and systemd versions, so treat the command as a template: verify your installed features and adapt the unit to the machine you are using. Keep the YouTube stream key private throughout.
Check your Debian release and FFmpeg build
Start by identifying the operating system and the FFmpeg executable available to the account that will run the service:
cat /etc/debian_version
ffmpeg -version
ffmpeg -buildconf
The version output identifies the installed release of FFmpeg; the build configuration gives clues about how it was compiled. Package versions and enabled encoders or protocols vary between Debian releases and between packaged and locally built binaries. Do not assume that a command copied from another Debian host will have the same codec support on yours.
If FFmpeg is not installed, use Debian's package tools or the installation method appropriate to your host, then repeat these checks. Before writing a service, confirm that the binary is in a stable location, commonly /usr/bin/ffmpeg, and that the eventual service account can execute it. Check a specific encoder or protocol with FFmpeg's help output, for example:
ffmpeg -encoders | grep -E 'libx264|aac'
ffmpeg -protocols | grep -i rtmps
These checks are clues, not a substitute for testing a complete command with your actual input. If libx264 is missing, the illustrative encoder choice below will fail; choose an encoder available in that build and suitable for your source. Similarly, confirm RTMPS support before attempting to publish. FFmpeg documents RTMPS as encrypted transport in its protocol documentation.
Also check the working directory and media path you intend to use. A service does not inherit the environment, current directory, mounted drives or shell variables from your interactive login. Use absolute paths and make sure the service account can read the input file. If the source is a MOV file or another format that is awkward to encode reliably, prepare and test it first; this guide to converting MOV files for a YouTube 24/7 stream covers that separate step.
Get the RTMPS URL and key from YouTube
In YouTube Live Control Room, open the scheduled or active live stream and find its encoder settings. Copy the server URL and stream key shown for that event. YouTube may initially show an ordinary RTMP URL; select or reveal the RTMPS option when available, and use the exact URL displayed for the stream. YouTube's encoder setup instructions describe where these values are provided.
The server URL and key are separate pieces of configuration even though FFmpeg commonly receives them together in its output URL. Do not put a real key in an article, public script, repository, screenshot, support request or shell history you share. Treat it like a password. A key embedded in a process argument may be visible to privileged local users or tools that inspect processes, so consider who has access to the Debian host and its logs.
A systemd unit file is usually readable by administrators and may be readable by other local users depending on its permissions. Restrict access to the unit and any file used to supply credentials. If a key is exposed, replace or rotate it in YouTube rather than assuming that hiding the text afterwards is sufficient. YouTube's live encoder troubleshooting guidance is useful when a connection is rejected or the event does not receive video.
Prepare an FFmpeg command with -nostdin
A shell background operator (&) only asks the shell to run a process in the background. It does not stop FFmpeg from checking for terminal input, make it start after a reboot, or provide a convenient service log. FFmpeg's FAQ explains that -nostdin disables those input checks so it can run as a background task; it also documents redirecting standard input from /dev/null as an alternative. See the FFmpeg FAQ.
Here is a command shape to test and adapt, not a universal encoding recipe:
/usr/bin/ffmpeg -nostdin -re -i /srv/stream/input.mp4 \
-c:v libx264 -c:a aac \
-f flv 'rtmps://INGEST_HOST/APP/STREAM_KEY'
Replace the file path and output URL with the values for your setup. The host, application path and key are placeholders: never copy them as if they were a real destination, and never publish a real key. The -re option reads a file at its normal rate, which is often relevant when sending a prerecorded source; it is not a general instruction for every kind of input. Check how your specific input should be read.
The encoder settings above are illustrative. They only work if your FFmpeg build includes the named encoders and the input has suitable streams. Choose output resolution, frame rate and bitrate to match your source, connection and YouTube's current recommendations rather than copying a setting from a different video. Consult YouTube's current live encoder settings and test the resulting command before turning it into a long-running service.
If you are looping prerecorded material, looping is a separate decision. A repeated file may need careful handling of timestamps, audio and transitions; one loop option is not right for every input. The FFmpeg guide to looping prerecorded videos on YouTube Live can help you think through the media behaviour, although its platform-specific commands are for Windows rather than Debian. For a playlist rather than one file, use a tested playlist workflow such as the automatic FFmpeg video playlist guide.
Run the command interactively first, with the actual key entered carefully and without sharing the terminal output. Confirm that YouTube receives the picture and sound and that the chosen event is the intended one. Stop the test with Ctrl+C before installing it as a service. If FFmpeg reports an unknown encoder, missing protocol or unreadable input, resolve that at this stage rather than diagnosing several changes at once later.
Create a systemd service for the stream
A systemd unit gives the stream a name, a defined account and a lifecycle independent of your login session. It can also be configured to start after the machine boots. This is more manageable than leaving a shell or terminal multiplexer attached to the job, but it does not make a bad input or network connection reliable by itself.
For a simple first unit, create /etc/systemd/system/youtube-stream.service as an administrator. The following is a template; replace paths and placeholders, and do not save a real stream key in a file accessible to people who should not have it:
[Unit]
Description=YouTube live stream from FFmpeg
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=streamer
Group=streamer
WorkingDirectory=/srv/stream
ExecStart=/usr/bin/ffmpeg -nostdin -re -i /srv/stream/input.mp4 -c:v libx264 -c:a aac -f flv rtmps://INGEST_HOST/APP/STREAM_KEY
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
The account named streamer must exist, and it must be able to read the file and execute FFmpeg. If you prefer to run the service under a different restricted account, change User and Group to match. Avoid running a media process as root without a specific reason. WorkingDirectory is explicit so the unit does not depend on the directory from which you happened to start it.
Restart=on-failure asks systemd to attempt a restart when the process exits unsuccessfully. Choose a restart policy deliberately: it can help recover from a process failure, but it will not fix a wrong key, unsupported encoder, unavailable source file or persistent network problem. Repeated restarts can make an underlying fault less obvious, so inspect the journal after the first failure. RestartSec is an example delay, not a guarantee that YouTube will accept a reconnect or that a stream will resume cleanly.
The example places the key directly in ExecStart to show the command shape. That is convenient but carries a credential exposure trade-off: process arguments and unit files can be inspected by suitably privileged local users. Restrict unit access and the host account, and assess whether a credential file or another controlled method is more appropriate on your Debian and systemd versions. Do not assume a configuration mechanism is supported without checking the local systemd manual. Be mindful that troubleshooting output and copied service definitions can reveal secrets too.
Systemd directives and supported features can differ with the version installed on a Debian host. Read the local manual pages (man systemd.service, man systemd.exec) if you intend to add hardening, environment files or other directives. Keep the first unit minimal; add only settings you understand and have checked against that host's manuals.
Enable and start the service
After saving the unit, ask systemd to reload unit definitions, then start the named service:
sudo systemctl daemon-reload
sudo systemctl start youtube-stream.service
Starting and enabling are different actions. start runs the service now; it does not by itself arrange to start at boot. If you want the stream to be attempted after a reboot, enable it as well:
sudo systemctl enable youtube-stream.service
You can combine the actions with sudo systemctl enable --now youtube-stream.service. Do this only after checking the event, input and key, since the service will then try to publish when enabled. If the host reboots for maintenance, systemd will attempt to start the process once the machine reaches the relevant boot target and network ordering permits it. This is a startup arrangement, not a promise that the stream will be live continuously: connectivity, input availability, encoder behaviour and YouTube's event state still matter.
A long-running prerecorded stream also depends on the media design. A single file may end, and an input that cannot be reopened will not become continuous merely because the service is enabled. For channels built from repeated ambience or music, plan the media loop and check its audio transitions before enabling automatic startup. The practical decisions in a continuous ASMR keyboard stream setup offer a useful example of thinking about continuity as well as process management.
Check status and logs with journalctl
First check whether systemd considers the unit active and whether FFmpeg has exited:
sudo systemctl status youtube-stream.service
For the service's recent output, filter the journal by unit:
sudo journalctl -u youtube-stream.service
To watch new log entries as they arrive, use follow mode:
sudo journalctl -f -u youtube-stream.service
The systemd journalctl manual documents unit filtering and follow mode. Press Ctrl+C to stop following the log; that does not stop the service. If the service ran before and you want entries since the current boot, add -b to the journal command. On some hosts access to the full journal requires sudo or membership in a permitted group.
Read the first useful error, not just the final failed state. An unknown encoder points back to the installed build; a missing input points to the file path or permissions; a TLS or connection error calls for checking the exact RTMPS URL, network access and protocol support. If YouTube does not show incoming video, verify that the event is active, the key belongs to that event, the input contains video and audio as expected, and the encoder settings match current guidance. Do not paste a log containing the full output URL into a public issue if it includes the key.
A service can be active while the stream is not useful to viewers, so check YouTube Live Control Room as well as systemctl. Conversely, a transient connection message does not necessarily tell you whether FFmpeg recovered. The journal provides process evidence; the live control room tells you what YouTube is receiving. Keep these checks separate when diagnosing a night-time failure.
Restart or stop the service safely
When you change a unit file, reload systemd before restarting the service so it reads the new definition:
sudo systemctl daemon-reload
sudo systemctl restart youtube-stream.service
After a restart, check status and the newest journal output. Restarting interrupts the current FFmpeg process and starts it again; it is not the same as making an in-place change to the live encoder. If you only changed the media file, verify whether the process has already opened it and plan a controlled restart if necessary.
To stop the stream without disabling automatic startup:
sudo systemctl stop youtube-stream.service
To prevent it from being started automatically on a later boot, disable it separately:
sudo systemctl disable youtube-stream.service
Stopping is the immediate action; disabling changes the boot behaviour. If you have exposed the key, stop using it and rotate it through YouTube rather than relying solely on a service restart. If you need to replace a key in a unit file, edit the file privately, reload systemd and restart, then check that the new stream is reaching the intended event. Avoid sharing the old or new unit contents in a support request.
For a temporary shell test instead of a service, `ffmpeg -nostdin ...