Skip to content
streamneo.
Setup Guides13 min read

How to Run a YouTube Radio Station from a Linux Server with systemd

Build a headless YouTube radio stream with Liquidsoap scheduling, FFmpeg encoding and systemd supervision on Linux.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

A headless YouTube radio station can be run as a Linux process: Liquidsoap selects and schedules audio, an FFmpeg-backed output encodes the audiovisual feed, and systemd supervises the foreground process. The destination is YouTube Live over RTMP or RTMPS; Icecast is a separate, optional destination for listeners using a conventional radio player.

This guide covers the moving parts and a practical service setup. It does not promise uninterrupted transmission: systemd can restart a process that exits, but it cannot fix a broken network, an invalid stream key, a full disk, or a source that keeps failing.

Plan the headless stream architecture

Think of the system as three jobs joined together. A scheduler chooses what to play and when. An encoder combines the audio with a video signal and sends the result to YouTube's ingest endpoint. A service manager starts the process at boot and can try to restart it after an exit. You can run these jobs from a remote Linux host without a desktop environment, provided the installed Liquidsoap build includes the output and encoding support you configure.

The destination matters. YouTube Live accepts an encoder feed at the URL and stream key shown in YouTube Studio. Icecast, by contrast, serves audio to radio players or directories through a stream URL and mount point. Liquidsoap can publish to either; you do not need to install or operate Icecast merely to send a feed to YouTube. Add it only if you also want a conventional internet-radio endpoint. The Icecast documentation describes that separate role.

Question YouTube Live output Optional Icecast output
Where does a listener go? A YouTube watch page A radio player or directory using your stream URL
What is sent? An encoded audiovisual feed to YouTube ingest Audio from Liquidsoap to an Icecast mount
When does it fit? You want the station to be a YouTube live channel You also want a conventional radio stream endpoint

This is a distinction of delivery, not a quality ranking. They can be used together if your software and host are configured to produce both outputs, but each has its own credentials, listeners and failure modes. If you are still deciding whether a computer should run the broadcast at all, the practical constraints in using an Intel NUC for a 24/7 prerecorded stream are a useful contrast to a server-based setup.

Before installing anything, check that your YouTube channel can create live streams, that you have suitable audio and visual material to broadcast, and that the host has sustained upload capacity for your selected settings. YouTube notes that initial live-stream enablement can take up to 24 hours, so do not leave channel activation until the evening you plan to launch. Make sure you have the rights needed for the material you intend to use; rights depend on the material and circumstances, so check them before broadcasting rather than assuming a playlist is cleared.

Schedule audio with Liquidsoap

Liquidsoap is the radio automation layer. It can read files from a folder, build a playlist, apply scheduling logic and feed an output. Start with a small, known collection of files and a simple rotation. Once that behaves as expected, add time-based shows, jingles or fallback sources. This makes it easier to tell whether an error is in file access, scheduling, encoding or the YouTube connection.

Keep the media library and configuration in paths the service account can read. A process that works when launched in your interactive shell may fail under systemd because the service has a different user, working directory and environment. Use explicit paths, check file permissions, and avoid relying on shell aliases or environment variables that only exist in your login session.

A schedule should have a defined answer for gaps: for example, a fallback playlist or a station slate in the audio chain. Test a deliberately empty or missing playlist path before relying on the service overnight. Decide how you will add new files, and whether the schedule should pick them up immediately or only after a planned reload. A safe change process is to validate the configuration, apply it during a quiet period, then listen to the resulting output.

The guide to removing long gaps from a podcast playlist is relevant if your source material is spoken-word recordings rather than continuous music. Even with a smooth playlist, monitor levels and transitions: a scheduler can select the right files while the files themselves contain silence, clipped openings or unexpectedly different loudness.

Install Liquidsoap using a package or build that supports the output you plan to use. Its available operators and command-line options depend on the installed version and build features. Confirm FFmpeg support and the codecs you intend to use before writing a production configuration. Use the installed version's documentation as the authority for syntax; examples copied from another version may not validate unchanged.

Provide the video component

A radio schedule supplies audio, but an encoder workflow sends an audiovisual feed. Decide what viewers should see while listening: a station identity image, a gently changing visual, a programme card, or another visual treatment that you have permission to use. A fixed visual may be a reasonable choice when the station has no reason to show live pictures, while a changing visual can identify programme segments. YouTube's encoder guidance specifies video and audio settings; it does not prescribe a particular visual design.

