Skip to content
streamneo.
Setup Guides12 min read

How to Stream a Pre-Recorded 24/7 YouTube Channel with FFmpeg and systemd

Loop a local video into YouTube Live with FFmpeg and systemd, then check reception, restart behaviour and archive limits.

sn.
StreamNeoPublished 5 October 2026
Worth sharing?

A Linux host can loop a local video into a YouTube Live broadcast, while systemd starts FFmpeg at boot and restarts it if the process exits. That gives you process supervision, not proof that YouTube is receiving a healthy broadcast; you must check the encoder logs and Live Control Room separately.

This guide covers a self-hosted RTMP workflow, with notes on HLS, credentials, testing and archive expectations. The example commands are starting points, not universal recipes: first check your installed FFmpeg build and the actual media file you plan to stream.

What this Linux setup does

The arrangement has three parts. A file on your Linux machine supplies the video and, if present, audio. FFmpeg reads that file repeatedly and sends an encoded stream to the ingest destination shown in YouTube Studio. A systemd service runs FFmpeg in the foreground, starts it when the host boots, and can try to start it again after an exit.

“Foreground” matters here. FFmpeg should remain the service’s main process rather than detach into the background. That lets systemd track whether the process is running and collect its standard output and error in the journal. You can then inspect the unit’s current state and its recent messages without keeping a terminal open.

This approach suits an operator who already manages a Linux computer or server and wants control over the media file, command and restart policy. It also leaves you responsible for the host, storage, network connection, credentials, FFmpeg compatibility and checks on the broadcast itself. A service shown as active can still be sending unusable output, repeatedly failing to authenticate, or failing to reach YouTube.

If you are considering a small computer at home, treat the model and workload as a compatibility question rather than assuming that any device can encode any file continuously. Stream copying can avoid video encoding, but only for compatible media; transcoding requires more processing. For a related look at hardware and cloud trade-offs, see whether to use a spare PC or cloud streaming service. If you want a file-transfer workflow for a remote Linux host, this guide to moving large stream videos to a Linux VPS is relevant before deployment.

Create a YouTube Live stream and get ingest settings

In YouTube Studio, create or select a stream in Live Control Room. The stream settings provide the ingest URL and stream key. Use the protocol and destination YouTube gives you for that stream; do not assume a URL copied from an old tutorial is still the right one for your account or selected protocol.

Keep the stream key private. Anyone who obtains it may be able to send a feed to your channel’s ingest point. Do not put a real key in a public unit file, a screenshot, a shared command transcript or a document committed to a public repository. Prefer a protected configuration file readable only by the service account and administrators who need access. If a key is exposed, review the current Studio controls for replacing or resetting it.

For a scheduled stream, YouTube’s encoder workflow is to start sending from the encoder, wait for the incoming preview, and then use Live Control Room to start the event when appropriate. The preview is a useful receiving-side check before you ask viewers to watch. Follow the current instructions in YouTube Help for creating a live stream with an encoder, since Studio labels and available controls can change.

YouTube offers different ingest arrangements. The command below uses RTMP and FLV as an example. If Studio specifies HLS, do not reuse an RTMP/FLV command unchanged: YouTube’s HLS setup documentation describes different ingest requirements, including HTTPS requests, TS segments and a rolling playlist, and notes that HLS has higher latency than RTMP. Use the current protocol-specific guidance rather than trying to make one output command cover both.

Loop a local file with FFmpeg

First inspect the file and the FFmpeg installation on the host. Confirm the path exists, that the service account will be able to read it, and that the installed FFmpeg build includes the needed demuxer, decoders or encoders. Container extension alone does not tell you whether the encoded tracks are suitable for the output format.

A basic RTMP command for a compatible local file has this shape:

ffmpeg -re -stream_loop -1 -i /srv/video/channel.mp4 \\
  -c:v copy -c:a aac -b:a 128k -ar 44100 \\
  -f flv 'rtmp://a.rtmp.youtube.com/live2/REPLACE_WITH_STREAM_KEY'

The placeholder is not a working key. Put -stream_loop -1 before the input’s -i: it tells FFmpeg to repeat that input indefinitely. -re reads a file at its natural playback rate, rather than sending it as quickly as the host can process it. The output options shown are an example for a particular class of source, not a certification that the file will work for your channel.

