A cron job can run a restart script for your YouTube FFmpeg stream at a chosen time, but it does not know which FFmpeg process you mean or whether YouTube is receiving a healthy broadcast. Use a script that identifies only your stream, records useful diagnostics without recording the stream key, and verify the result in YouTube Live Control Room.
This approach suits a stream where a planned interruption is acceptable and a restart at a fixed time is useful. If FFmpeg is already managing a temporary network-output interruption, or your goal is to recover only when something fails, a scheduled restart may be the wrong tool. The key distinction is whether you need time-based maintenance or process-level and output-level recovery.
What cron can and cannot recover
Cron runs a command according to a schedule. It does not supervise the identity or health of the process that command starts. A daily job can launch your restart script, but that script must separately determine which FFmpeg process belongs to this stream, stop it, and start it again. A broad command that kills every process called ffmpeg can interrupt unrelated work, including another channel or a recording.
A restart can help if the intended FFmpeg process has become stuck or you want to refresh it at a predictable time. It cannot guarantee that the next attempt will connect, repair a bad input file, correct an invalid stream key, improve a weak upload connection, or prevent every disconnect. YouTube might show the stream as offline or still processing while the encoder starts, and a process can be running without delivering usable video or audio.
There are different failure modes to consider. If FFmpeg is alive but its network output has been interrupted temporarily, FFmpeg's FIFO output options may provide recovery attempts; that is not the same as restarting the whole process on a timer. If the process has failed, a supervisor that checks process state may better match the need than a fixed-time cron job. If you only need to restart once during a quiet window, cron may be sufficient. For a discussion of whether a modest device is suitable for a continuous loop, see what a Raspberry Pi 3 B+ can handle for a 24/7 YouTube loop.
Before choosing, ask what happened during the last interruption, whether a brief scheduled break is acceptable, and whether you want recovery at a set time or only when an error occurs. A timed restart can itself create a visible interruption, even when the process starts successfully. Avoid adding a restart simply because the stream is old; first check whether the stream actually benefits from one.
Prepare the YouTube stream URL and key
In YouTube Live Control Room, use the current server URL and stream key for the intended stream. The encoder needs both: the server URL identifies where it should connect, and the key authenticates the broadcast. YouTube's encoder setup guidance explains the live-stream setup process. Its stream settings page describes the stream key and connection settings, including RTMP and RTMPS options where supported: YouTube stream settings.
Treat the key like a password. Do not put a real key in a public script, a shared screenshot, a support post, or a command pasted into a shell history that other users can read. Use the current key from Live Control Room; if you reset it, update the protected configuration used by FFmpeg before the next scheduled restart. Otherwise the script may run correctly while YouTube rejects the connection.
Use a dedicated Linux account for the stream if that fits your system, and restrict access to its configuration file. For example, you might keep settings in /home/streamer/.config/yt-live/stream.env and allow only the account that runs the stream to read it. Check ownership and permissions with your distribution's normal tools. Do not assume a file is private merely because it is not in a public web directory.
First run the exact FFmpeg command manually as the account that will run it unattended. Use absolute paths for the FFmpeg executable, input file and any supporting files. Confirm that the input opens, the output protocol matches the YouTube URL, and the intended video and audio settings are accepted. YouTube's quality guidance varies with resolution, frame rate and codec, so test the actual configuration rather than relying on a generic command copied from elsewhere.
A safe example should show the shape of the configuration without exposing the credential. For instance, a configuration may define a server URL and a key separately, while the command joins them only when it launches FFmpeg. Keep diagnostic output from including the expanded output URL, since that URL may contain the key. If your FFmpeg wrapper or shell tracing prints every expanded command, disable that tracing around the sensitive value.
Write a restart script that targets one FFmpeg process
There is no universally safe process-matching command that fits every Linux distribution and deployment. A process-name match such as pkill ffmpeg is too broad when other FFmpeg tasks may run on the same host. Choose a reliable identity for this one stream: a PID file managed by the script, a distinct configuration or input argument that you can match unambiguously, or a service manager configured for this stream. If you already run FFmpeg under a service manager, use that manager's restart mechanism rather than layering a second process controller on top.
A PID file is useful only if you manage it carefully. Record the PID when the script starts FFmpeg, then check that the PID still belongs to the intended command before signalling it. PIDs can be reused after a process exits, so blindly killing the number found in an old file is unsafe. If you cannot verify ownership, stop and investigate rather than killing an arbitrary process. The Linux cron reference describes scheduling syntax; it does not define a universal stream restart script.
The basic sequence is straightforward: acquire a lock so two copies do not overlap, read and validate the protected configuration, stop only the identified stream process, allow it to exit, and start the configured command. If the process does not exit after a graceful termination request, decide explicitly whether and how to escalate. Do not silently use an indiscriminate force-kill as the default. Record a failure status if the old process remains or the new process cannot start.
Below is a deliberately incomplete shell outline, not a drop-in script. The process-identification functions are placeholders because your system must define and test them. start_stream should invoke the real FFmpeg command with absolute paths, -nostdin, the correct input and output settings, and the protected key. It should not print the key or the full output URL to the log.
#./bin/sh
set -eu
LOG=/var/log/yt-live/restart.log
CONFIG=/home/streamer/.config/yt-live/stream.env
log() {
printf '%s %s\n' "$(date -Is)" "$*" >> "$LOG"
}
# Implement these for this host. Verify that any PID belongs to this stream.
stop_this_stream() {
:
}
start_stream() {
:
}
log "restart requested"
# Load protected settings only after checking ownership and permissions.
# Do not enable shell tracing or log expanded command arguments here.
stop_this_stream
start_stream
log "start command issued; verify reception in Live Control Room"
Before scheduling anything, replace the placeholders with tested functions and make the script executable by the chosen account. Ensure the account can write to the log and read the configuration, but do not grant broader access than needed. If the restart script is long or stateful, a service unit or another process supervisor may be easier to reason about than hand-written PID management.
A separate continuous loop is not always the answer either. For a file-based playlist or a repeated recording, prepare the media and playback command deliberately; the guide to preparing video files for OBS playlist streaming on Linux covers a neighbouring workflow. A restart script should not be used to disguise an input that reaches its end or a command that was never configured to loop.
Add logging and protect credentials
Logging should tell you what the job attempted and what happened, without leaking the key. Useful entries include the timestamp, that a restart was requested, whether the identified process was found, whether termination succeeded, whether the new process was launched, and a failure reason. FFmpeg's error output can help diagnose input or connection problems, but review it for sensitive URL material before keeping or sharing it.
Append output to a file with permissions limited to the stream account and administrators who need to troubleshoot. Rotate the log if it can grow without limit. Keep the script's own status separate from FFmpeg's output where practical, so you can distinguish a failure to run the wrapper from a failure in the encoder. A message that says “start command issued” is not evidence that YouTube has received a healthy stream.
Protect the key at every point where it might appear: configuration, process arguments, shell tracing, logs, backups and terminal history. Some operating systems expose process arguments to other local users, depending on configuration. If that matters on your host, use an approach suited to its security model, restrict account access, and check the actual process visibility rather than assuming a hidden file solves every exposure. Avoid posting diagnostic logs until you have checked and redacted credentials.
When the key is reset in Live Control Room, update the protected configuration and test a fresh connection manually. A cron restart cannot fix an outdated credential. If you share the host with another operator, agree who can change the key and who updates the encoder, so the next scheduled run does not fail unexpectedly.
StreamNeo can remove the need to keep a Linux computer and its cron process running for a file-based 24/7 YouTube broadcast, which matters when the operational pain is maintaining the host rather than controlling a custom FFmpeg pipeline. It takes an uploaded video and runs the YouTube broadcast with the computer switched off; it is YouTube-only. That does not replace this guide when you need a bespoke Linux encoder workflow or a live capture input.
Schedule the job with cron
Once the script works manually, add it to the crontab of the account that should run it. A five-field entry such as 0 3 * * * /home/streamer/bin/restart-yt-live.sh is an example of a daily run at 03:00 according to the cron environment's local time. Adapt the time to a quiet period for your viewers, and check your system's timezone and daylight-saving behaviour. Do not put a stream key in the crontab line.
Cron's environment is smaller than an interactive shell's. Use absolute paths, set any required environment values in the script, and do not depend on a shell profile to define PATH. Ensure the script has a valid interpreter line and that the account can access its input, configuration and log. Test the exact script under that account before relying on the schedule.
Cron checks entries on a minute-based schedule, but the exact handling of unusual schedules and local-time changes is a matter to verify for your cron implementation. The crontab reference documents the schedule fields and day matching. If your requirement is “restart after an error” rather than “restart at 03:00”, a timer is not a health check; consider a supervisor or error-aware design instead.
Avoid overlapping runs. A lock or equivalent guard should make a second invocation exit safely while the first is still stopping and starting the stream. Otherwise a delayed script can create two FFmpeg processes, or one run can terminate a process launched by another. Include a clear log entry for a skipped run, and make sure the lock is released if the script exits unexpectedly.
Start with a schedule that you can observe, then inspect both the script log and YouTube's reception view after it fires. If the restart causes a noticeable gap at a busy time, move it or reconsider whether a periodic restart is needed. A maintenance window is an operational choice, not a promise that viewers will not notice the interruption.
Use -nostdin and decide whether -re fits
For unattended execution, FFmpeg's -nostdin disables interaction with standard input. This prevents an encoder running in the background or from cron from waiting for console input that nobody can provide. Put it in the FFmpeg invocation, then test the command outside cron so you can catch configuration errors before the scheduled run.
The -re option reads an input at its native frame rate. It is commonly useful when you are sending a media file as a live stream and want it paced in real time rather than read as quickly as possible. It is not a universal “make streaming work” switch. FFmpeg cautions against using a low read rate on an actual live input, such as a live capture or network feed, because pacing it again can contribute to packet loss.
| Input and goal | Consideration | Practical choice |
|---|---|---|
| Recorded file sent as a live programme | The file can otherwise be read faster than real time | Consider -re to pace the file, then test playback and audio synchronisation |
| Live capture or network input | The source is already arriving in real time | Do not add -re by habit; follow FFmpeg guidance for the input and observe for packet loss |
| File playlist intended to repeat | Restarting the process is separate from defining playback behaviour | Configure looping deliberately and verify how the playlist transitions |
| Stream output interrupted temporarily | The process may still be running while output recovery is needed | Assess FFmpeg FIFO recovery separately from a timed process restart |
These are decision points, not a complete FFmpeg command. Input options can be order-sensitive, and codec, resolution, frame rate, keyframe interval and bitrate must match what your source and connection can sustain. YouTube recommends testing with the intended audio and video and monitoring stream health. See its live encoder troubleshooting guidance if the stream does not arrive as expected.
Verify reception in YouTube Live Control Room
After the cron job fires, check the job's log for the sequence of events and inspect FFmpeg's diagnostics for a useful failure reason. Then open the relevant stream in YouTube Live Control Room. Confirm that YouTube is receiving the encoder signal, that the preview shows the intended picture, and that audio is present when expected. Check the stream health indicators rather than treating a successful shell exit as proof of delivery.
YouTube's live streaming tips recommend testing the encoder and monitoring the stream. A running FFmpeg process only proves that a process exists; it does not prove that the stream URL and key are current, the network path is working, or YouTube can decode the output. Likewise, a log line that the command was launched says nothing about whether the Control Room has received valid media.
If reception is absent, work from the boundary where the evidence stops. A missing cron log entry suggests a scheduling, account or script-path problem. A wrapper error points to permissions, configuration or process handling. FFmpeg connection errors suggest checking the current URL and key, protocol, network access and encoder configuration. If YouTube receives a signal but reports poor health, inspect the actual media settings and upload capacity rather than repeatedly restarting without diagnosis.
Test the whole sequence before depending on it overnight: run the script manually, confirm the intended process stops and starts, then observe a scheduled run. Keep a note of the stream time and what the Control Room showed, so you can compare it with the log if a later restart fails. For streams that rotate source material, the guide to diagnosing YouTube health warnings during playlist changes can help separate a transition issue from a failed encoder restart.
A successful test does not guarantee every later reconnect will work. Keys can be reset, input files can change, and network or YouTube conditions can differ. The useful outcome is a repeatable procedure that identifies what happened and leaves you with enough evidence to decide what to fix next.
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
Does cron restart FFmpeg automatically if it crashes?
Not by itself. A cron entry runs at scheduled times; it does not continuously watch a process or know whether FFmpeg crashed between runs. If you need recovery based on process failure, use a supervisor or another design that checks the process condition.
Can I use pkill ffmpeg in the restart script?
Avoid it on a host where other FFmpeg tasks may run, because it can stop unrelated processes. Target a verified PID or a uniquely identified service for this stream, and test that the stop action affects only the intended encoder.
Should I add -re to every command?
No. It can pace file input for a live broadcast, but FFmpeg cautions against applying a low read rate to actual live inputs. Decide based on whether the source is a file or already-live capture/network input, then test the result.
How do I know the restart worked?
Check the script and FFmpeg logs for the attempted stop and start, then verify reception, preview and health in YouTube Live Control Room. The process being present is not enough to establish that YouTube is receiving a healthy broadcast.