Skip to content
streamneo.
Setup Guides13 min read

How to Run a YouTube Loop Stream on Linode with Ubuntu and systemd

A practical guide to looping authorised video from an Ubuntu Linode to YouTube Live, with systemd supervision and clear recovery limits.

sn.
StreamNeoPublished 7 October 2026
Worth sharing?

A Linode running Ubuntu can keep an encoder process online after you disconnect from SSH, while FFmpeg reads and loops a video file and sends the feed to YouTube Live. systemd can start that process and restart it after some failures, but it cannot guarantee an uninterrupted broadcast or replace checking YouTube's stream health.

The workflow has four separate parts: confirm your channel can go live, create the event and obtain its ingest details, prepare authorised media and an encoder, then supervise and monitor the process. Keep the stream key private, test the complete path before leaving it unattended, and check your Linode transfer terms against the actual bitrate you send.

Prepare the Linode and Ubuntu host

Create an Ubuntu Linode in a region that suits your likely audience and the workload. The location can affect network path and latency, but it does not by itself determine whether YouTube viewers receive a stable stream. Choose a host with enough CPU for the encoder settings you plan to use, enough disk for the source video and logs, and network capacity for continuous outbound traffic. Check Linode's current plan and transfer terms before committing; older community discussions are not reliable evidence of current allowances.

Use an unprivileged Linux account for the stream process rather than running FFmpeg as root. Keep administrative access separate, use SSH keys where possible, and apply Ubuntu security updates through your normal maintenance process. Upload the video to a directory that the stream account can read, and avoid placing it in a temporary folder that might be cleaned automatically. A long loop still depends on the local file remaining available and unchanged.

Treat this host as an encoder, not a video library that YouTube can fetch from a URL. The source must be a local file readable by FFmpeg. A YouTube playlist URL is not a local media file, and downloading or rebroadcasting other creators' material can violate rights or platform rules. Confirm that you have permission for both the picture and the audio before using a video as a continuous live source.

Before configuring the stream, decide whether a single file meets the programme's needs. If you need a changing rotation, the workflow differs from looping one video; this guide on creating a YouTube live loop playlist that randomises videos explains a different content pattern. For a single-file loop, keep the source and the live event distinct in your planning: the file is on the host, and YouTube receives an encoded feed.

Schedule the YouTube Live event and retrieve its ingest details

First confirm that live streaming is enabled for the channel. YouTube's live-streaming eligibility guidance describes the current account requirements, including verification, age, and restrictions. If the channel is not eligible yet, resolve that before building the host workflow; an encoder cannot bypass account restrictions.

In YouTube Studio, create or schedule a live stream in Live Control Room. Set its title, description, audience, visibility, and intended start time. Decide whether the event should be public, unlisted, or private, and review its archive settings in the interface. These choices are separate from the encoder: systemd can keep sending a feed, but it cannot choose who can watch or how YouTube handles the event after it ends.

Open the stream settings and copy the current ingest URL and stream key. YouTube documents how to find these in Live Control Room stream settings. Prefer the RTMPS address when your chosen encoder supports it. YouTube explains that RTMPS encrypts the connection between encoder and ingestion service; this protects transport, not the key stored on your Linode or media at rest.

A stream key is a credential. Do not paste a real value into a public shell transcript, a tutorial screenshot, a shared configuration file, or a support request. If it is exposed, reset it from YouTube Studio and update the host's configuration. Avoid putting it directly into commands that may be saved in shell history. You will need a secure, permission-restricted way to pass the key to the service process, and should verify how your chosen FFmpeg invocation receives it before making a unit file.

Install FFmpeg and verify the source media

Install FFmpeg from a package source appropriate to the Ubuntu release on your Linode, then check that the executable is available to the account that will run the service. Package names, build options, and installed paths can vary by release and repository, so verify the result on the actual host rather than assuming a command from another distribution applies. Confirm the FFmpeg version and that the build supports the output protocol and codecs you intend to use.

Check that the uploaded source is readable by the stream account, and inspect its duration, video dimensions, frame rate, audio tracks, and codecs. A file that plays on a desktop can still be a poor live input if it has an unsupported stream, unexpected variable frame rate, damaged sections, or no audio when the programme requires it. Test it with representative movement and sound rather than checking only its filename or file size.

