To stream a podcast archive to YouTube Live from a Linux VPS, run FFmpeg on the VPS to read your video file or episode playlist and send it to YouTube’s ingest endpoint. Use systemd to start and supervise FFmpeg, then check YouTube’s stream and broadcast state separately; a restarted process does not prove viewers can see the intended live event.
This guide follows the default channel-stream workflow and explains where a scheduled event differs. You will need a channel enabled for live streaming, an archive with a suitable visual track, a Linux account for the service, and a way to inspect both service logs and YouTube Studio. Test the entire path before leaving it unattended.
Understand the broadcast and stream roles
YouTube Live uses two related objects that serve different purposes. A liveBroadcast is the viewer-facing event or video. A liveStream represents the incoming media transmission. YouTube binds a broadcast to one stream, while a stream can be reused for recurring broadcasts. Treating these as the same object makes recovery and scheduling harder to reason about.
For a continuous channel, you may use the channel’s default stream workflow in YouTube Studio. You start the feed there and point FFmpeg at the current ingest address and stream key. For an API-scheduled event, you create or select a broadcast with its own event settings and associate it with a stream. A scheduled broadcast has an event lifecycle; restarting FFmpeg alone does not necessarily start, reopen, or correctly associate that event.
The YouTube LiveStreams resource documentation describes the stream object and its ingestion details, including the ingest address and stream name. The LiveBroadcasts resource documentation describes the event side. Read the current channel and API instructions before setting this up, because permissions and available settings can differ.
First decide what viewers should experience. A single long recording played once is a live event that ends when the input ends. Repeating one recording indefinitely is a continuous loop, but it may not make a useful archive or viewer experience. A sequence of episodes needs deliberate ordering, transition behaviour, and a plan for what happens when the list ends. For a deeper look at episode sequencing, see how to build an automatic FFmpeg playlist.
| Intended programming | Source behaviour | Broadcast planning |
|---|---|---|
| One episode or long recording | Play once, then end | Plan to stop the event and check its replay |
| One ambience or podcast recording as a continuous channel | Repeat the same input | Decide whether a loop is appropriate and test the end-to-start transition |
| Several episodes | Read a defined sequence | Decide episode order, gaps, metadata and what happens at the final item |
Prepare the Linux VPS and archive
Use a VPS that can read the archive continuously and sustain the required network connection to YouTube. The file should be stored somewhere stable and readable by the dedicated service account, rather than in a user’s temporary directory or a removable mount. Check available disk space, network egress rules, and the VPS provider’s traffic policy. If you are using Hetzner, review the practical considerations in the guide to cloud traffic limits for continuous YouTube streaming.
Install FFmpeg from a trusted package source for your Linux distribution, and note the installed version. Commands and supported options can differ between builds. Check the actual media streams before choosing an output command:
ffprobe -hide_banner /srv/podcast/episode.mp4
Review whether the file has both video and audio, its codecs, dimensions, frame rate, and audio format. Podcast audio alone is not a complete video live stream: choose a visual track, such as an episode cover slate or a simple waveform video, and combine it with the audio before sending it to YouTube. A still image can be enough for a basic test, but confirm the output really contains video and audio rather than assuming the source file or command supplies both.
If the archive is already in a format that YouTube accepts for the chosen ingest profile, stream-copy may avoid the CPU cost of re-encoding. If it does not fit, transcode to a suitable profile. That can increase CPU use and create new failure modes if the VPS is undersized or the chosen settings do not match YouTube’s current guidance. Do not treat one codec or bitrate as universally correct: consult YouTube’s current live encoder settings guidance and test the exact file and settings.
For a multi-episode archive, prepare an explicit playlist rather than relying on a shell wildcard or directory order. An FFmpeg concat list, a playlist-aware process, or a separate orchestration tool can provide a known sequence, but each approach has different requirements for matching codecs and handling transitions. Decide whether episodes should run back to back, include a gap, or end the broadcast. The separate video and audio VPS playlist guide covers another archive arrangement.
Before publishing, confirm you have permission to stream the episodes, music, clips, and artwork. A podcast feed being publicly available does not by itself establish permission to rebroadcast every element in it. YouTube’s policies and copyright processes can change, so review the current official guidance for your channel and material.
Configure FFmpeg for YouTube ingest
Get the current RTMPS ingest endpoint and stream key from YouTube Studio or, if you are managing events through the API, from the stream’s ingestion information. RTMPS is RTMP carried over SSL; Google’s RTMPS ingest documentation specifies the protocol and connection requirements, including port 443. Use the exact address and path supplied for your stream rather than guessing an endpoint.
The basic shape of an FFmpeg command is an input, any required video and audio mapping or encoding options, and an RTMPS output URL containing the stream key. A file-to-RTMP output must be paced in real time: otherwise, FFmpeg may try to send the file faster than its playback duration. FFmpeg documents real-time input handling and RTMP output in its official protocol documentation. The following is a template, not a drop-in profile:
ffmpeg -re -i /srv/podcast/episode.mp4 \
-c:v libx264 -c:a aac \
-f flv "rtmps://INGEST_HOST/INGEST_PATH/STREAM_KEY"
Replace the example endpoint with the current address from YouTube, and do not paste a real key into a public post, shared screenshot, or repository. The encoding choices here illustrate a transcode path; check your input, FFmpeg build, and YouTube’s current requirements before using them. If the source codecs and container are appropriate, a stream-copy path can reduce CPU use, but it cannot fix an incompatible source format. Monitor resource use during a test and inspect YouTube’s reported stream health.
For a single recording repeated continuously, FFmpeg’s input loop options can be useful. Test the exact behaviour at end-of-file and at the loop boundary before relying on it. A loop of one file is not a playlist manager: it does not decide episode order, insert programme information, or define what should happen if a file disappears. A sequential archive needs a sequence mechanism and an operational plan for a failed or completed item.
A one-time episode also needs an explicit end-of-broadcast plan. When FFmpeg reaches the end, the process may exit and systemd may restart it if configured to do so. That is not automatically the desired outcome: it could replay the episode, reconnect to an event that has ended, or produce a feed that no longer matches your intended schedule. Choose restart behaviour in light of the content and YouTube event lifecycle, not merely because restarting a process is possible.
Store credentials safely
The stream key is a credential. Anyone who can use it may be able to send media to the associated ingest stream, so limit access to it and rotate it if it is exposed. Do not put it directly in a unit file that is broadly readable, a script committed to source control, or a command copied into a shared shell history.
A practical pattern is to keep a root-owned environment file or another protected secret file with restrictive permissions, and have the service load it. Put the endpoint and key in separate variables if that makes updates clearer. Confirm the service account can read the necessary file but ordinary users cannot. Avoid printing the secret in logs, diagnostics, or status messages.
The exact syntax and file-permission approach depend on the distribution and systemd version. Validate the unit with the tools on the target VPS and consult the systemd.exec manual for environment and execution behaviour. Remember that environment variables can be exposed to privileged diagnostics or processes with sufficient access; a protected file is risk reduction, not a reason to share credentials carelessly.
Use a dedicated unprivileged Linux account for the encoder. Give it read permission on the archive and any playlist, and only the access it needs to write logs or temporary files. Keep administrative changes separate from routine operation. If the archive is replaced, check ownership and permissions again before restarting the service.
Create a systemd service
A system service gives systemd a foreground process to start, stop, and observe. Keep FFmpeg in the foreground; do not background it from ExecStart or wrap it in a shell that hides the actual exit status. The service definition below is a starting example. Adapt paths, account names, variables, and directives to your distribution and installed systemd version.
[Unit]
Description=Podcast archive to YouTube Live
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=podcast-stream
Group=podcast-stream
EnvironmentFile=/etc/podcast-stream/ingest.env
ExecStart=/usr/bin/ffmpeg -re -i /srv/podcast/episode.mp4 -c:v libx264 -c:a aac -f flv ${INGEST_URL}
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
The delay shown is an example choice, not a YouTube requirement or a guarantee that a reconnect will be accepted. Review how your systemd version expands environment variables in ExecStart; if the URL contains special characters or your preferred secret handling is more involved, use a carefully permissioned wrapper or credential mechanism and validate the resulting process arguments. Unit parsing and service behaviour should be checked on the actual host, not inferred from this example.
Restart=on-failure tells systemd to try starting a process again after certain failures. It does not assess whether YouTube has returned to a live state, whether the input is still readable, whether the stream key is valid, or whether the VPS has enough CPU and network capacity. This is process supervision, not end-to-end recovery. A separate monitoring procedure must check the service and the YouTube event.
After saving a unit, reload systemd’s unit definitions, enable the service if it should start at boot, and inspect its status before relying on it. Keep a record of the exact file and command that passed testing. For a loop or playlist, make sure the unit launches the intended sequence and that a failure does not accidentally restart a one-time episode from the beginning without your knowledge.
Start and supervise the stream
Start with a private or unlisted test event where available, so you can inspect the feed before directing viewers to it. Start the broadcast in YouTube Studio or create and bind the scheduled broadcast through your chosen API workflow. Then start the service and inspect systemd’s status and recent journal entries. Use the journal to answer operational questions: did FFmpeg start, did it open the input, did it connect to the expected output, and did it exit or report an error?
A service that is active only tells you that systemd considers the process running. It does not show that audio is audible, the visual track is present, the ingest is healthy, or viewers are receiving the intended broadcast. Check YouTube Studio’s incoming preview and stream health, and watch the event from a separate viewer session. YouTube reports health issues such as missing audio or configuration mismatches; use those diagnostics alongside FFmpeg logs rather than treating either view as complete.
During a maintenance test, deliberately stop the service or interrupt the network in a controlled way, then observe what happens. Does systemd restart FFmpeg? Does FFmpeg reconnect? Does YouTube show the expected stream again? Is the same broadcast still live, or does the event need an operator action? The answer depends on the broadcast model, the nature of the interruption, and YouTube’s current state. Record what you observe and make the operational response explicit.
If FFmpeg repeatedly exits, look for the first useful error in the journal rather than increasing restart frequency blindly. A missing file, invalid key, incompatible media, unavailable network route, or insufficient CPU can all cause a different problem. The FFmpeg reconnect-log troubleshooting guide can help you distinguish process output from symptoms on the viewer-facing stream.
Systemd can relaunch a process after it exits, but it cannot promise uninterrupted streaming. A restart policy does not guarantee that the YouTube broadcast recovered, that the media is correct, or that the VPS and network stayed available. Assign someone to check the stream and event state after an alert or restart, particularly before leaving a new setup unattended overnight.
Verify stream health and replay
Check ingest and replay as two separate outcomes. While live, confirm that YouTube Studio sees the incoming stream and reports acceptable health, then check the picture and sound from a viewer’s perspective. A green or healthy ingest indication does not prove that the archive is the right episode or that its slate and audio are usable. Make a short test recording and listen to it, including a transition if your programme loops or moves between episodes.
When the programme is meant to end, stop FFmpeg cleanly and finish or end the broadcast through the appropriate YouTube workflow. Allow YouTube to process the completed broadcast into a video. The replay may not appear immediately, so check the channel’s video list and the event’s recording or archive settings after processing has had time to complete. The LiveBroadcasts documentation describes relevant recording and DVR settings; check the current choices for your channel rather than assuming every event has the same behaviour.
Open the resulting replay as a viewer and verify that it begins and ends where expected, includes the intended audio and visual track, and is available under the privacy setting you intended. If you ran a continuous loop, inspect a loop boundary in the recording. If you ran several episodes, check that the sequence and transitions match the playlist plan. A successful ingest and a completed replay are distinct checkpoints, and both belong in your runbook.
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 live stream uninterrupted?
No. It can manage the FFmpeg process and restart it under a chosen policy, but it cannot ensure YouTube has resumed the intended broadcast or that the VPS, network, source media, and ingest are all working. Check both the service journal and the YouTube stream and broadcast state after a restart.
Should I use a scheduled broadcast or the default channel stream?
Use the workflow that matches the programme. A default channel stream can suit a continuously running feed, while an API-scheduled broadcast represents a distinct event with its own lifecycle and settings. In either case, understand how the incoming stream is bound to the viewer-facing event before automating recovery.
Can I use one FFmpeg loop for a whole podcast archive?
A loop option can repeat an input, but repeating one file is different from sequencing multiple episodes. For an archive, define the episode order and how transitions and end-of-list behaviour should work, then test that sequence through to the viewer-facing replay.
Why is the replay not visible as soon as the stream ends?
YouTube processes a completed live broadcast into a video, and the replay may take time to become available. Check the event’s recording settings, then look for the processed video in the channel and test it as a viewer after processing completes.