In this example, -c:v copy asks FFmpeg to pass through the existing video track rather than encode it again. That can reduce processing, but only works when the source video, container handling and destination are compatible. The audio is encoded as AAC with the example settings shown. If your source has no audio track, these audio options do not conjure one; decide whether silence or another audio source is needed, and test that choice against YouTube’s current requirements.

If copy mode fails or the incoming stream is not acceptable, inspect the media properties and use a deliberate transcode configuration. Choose the video codec, pixel format, frame rate, bitrate and keyframe interval to match YouTube’s current encoder guidance and the needs of the source. Transcoding can make incompatible source media usable, but it adds processing work and requires a configuration suited to the host. Consult the FFmpeg documentation for the version installed on your machine; options and supported formats depend on the build.

Test the command in a controlled session before creating a boot-enabled service. Watch for file-read errors, unsupported codecs, missing audio, timestamp warnings and connection or authentication failures. Then confirm the preview in Studio. A command that starts without immediately exiting is not enough to establish that viewers will receive the intended picture and sound.

For a playlist of different clips, validate the playlist and transitions separately before using it in an unattended loop. Files with different codecs, audio layouts or timestamp behaviour may not join cleanly just because they play individually. Test the transition points and continuity locally. If your channel is based on worship material, this FFmpeg loop guide for church worship videos covers a related stream-copy scenario, but check your own files rather than assuming their characteristics match.

Run FFmpeg as a foreground systemd service

Once a manual test works, create a system service that runs the same FFmpeg command as its foreground process. Store the command and credentials in a way that avoids exposing the key in a world-readable file. A dedicated service account with only the file and device access it needs reduces accidental access; the precise user and paths depend on your host.

A unit should identify the executable, arguments, working context if required, restart behaviour, and where configuration is obtained. Keep the FFmpeg command’s output visible to systemd rather than daemonising it. On a typical systemd installation, a unit can send standard output and error to the journal, which makes messages available through journalctl. Exact directives can vary with installed systemd versions, so check the local manual pages and validate the unit before enabling it.

An environment file can keep a key out of the unit text, but it is still a file containing a secret. Restrict its ownership and permissions, and make sure the service can read it while unrelated users cannot. Avoid printing the full key in debugging output. If you place the key directly in a command argument, it may be exposed through administrative process inspection or diagnostic records, so consider the access model on your machine before choosing that method.

After creating or changing a unit, ask systemd to reload its unit definitions and start the service for a controlled test. Inspect systemctl status for the service state and journalctl -u <service> for FFmpeg’s recent messages. Use your actual unit name in place of <service>. Check both for obvious errors, but remember that a quiet journal or running process does not substitute for the YouTube-side preview.

Enable startup and process recovery

When the test is satisfactory, enable the service so systemd starts it at boot. Select a restart policy and delay that fit the host’s failure modes. A restart after process exit can recover from a transient crash, but a very short retry cycle can repeatedly hammer a bad configuration and make diagnosis harder. A delay gives you time to inspect failures and avoids treating every immediate exit as a healthy recovery.

Try a deliberate, safe restart before relying on the setup overnight. Confirm that FFmpeg exits, systemd attempts the configured restart, and the new process reaches the expected ingest state. Then check the journal and Studio preview again. A machine reboot test can also reveal missing mounts, a file path unavailable at boot, or credentials that were accessible in your login session but not to the service account.

Do not mistake a restart policy for a repair mechanism. It cannot correct a missing file, unsupported media, revoked key, repeated authentication failure, full disk, broken network or a YouTube event that is no longer accepting the feed. If FFmpeg starts and then fails for one of those reasons, systemd may simply repeat the same failure. Fix the cause, then verify both the local process and the receiving broadcast.

For an unattended channel, decide how you will notice a problem while away from the host. The system journal is useful for local diagnosis, but it does not alert you if the machine loses power or the internet connection disappears. A separate external check or alert can add visibility, and should test viewer-facing playback or the incoming broadcast rather than only asking whether the process exists. The overnight stream log checklist is about OBS, but its diagnostic habit—checking evidence after a failure rather than assuming a green process state—is useful here too.