YouTube's encoder settings guidance and bitrate table sets requirements and recommendations by codec, resolution, and frame rate. For example, its table for 720p at 30 frames per second lists H.264 at a 3 Mbps minimum and 8 Mbps recommended, while AV1 or H.265 is listed at a 2 Mbps minimum and 6 Mbps recommended. These are different settings, not a universal bitrate prescription. Choose a combination your host can encode reliably and your outbound budget can sustain.

There is a trade-off between picture detail, CPU use, compatibility, and traffic. A lower resolution or bitrate can reduce processing and transfer demands, but may make fine text or detailed devotional artwork less clear. A more demanding codec can achieve a given visual result at a different bitrate, but only helps if the installed FFmpeg build, YouTube ingestion path, and host can handle it. Use YouTube's current table for the chosen profile, then observe actual CPU and stream health during a test.

Build a loop for authorised local video

The encoder must read the file repeatedly and send a continuous live output. FFmpeg supports looping inputs, but exact option placement and output behaviour depend on the build, source format, and target protocol. Validate the specific FFmpeg documentation and test invocation on your Ubuntu version before turning it into an unattended service. In particular, confirm that looping applies to the input, that timestamps and audio behave as expected at the boundary, and that the process does not exit at the end of one pass.

Do not copy a command blindly and assume the stream will recover from a network interruption. Input looping and output reconnection are separate concerns. A command may correctly repeat a file yet stop when the connection fails; another may reconnect but fail to resume cleanly at the expected point. Test both normal looping and a deliberate interruption on a non-public or otherwise suitable event before relying on it.

Set video and audio encoding parameters to match the YouTube settings selected earlier: codec, resolution, frame rate, bitrate mode, keyframe interval, and audio format. YouTube recommends constant bitrate, supports several codecs, and recommends a two-second keyframe interval with no interval above four seconds. Use the details on the official encoder page rather than a universal one-line command. Match the configuration to the event and the ability of the Linode to sustain it.

If the stream is a still devotional image with music, the media may impose a different CPU load from a motion-heavy video, but do not assume it is automatically trivial. Decode and encode behaviour depends on the file and chosen output settings. Watch the host while the process runs, and make sure it has headroom rather than sitting at a sustained resource limit. For a different host approach, compare the operational trade-offs in this guide to a cloud PC versus a VPS for a nonstop channel in India.

Test the feed in YouTube Live Control Room

Start with a controlled test. Use representative media, the planned resolution and audio, and the actual network route and key handling. Check that Live Control Room receives the encoder feed and shows a preview before treating the setup as ready. Listen as well as watch: a preview can show moving video while audio is silent, distorted, out of sync, or missing altogether.

YouTube advises checking stream health and messages in Live Control Room. Give the preview time to reveal issues such as dropped frames, poor audio, or a mismatch between encoder settings and the event. Confirm that the intended audience can access the event at the selected visibility. A healthy-looking encoder process alone does not prove that YouTube is receiving a usable stream or that the public event is available as intended.

Test the loop boundary. Watch and listen through the transition from the end of the file to the beginning. Check for a black frame, audio gap, abrupt volume change, duplicated segment, or an early process exit. If the source has a deliberate opening slate or silence, decide whether seeing it on every repeat is acceptable. A loop that looks seamless in a local player may behave differently once encoded and ingested.

Keep the test event's archive and visibility settings in view. A test can be private or unlisted while you validate, but confirm the final event's settings separately before the intended audience arrives. YouTube's event controls and the encoder process have different jobs. This is also a good point to compare the approach with running a 24/7 YouTube stream using FFmpeg on an Oracle Cloud VM: the media and YouTube checks remain useful even when the host provider changes.

Create and enable a systemd service

Once the command has been tested interactively, make systemd responsible for starting it independently of your SSH session. A service unit generally identifies the account, working directory, start command, and process behaviour. It can start the encoder when requested and apply a restart policy after the process exits. It does not repair a bad command, restore a deleted source file, fix an invalid key, or guarantee that YouTube accepts the feed.

Before writing the unit, verify the executable path, file permissions, working directory, and how the stream key is supplied. Keep secrets in a protected configuration mechanism accessible only to the service account and administrators. Check systemd's current documentation for unit directives and environment handling; do not assume shell features such as variable expansion or redirection work inside an execution directive as they do in an interactive shell. If a wrapper script is needed, keep it readable, executable only by appropriate users, and free of exposed credentials.

