Skip to content
streamneo.
Troubleshooting12 min read

How to Set Up a YouTube Live Video Loop on Google Cloud Compute Engine

Run a prerecorded YouTube Live loop on a Compute Engine VM, with systemd restart handling and checks for actual stream health.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

A YouTube Live video loop on Google Cloud Compute Engine uses a Linux VM to run an encoder such as FFmpeg, which sends a prerecorded video to YouTube repeatedly. You can use systemd to restart the encoder after certain process failures, but that only shows the process has been relaunched; it does not prove YouTube is receiving a healthy stream.

You will need a channel eligible to go live, a stream created in YouTube Studio, a billing-enabled Google Cloud project, and media the VM can read. The sections below cover the setup and, importantly, how to tell process recovery apart from a working broadcast.

Check the channel and prepare the stream

Before creating a VM, check that the channel can go live. YouTube’s live-streaming eligibility help says a channel must be verified and must not have had live-streaming restrictions in the previous 90 days. Check the current Help page for the channel’s status and any requirements that apply to it.

In YouTube Studio, open Live Control Room and create or schedule a stream. Choose the privacy setting deliberately. A private or unlisted test lets you inspect the feed before using a public broadcast; it is not a substitute for checking the preview and stream health indicators.

The encoder needs the ingest server URL and stream key shown for that stream. YouTube explains how to create a stream with an encoder. Treat the key as a password: avoid putting it in a public repository, a shared screenshot, or a log that others can read. YouTube’s stream settings guidance describes stream keys as similar to a stream’s password and address. If the key is exposed, reset it in Live Control Room and update the encoder.

YouTube recommends RTMPS for an encrypted connection. Live Control Room may show an RTMP URL by default; reveal the RTMPS option if you intend to use the encrypted ingest URL. Copy the URL and key carefully. A misplaced character can prevent the encoder from connecting, and changing the key in Studio means the sender must use the replacement.

Put the VM and media in place

Create a Linux Compute Engine VM in a Google Cloud project with billing enabled. Google’s Compute Engine Linux VM guide shows creating an instance and connecting over SSH; Ubuntu 24.04 LTS is an example in that guide, not a requirement for this workflow. Choose a supported Linux image and confirm that the FFmpeg package or build you intend to use is available for it.

A VM that runs continuously can incur compute and network charges. The actual cost depends on the selected machine, its runtime, storage, and network use. Check current Google Cloud pricing and your project’s billing controls rather than relying on an old estimate. If you are only testing, remember to stop or delete resources when finished; an always-on channel, by contrast, needs the VM to remain available.

Place the authorised source video somewhere the VM can read, such as its attached storage or another storage location you have configured. The research behind this guide does not establish one required upload method, nor does it establish a suitable VM size for a particular file. Make sure the file is complete and readable before configuring a service, and confirm there is enough disk space for any local copy.

A VM-initiated stream normally sends traffic out to YouTube. Google’s VPC firewall overview says default VPC rules allow outgoing traffic and block incoming traffic by default. You do not inherently need to open an inbound port merely to send a stream outbound. Actual egress still depends on the VM machine type and routing, so investigate connectivity if the VM cannot reach the ingest endpoint.

Run FFmpeg as the service’s main process

Systemd supervises a service process. For useful restart behaviour, FFmpeg should be the service’s foreground process, so systemd can observe its exit status. If a shell script starts FFmpeg in the background and exits successfully, systemd may consider the script itself to have completed. It then cannot supervise the encoder in the way you intend.

The service configuration should run the selected FFmpeg executable directly, with its input, loop behaviour, video and audio settings, and YouTube ingest destination supplied as arguments. Do not treat a command found in an unrelated article as verified for your particular FFmpeg build. The exact loop syntax and reconnect behaviour have not been established here, and options can vary with the build and use case. Check current FFmpeg documentation for the options you choose, then test the actual command with your file and a private or unlisted stream.

The sender must also match YouTube’s current encoder requirements. Its encoder settings page lists accepted video and audio codec choices and guidance on bitrate, frame rate, rate control, and keyframes. YouTube recommends a two-second keyframe interval and says it should not exceed four seconds. Bitrate depends on resolution and frame rate; consult the live guidance when configuring the stream rather than copying a figure into a setup that may be revisited later.