Validate broadcast health in Live Control Room

There are two separate checks to make. On Linux, use systemctl status and the journal to see whether systemd is managing FFmpeg and what the encoder reports. In YouTube Studio, use Live Control Room to confirm that YouTube receives the feed, displays the expected preview and shows the correct event state. The second check is essential because a live process can still send invalid or unwanted media.

Before opening the stream to viewers, look at the picture and listen to the audio in the preview. Check that the file starts where expected, that looping returns to the beginning cleanly, and that there is no unintended black screen or silence. Confirm that Studio has accepted the feed and that the event is in the intended state—scheduled, waiting, live or otherwise as appropriate to your workflow. A scheduled encoder feed may need an explicit Go live action in Studio.

If the preview does not appear, work through the layers instead of repeatedly restarting without evidence. Confirm the stream key and ingest URL against Studio, inspect the FFmpeg log for connection or encoding errors, check network access, and verify the file permissions and media compatibility. If the preview appears but the audience-facing watch page does not behave as expected, check the event state and visibility settings in Studio. Do not infer public availability from a local service state.

YouTube’s interface and diagnostics are the receiving-side authority for this workflow. Recheck them after a key change, host reboot, unit change or encoder restart. For an important channel, include a person or external monitor who can check the actual watch experience; process supervision alone cannot tell you whether a viewer hears the right audio or sees the intended programme.

Understand archive limits and operational checks

A continuous loop and a continuous YouTube event are not the same thing. FFmpeg can be configured to keep reading a local file, but the platform’s event state, the network path and the receiving service determine what is actually broadcast. Plan for event boundaries and possible reconnects instead of treating “24/7” as a guarantee of one uninterrupted session.

YouTube says streams under 12 hours are automatically archived. A nominal 24/7 event runs beyond that threshold, so do not plan on receiving one complete archive of the entire continuous broadcast. Decide whether you need separate event sessions, local source recordings, or another recording plan, and check the current YouTube encoder guidance before relying on an archive. Even where sessions are deliberately bounded, confirm what was actually retained in Studio.

A local recording plan can preserve a copy of your programme source, but it is not automatically a recording of exactly what viewers received. If that distinction matters, consider how you will verify the live output and preserve the relevant material. Keep sufficient storage for whatever recording approach you choose, and monitor it: an exhausted disk can affect both a recording and the service’s ability to operate.

Use a short operational checklist at handover and after changes: Is the host reachable? Is the media file present and readable by the service account? Is the systemd unit active without a loop of errors? Does the journal show a sensible connection? Does Studio show the correct preview and event state? Is the stream key still private? Is there a plan for a restart, a lost connection and an archive that ends before the full programme?

For a channel that needs actual sessions and retained replays, define event boundaries intentionally and document who starts and checks each one. That creates more operator work than leaving one event open indefinitely, but makes the archive requirement easier to reason about. If you need a channel loop without managing a Linux host, compare the operating burden honestly with a managed approach; your choice should account for control, recurring cost, host and network responsibility, and the checks you are prepared to perform.

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

How do I loop a video forever in FFmpeg?

Use -stream_loop -1 before the input’s -i option, then send the input at its natural playback rate with -re when appropriate. Check the source tracks and output compatibility first; a looping option does not make an unsupported file valid for YouTube ingest.

Can you stream a pre-recorded video as live on YouTube?

You can send a prerecorded file through an encoder to a YouTube Live event, subject to YouTube’s current account and stream requirements. Create or select the event in Studio, use its current ingest settings, and verify the incoming preview and live state in Live Control Room.

Does systemd guarantee that the YouTube stream stays live?

No. systemd can start and supervise the FFmpeg process and attempt recovery after an exit, but it cannot prove that YouTube is receiving valid video or that an event remains live. Check the journal and Studio independently, and arrange a separate alert or viewer-facing check if the channel must be monitored unattended.

Will a 24/7 stream become one complete YouTube archive?

Do not assume so. YouTube’s automatic archive guidance applies to streams under 12 hours, while a continuous 24/7 event exceeds that limit. Plan event boundaries or a separate recording approach, and check the current official guidance and the retained result in 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 ↗