Choose restart behaviour deliberately. A restart after failure can recover from a process crash or an unexpected exit, but an aggressive restart loop can repeatedly launch a process that will never work, consume resources, and obscure the underlying fault. A systemd rate limit can also stop repeated attempts. Review the service's current status and logs after starting it, and confirm a manual stop behaves as intended. A service configured to restart should not be mistaken for continuous service availability.

Enable the unit only after a successful controlled test. Then reboot or otherwise validate the intended start behaviour during a maintenance window, while you can observe both systemd and YouTube. Verify that the process runs as the intended user, can read the media and secret configuration, and begins sending to the correct event. If you are not comfortable checking unit semantics or secret permissions, keep the setup attended until someone qualified has reviewed it.

Check logs, restarts, and transfer usage

When a stream stops working, diagnose in layers. First check that the source file still exists and is readable. Next inspect whether FFmpeg is running and whether its recent output indicates an input, encoding, or connection problem. Then check systemd's service state and journal for exits, restart attempts, permission errors, or rate limiting. Finally, inspect Live Control Room for received data, stream health, and event availability. Each layer answers a different question; a running unit is not proof of a healthy broadcast.

Use systemd's status and journal tools to review the unit and its recent logs, but protect the output before sharing it. A command line or diagnostic log may contain the stream key or other sensitive details. Redact those values, and rotate the key in Live Control Room if there is any chance it was exposed. After changing the key, update the protected host configuration and restart the service, then confirm that YouTube receives the feed again.

A 24/7 output also creates ongoing transfer use. Estimate the payload with bitrate in bits per second multiplied by seconds of streaming and divided by eight to convert bits to bytes; then allow for protocol overhead and other traffic. This is arithmetic, not a fixed provider allowance or a promise about billed usage. Measure the actual output where possible and compare it with Linode's current terms and usage reporting. Linode does not remove transfer limits simply because the video is a live stream.

For context, a continuous 8 Mbps video payload would be roughly 86.4 gigabytes per day using decimal units before overhead: 8,000,000 bits per second × 86,400 seconds ÷ 8, then converted to decimal gigabytes. The real amount can differ because of actual bitrate variation, audio, transport overhead, reconnects, and other host traffic. This example is a calculation, not a Linode plan allowance. Check current provider terms rather than relying on historical figures in forum posts.

Also review CPU, memory, disk space, and log growth. A loop can run for days while logs or other files accumulate, and a full disk can turn an otherwise healthy service into a failure. Plan how you will notice a failed encoder, an unhealthy YouTube ingest, or an event that is no longer accessible. systemd can restart a process when its configured conditions are met; it cannot tell you whether the programme content is appropriate, whether the audio sounds right, or whether viewers can watch.

For a channel that needs human response, arrange a routine check and a notification path appropriate to the channel. Do not treat an unattended service as unattended operations. A power or provider problem, expired or reset key, source-file issue, YouTube event setting, or software update can all require a person to investigate. The guide to keeping a devotional stream live during power cuts in India covers a different failure mode: your cloud host may remain online while local production or monitoring still needs attention.

If maintaining Ubuntu, FFmpeg, unit files, secret permissions, and transfer checks is more operational work than you want, StreamNeo removes the specific burden of keeping your own encoder host and systemd service running: you upload a file, provide the YouTube key, and can switch off your computer. It remains your responsibility to use authorised media, configure the event, and check the stream.

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

Can systemd keep a YouTube stream running after I close SSH?

Yes, a system service runs separately from your interactive SSH session, so closing the terminal does not itself stop the encoder. It can also restart a process after certain exits if configured to do so. It cannot guarantee uninterrupted streaming or confirm that YouTube is receiving a healthy feed.

Can I loop a YouTube playlist URL with this setup?

No. This workflow loops a local video file that FFmpeg can read, not a YouTube playlist URL. Use media you have permission to broadcast, and verify the local file's format and playback before configuring the encoder.

Does a Linode make 24/7 streaming unlimited?

No. Continuous outbound video uses transfer, and the applicable allowance or billing depends on Linode's current terms and your actual traffic. Estimate from the encoder bitrate, measure usage, and check the current provider information rather than relying on old community examples.

What should I check if the service is active but the stream is offline?

Check the source file and FFmpeg logs first, then the systemd journal and service status, and then Live Control Room's preview and health messages. Confirm the key and event settings without exposing the key in logs or screenshots. A process can be active while its output is rejected, disconnected, or attached to the wrong event.

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 Setup Guides guides ↗ · All topics ↗