Keep the command understandable and protect credentials. A stream key embedded in a service file can be readable by users with sufficient system access; do not make the unit file world-readable or place its contents in a public repository. Consider who can inspect service configuration and logs on the VM. Avoid printing the full ingest URL if it includes the key when troubleshooting.

If the unit invokes a wrapper script, the wrapper should remain in the foreground and hand control to FFmpeg rather than detach it. The aim is to have systemd track the process whose health matters. For related configuration pitfalls, see setting up an FFmpeg stream key for a Telugu devotional playlist and running FFmpeg on Raspberry Pi OS Lite; those workflows are not substitutes for checking the arguments and paths on your Compute Engine VM.

Create a systemd unit

A systemd unit describes how to start the long-running sender. Create a service unit with a clear name, a description, the account under which it runs, the working directory if needed, and an ExecStart that launches the foreground encoder. The unit should also define the restart policy and delay that suit your recovery approach. Use the systemd documentation for the syntax supported by the Linux distribution on the VM.

For example, a unit’s shape is conceptually: a service section with User, optional WorkingDirectory, ExecStart pointing at FFmpeg and its arguments, and Restart plus RestartSec settings. This is a layout illustration, not a complete copy-and-paste unit: paths, account names, command options, and credential handling must match your own machine. A malformed unit or an incorrect file path will fail before YouTube is involved.

Keep the executable and arguments explicit. Avoid relying on shell aliases, an interactive user’s environment, or a relative path that only exists in an SSH session. If your input file is at /home/channel/media/loop.mp4, for example, confirm that the service account can read that exact path. Similarly, confirm the account can access any required configuration without granting broad permissions unnecessarily.

After creating or changing a unit file, systemd needs to reload its unit definitions before it can use the new configuration. It is useful to separate two checks: whether systemd accepted the unit and whether FFmpeg can actually read the file and connect to YouTube. A successful unit reload says nothing about the remote ingest receiving valid audio and video.

Set restart behaviour for failures

A restart policy can ask systemd to start the service again when its main process exits unsuccessfully. That is the central distinction from a one-off SSH command: if FFmpeg crashes or exits with a failure, the supervisor can attempt another launch according to the policy. Choose a policy whose documented semantics match the outcome you want; do not assume that every exit or stop is treated as a crash.

A policy such as on-failure is commonly used when a process should be restarted after an unsuccessful exit, while a clean exit is not automatically treated the same way. Verify the exact behaviour against your distribution’s systemd documentation. If a process repeatedly fails, systemd may apply start-rate limits rather than launch it without end. A restart policy is therefore recovery machinery, not a correction for a bad file path, invalid stream key, incompatible encoder settings, or a network route that never works.

Systemd does not restart a manually stopped service as though it had crashed. An operator stop is an intentional management action, and it must remain possible to stop a stream without a supervisor immediately undoing that action. Likewise, a systemd restart does not guarantee that YouTube’s live session recovers, that playback is uninterrupted, or that viewers see a continuous programme. It can relaunch a local process; YouTube still has to accept the new connection and receive a healthy feed.

That difference matters overnight. A log showing “started” or a service status of “active” means systemd has a process running, not that the video is moving in Live Control Room. If the encoder is alive but sending no frames, systemd may have no process failure to detect. If YouTube rejects the stream key, a restart can repeat the same rejection. For troubleshooting, compare the process state with the Live Control Room indicators rather than treating one as proof of the other.

Choose a delay and understand restart limits

A restart delay gives a failed process time before the next start attempt. It can prevent rapid repeated launches from hammering logs and immediately repeating a transient failure. It also means recovery is not instantaneous. Select a delay based on the failure modes you expect and the acceptable interruption for your channel; no single value can guarantee a YouTube session will resume.

Repeated failures may trigger systemd’s start-rate limiting. The service can then stop attempting further starts until the limit condition is cleared or the manager is reset, depending on configuration. Consult the systemd manual pages for Restart=, RestartSec=, and start-rate settings on the VM’s installed version. Avoid disabling limits just to conceal a persistent configuration error: a loop of failed starts can consume resources and obscure the first useful error in the logs.