Make the visual part of the actual output, rather than assuming that a running audio playlist alone has produced the feed you intended. With an FFmpeg-backed Liquidsoap output, configure an appropriate video source alongside the audio source. Confirm the installed Liquidsoap and FFmpeg combination can provide that source and encode the chosen formats. A test should show both moving or static picture as intended and audible, correctly routed programme audio in YouTube's preview.

A simple visual also has operational consequences. A large image, complex animated loop or high-resolution video source consumes processing and memory that a still image may not. Choose a source your host can render and encode continuously, and test it for longer than a quick local preview. Check aspect ratio, text legibility on a phone, and whether the image remains suitable throughout the schedule. If you plan to change the visual while the stream is active, test that workflow separately rather than assuming a configuration reload will switch it cleanly.

Keep the visual assets local and in stable paths, and grant the service user read access. If the encoder cannot open an image or video file after reboot, systemd may restart the process without correcting the missing asset. For channel-specific operational considerations, see the article on changing the video on an active YouTube live stream.

Send the encoded stream to YouTube Live

In YouTube Studio, create or open the live stream and copy the ingest URL and stream key from the live control room. YouTube's encoder instructions explain the workflow and state: “To start streaming, enter your YouTube Live server URL and stream key into your encoder.” Put those values in the Liquidsoap output configuration using the syntax supported by your installed build. Do not put a real key in a public example, a source repository or a support message.

Treat the key as a credential. YouTube describes it as information that tells the encoder where to send the feed and enables YouTube to accept it. Restrict access to configuration files that contain it. If it is exposed, reset it through Live Control Room and update the encoder configuration. A key reset will interrupt any process still trying to use the old value until you apply the replacement.

YouTube lists RTMP and RTMPS for ingest and recommends RTMPS as the encrypted option. Its current live encoder settings recommend constant bitrate (CBR), a two-second keyframe interval and no more than four seconds between keyframes. For RTMP or RTMPS it lists AAC or MP3 audio, and H.264, H.265/HEVC or AV1 video. Match the chosen settings to what your Liquidsoap and FFmpeg build supports, then confirm the actual stream health in YouTube Studio.

Use YouTube's figures as ingest guidance, not as a guarantee that a particular virtual server can sustain a bitrate. In the settings table accessed in 2026, YouTube lists H.264 720p at 30 fps as 3 Mbps minimum and 8 Mbps recommended; H.264 1080p at 30 fps is 5 Mbps minimum and 14 Mbps recommended. For stereo, the advanced recommendations specify a 44.1 kHz sample rate and 128 kbps audio bitrate. These are examples for those formats, not settings that every station must use. Check the current table when configuring a different resolution, frame rate or codec.

Your connection needs headroom above the encoded stream's total bitrate, because the capacity available to the host can fluctuate and other traffic may compete for upload. Test from the server or its network path where possible; a speed test from your home connection does not establish what a remote host can upload. YouTube recommends testing with representative audio and motion and monitoring stream health. A short test at the actual resolution and schedule helps expose problems that a local file playback cannot, including dropped frames, unstable ingest or a mismatch between configured and delivered audio.

Run the foreground process under systemd

For production, keep Liquidsoap in the foreground and let systemd supervise that process. The Liquidsoap production guide says: “In production, run liquidsoap in the foreground under a service manager, such as systemd on Linux or launchd on macOS.” Do not daemonise Liquidsoap behind systemd: the manager needs to track the process it started.

A minimal illustrative unit follows. Replace paths and account names with those used by your installation, and review the Liquidsoap production documentation for your version.

[Unit]
Description=YouTube radio stream
After=network-online.target
Wants=network-online.target

[Service]
User=liquidsoap
Group=liquidsoap
ExecStart=/usr/bin/liquidsoap /etc/liquidsoap/radio.liq
Restart=always

[Install]
WantedBy=multi-user.target

Create a restricted service account rather than running a radio process as root. Give that account access only to the configuration, media and visual assets it needs, and ensure sensitive stream-key files cannot be read by unrelated users. The network-online.target ordering helps defer start until the system considers networking available; it does not prove that DNS, the remote ingest service or the route to it is working.