Test the expected cases deliberately. First, start the service with a working file and verify the outgoing feed. Then observe what happens when FFmpeg exits due to an ordinary failure in a controlled test, and check whether systemd records a new attempt. Do not expose the live stream key while doing this. A useful test also confirms that repeated attempts eventually become visible as rate-limited rather than silently assumed to continue forever.

Enable, start, and inspect the service

Once the unit is in place, reload systemd, start the service, and enable it if it should start when the VM boots. Enabling affects boot behaviour; it does not mean the service is currently healthy. Starting it is a separate action. Use systemctl status to see systemd’s view of the unit, and inspect the journal for the service when it fails or restarts.

Read the first relevant error, not only the last line. A “no such file” message points towards an input path or working-directory issue; a permission error suggests the service account cannot read the media; a connection or authentication error points towards the destination, key, or network. Exact messages vary. Correct the underlying problem before repeatedly restarting the same broken command.

Keep a record of the unit changes and the time you made them, but redact the stream key from notes and shared logs. If you change the key in YouTube Studio, update the service configuration and restart the service intentionally. Use systemd’s stop action when you want to stop the broadcast; do not rely on killing a child process inside a wrapper and assume the unit’s state will follow.

The service may restart after a VM reboot if it is enabled, but booting the local process is not the same as restoring a YouTube broadcast session. Check the VM’s boot outcome, the unit state, and the Live Control Room after a reboot or maintenance event. For a closer look at how loop behaviour can go wrong even when a picture repeats, see why a fireplace video can repeat while its audio does not loop. A separate decision about hardware is covered in whether FFmpeg needs a GPU for 24/7 YouTube streaming; do not infer a VM requirement without testing your own encoding workload.

Verify stream health in Live Control Room

Open Live Control Room and check the stream preview, connection status, audio, and video. YouTube’s encoder setup guidance recommends testing and monitoring the feed. Watch for a moving picture, audible sound, and any status or health warnings. The preview is the evidence that the platform is receiving a stream; a running Linux process alone is not.

Test privately or unlisted before making the broadcast public. Confirm that the correct source video is playing, that audio stays in sync, and that the stream continues across the intended loop point. A file that plays locally may still produce a black frame, silent audio, or a broken transition after encoding. Let the test cover enough of the content to inspect the loop boundary rather than checking only the opening seconds.

If systemd says the service is active but Live Control Room shows no incoming feed, troubleshoot the connection and encoder separately. Check that the RTMPS URL and current key are correct, the VM has outbound connectivity, and FFmpeg is producing the expected codecs and stream settings. If the process has exited, inspect the journal first. If it remains alive while the feed is unhealthy, restarting it may be a useful diagnostic action, but do not mistake the action itself for confirmation of recovery.

YouTube says streams under 12 hours are automatically archived in its encoder setup help. Do not treat an archive as a monitoring system for a 24/7 channel: check the live session while it is running and verify what YouTube currently supports for your use. Also remember that this design depends on you maintaining the VM, the unit, the media, and the stream settings. If managing a VM and its recovery checks is the pain point, StreamNeo can remove that particular burden by taking an uploaded video and running it as a YouTube live stream while your computer is off.

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 systemd restart FFmpeg if the process crashes?

It can, if FFmpeg is the service’s main foreground process and the unit’s restart policy covers that failure. Confirm the installed systemd version’s behaviour and inspect the journal after a controlled test. The restart only confirms a new process attempt, not a healthy YouTube feed.

Will systemd restart a service I stop manually?

No. A deliberate stop is not the same as an unexpected process failure, and systemd should not undo an operator’s stop action. Start the service again explicitly when you are ready to resume.

Does a restarted FFmpeg process restore the YouTube Live session?

Not necessarily. YouTube must accept the encoder’s new connection and receive usable video and audio; check Live Control Room rather than relying on systemctl status. Neither a restart policy nor an active process guarantees uninterrupted playback.

Can I copy a loop command from this guide?

No command here is presented as tested or authoritative. Check current FFmpeg documentation for the syntax supported by your build, then test the actual file, settings, and YouTube connection in a private or unlisted stream.

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 ↗