The example uses Restart=always, following the Liquidsoap production guide's minimal pattern. A restart policy means systemd may start the process again after it exits; it does not mean the next attempt will succeed, or that a connection failure will always cause Liquidsoap to exit. Be deliberate about how your Liquidsoap output responds to a lost connection, and watch the logs for repeated failures rather than treating repeated restarts as a repair.

Before enabling the service, check the configuration with the installed version's check command, such as liquidsoap --check /etc/liquidsoap/radio.liq where that option is available. Then verify the executable and configuration paths, permissions and account. Enable and start the unit with systemctl enable --now radio, substituting your unit name. Use systemctl status radio to see whether systemd considers it active, then confirm the feed itself in YouTube Studio; an active process is not proof that YouTube is receiving healthy audio and video.

Check logs and recover from interruptions

Systemd captures a service's standard output in the journal by default. Read the recent entries with journalctl -u radio, or follow new ones while testing with journalctl -u radio -f. Add a time range when investigating an overnight failure. The error message often points to the layer that needs attention: a missing file or permission problem differs from an invalid key, a refused connection or an encoder error.

When the feed stops, inspect both ends. On the host, check service status, the journal, disk space, CPU and memory pressure, network reachability and whether the configured media still exists. In YouTube Studio, check the stream health warnings and preview. If systemd restarted Liquidsoap, identify why it exited; if the process remains active but the feed is unhealthy, look at output and connection handling rather than assuming a restart is needed.

A sensible recovery sequence is to preserve the relevant logs, correct the identified cause, validate the Liquidsoap configuration, then restart the unit deliberately and verify the resulting picture and sound in the control room. Avoid repeatedly restarting without reading the error: that can obscure the first useful message and may leave a process in a restart loop. If you reset the stream key, make sure the running configuration uses the new key before expecting the ingest connection to recover.

Test after changes to the Linux host, Liquidsoap, FFmpeg, audio files, visual assets, network or YouTube output settings. A reboot test is especially useful: it checks whether the service account can see all required files and whether the unit starts without an interactive login. Keep a short operational note with the unit name, configuration location, key-reset procedure and the commands your team uses to check status. Do not put the key itself in that note.

YouTube says streams under 12 hours are automatically archived. Stopping the encoder ends the sending of content; plan any maintenance around that behaviour and check the current YouTube workflow if archiving matters to you. For channel-specific scheduling ideas, the guide to a 24/7 devotional music channel using a cloud service is a useful companion, though a server-based Liquidsoap setup has different operational responsibilities.

Choose one destination or two

If the goal is only a YouTube live channel, configure Liquidsoap's YouTube output and the video component, then test that path directly. Do not add Icecast simply because the word “radio” appears in the project description. Extra services create another configuration and another endpoint to monitor, without changing where a YouTube viewer watches the stream.

Add Icecast when you have a separate reason to serve listeners outside YouTube, such as a station player that connects to your own radio URL. Liquidsoap can publish to Icecast or Shoutcast as a separate output. The Icecast project page describes its use for internet radio, while YouTube ingest is the encoder workflow above. Decide whether you need one destination or both before opening ports and maintaining credentials for another service.

For either path, write down what success looks like: the expected audio, the visual if sending to YouTube, the destination URL or control-room status, and where to find logs. Keep a manual test procedure as well as an unattended service. That gives you a way to distinguish a scheduling issue from an encoding or network issue without assuming that a green systemd status tells the whole story.

Once your source files, channel and destination are ready, choose the operating arrangement that fits how much Linux maintenance you want to handle.

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

Do I need Icecast to stream a radio station to YouTube?

No. YouTube Live receives an encoder feed using its ingest URL and stream key; Icecast serves an audio stream to radio players or directories. Use Icecast only if you also want that separate endpoint.

Can systemd guarantee that the stream stays live?

No. It can start the configured foreground process and apply a restart policy if that process exits. It cannot ensure that a network connection, credentials, media files or YouTube ingest remain healthy, so check both the journal and YouTube's stream health.

Does a headless YouTube radio stream need a particular kind of visual?

The encoder feed should be configured with the video component you intend viewers to see, but YouTube's encoder guidance does not prescribe a particular design. Test the selected visual with the actual audio output and check how it appears in the live preview.

What should I do if the stream key is exposed?

Treat it as compromised and reset it through YouTube Live Control Room, then update the protected configuration used by Liquidsoap. Check that the running service is using the new key and confirm the feed in YouTube Studio.

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 ↗