Skip to content
streamneo.
Setup Guides12 min read

How to Run a Pre-Recorded YouTube Stream from a Raspberry Pi

Use FFmpeg on a Raspberry Pi to send a local video to YouTube Live, repeat it, protect your stream key and check the feed overnight.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

A Raspberry Pi can act as the encoder for a pre-recorded YouTube stream. FFmpeg reads a video stored on the Pi at real-time speed, encodes it when needed, and sends the feed to YouTube's ingest service.

For a looped devotional video, study visual, local information screen or ambience recording, the practical challenge is not starting FFmpeg once. It is choosing settings the Pi can sustain, keeping the upload connection stable, and treating the YouTube stream key as private configuration.

How the Raspberry Pi streaming path works

The complete path has four parts: a media file, FFmpeg running on the Raspberry Pi, an upload connection, and a YouTube Live broadcast. The Pi does not upload the file as a normal video. It opens the file, produces the video and audio in sequence, and sends that sequence to YouTube as an ongoing live feed.

The -re option is important when the input is a file. Without pacing, a media tool may read the file as quickly as the Pi and storage allow. That is useful for conversion, but it is not how a live broadcast behaves. With -re, FFmpeg reads the file at its native playback rate, so a ten-minute file takes roughly ten minutes to play rather than being sent in a short burst. FFmpeg documents -re as an option for simulating a live input from a file, where output pacing matters. See the FFmpeg documentation when adapting the command to a different input.

If you want the same file to continue after it ends, -stream_loop -1 tells FFmpeg to repeat the input indefinitely. This is an input option and belongs before -i. The loop is local to FFmpeg: YouTube receives one continuing encoder feed, not a series of separate uploaded videos.

YouTube supplies the destination details in Live Control Room. The server address, or ingest URL, tells FFmpeg where to send the feed. The stream key identifies the broadcast configuration. Use the current values shown for your stream rather than relying on an old example copied from a forum post. YouTube recommends RTMPS, the encrypted form of RTMP, for ingest. Its official encoder guidance explains the current workflow and supported settings.

The Pi therefore has two jobs. It must decode the local file and, if necessary, encode it into a format YouTube can accept. It must also transmit the resulting stream continuously. A command can be syntactically correct and still fail in practice if the Pi cannot encode in real time or the connection cannot sustain the selected bitrate.

Check the media and Pi setup

Start with a Pi that is suitable for the work you actually want it to do, but do not assume that a particular model will handle every file. The research available for this setup does not establish a model-specific performance threshold. Resolution, frame rate, codec, audio, filters, storage speed, cooling and other processes all affect the result.

Install FFmpeg using the package source appropriate to the Raspberry Pi OS release on the device. Package names and available versions can change, so check the documentation for the operating system you are running rather than copying an installation command intended for another release. Raspberry Pi's official documentation is the right place to confirm the operating-system details.

Put the media on local storage and use a stable path. A simple path such as /home/pi/media/channel-loop.mp4 is easier to use in a service or startup script than a removable drive that may be mounted under a different name after a restart. Avoid editing the original file while FFmpeg is reading it.

If you do not know the file's streams and codecs, inspect it with ffprobe. You want to know whether it contains video, audio, or both, as well as the video dimensions, frame rate and codec. A file with no audio needs a separate decision: you can test whether the current YouTube configuration accepts it, or prepare an audio track you have permission to use. The optional audio mapping in the example below only stops FFmpeg failing when no audio stream exists. It does not prove that YouTube will accept a silent feed in every configuration.

A first check might look like this:

ffprobe "/home/pi/media/channel-loop.mp4"

Look for warnings before you begin the live test. A damaged file, a path with a typing error, or a file that depends on unavailable external media will create a problem before network settings matter.

Keep the Pi on reliable power, place it where it can remain cool, and use a wired network connection if that is practical. Wi-Fi can work, but a signal that is adequate for browsing may still be inconvenient for an uninterrupted upload. Close unnecessary applications and watch CPU use during a test. There is no honest universal Pi setting that removes the need to measure your own device with your own media.

Get the YouTube ingest details

If live streaming is not enabled on the channel, complete that step first. YouTube says first-time enablement may take up to 24 hours, so do not leave it until the intended broadcast is about to start.

Open YouTube Live Control Room and create or select the live stream. Copy the current stream URL and stream key into a private place on the Pi. In the command later in this article, <current-ingest-host>, <stream-path> and <STREAM_KEY> are placeholders, not values to publish or reuse literally.

Prefer the RTMPS address displayed by YouTube for the selected stream. Do not assume that an ingest address found in an old tutorial is still the correct one for your account or current configuration. The YouTube encoder setup page covers the relationship between the server URL, stream key, preview and Go live action.

For a scheduled stream, YouTube may show an incoming preview before the audience-facing broadcast has begun. Starting FFmpeg is not necessarily the same as clicking Go live. Follow the sequence displayed in Live Control Room: start the encoder, wait for the preview, check the stream health, and use the relevant control to begin the scheduled broadcast.

Before committing to a long run, make a private or otherwise suitable test using the same media, bitrate and network path. Test movement as well as a static image, and test audio if the final channel will contain audio. A mostly static devotional image may place a different load on the encoder from a detailed video with frequent motion.

Configure FFmpeg to read and repeat the media

The following is a practical starting command. It has not been tested against every Raspberry Pi, Raspberry Pi OS release, media file or connection, so treat it as a template rather than a guaranteed fit:

ffmpeg -re -stream_loop -1 -i "/path/to/video.mp4" \
  -map 0:v:0 -map 0:a:0? \
  -c:v libx264 -preset veryfast -pix_fmt yuv420p \
  -c:a aac -b:a 128k -ar 44100 \
  -b:v 2500k -maxrate 2500k -bufsize 5000k \
  -r 30 -g 60 -f flv \
  "rtmps://<current-ingest-host>/<stream-path>/<STREAM_KEY>"

Replace the file path and the three YouTube placeholders. Never replace them with a stream key in an article, screenshot, public repository or support post. Keep the command in a private file with appropriate permissions if you need to run it repeatedly.

The order of the options matters. -re and -stream_loop -1 apply to the input, so they appear before -i. The mapping and codec settings describe the output and appear after the input. -map 0:v:0 selects the first video stream. -map 0:a:0? selects the first audio stream when one exists; the question mark makes that selection optional.

The sample converts video to H.264 and audio to AAC, then places the result in an FLV output for the YouTube ingest connection. The sample uses a 30-frame-per-second output and a 60-frame GOP. In that combination, the GOP represents a two-second keyframe interval. YouTube's current encoder guidance recommends a two-second interval and says not to exceed four seconds. It also describes H.264, H.265 and AV1 video options, AAC or MP3 audio, and constant bitrate guidance. Check the current official page when choosing settings for a new broadcast.

The sample bitrate values are illustrative starting settings, not a promise about what your Pi or upload connection can sustain. If CPU use remains high, frames are dropped or the feed falls behind, lower the resolution, frame rate or encoding demand. If the upload connection cannot sustain the outgoing bitrate, reduce the bitrate or choose a more suitable quality level. The bitrate guide for long-run streams can help you compare the trade-off between picture quality and sustained upload demand.

Copy the stream or transcode it

Transcoding gives you more control. FFmpeg decodes the source, creates H.264 and AAC output, applies the requested frame rate and bitrate, and sends that output to YouTube. The cost is CPU work and heat on the Pi.

Stream copy can reduce CPU use because FFmpeg passes compatible streams through instead of encoding them again. It is only a sensible shortcut after you have checked the file's codecs, pixel format, frame rate, keyframe spacing, audio and container compatibility against YouTube's current ingest guidance. A file that plays correctly in a desktop media player is not automatically a suitable live ingest source.

In a copy-mode test, you might investigate options such as -c:v copy and -c:a copy, but do not add them simply because the Pi is busy. If the source has an unsuitable codec, irregular timing, no usable audio, or keyframes that do not suit the live feed, copying can move the incompatibility further down the path rather than solving it.

For a first test, the explicit transcode command is easier to reason about. Measure the Pi while it runs. If it sustains the output without CPU saturation and the YouTube preview remains healthy, you have evidence for that particular file and setting. You do not yet have evidence that every file in the channel's future library will behave the same way.

Start and verify the live feed

Run the command from a terminal and watch both the FFmpeg output and Live Control Room. FFmpeg should continue reading the file at its normal rate rather than racing through it. YouTube should show an incoming preview and stream-health information.

For a scheduled stream, start the encoder first and wait for YouTube to receive it. Then complete the Go live step shown in Live Control Room. Check the audience-facing playback as well as the preview. A preview can look acceptable while the public player, audio selection or timing still needs attention.

During the test, watch for messages about dropped frames, connection interruptions, unavailable audio and encoding speed. On the Pi, check whether the CPU is staying near saturation, whether the device is becoming hot, and whether the process is still progressing through the file. On the network, check whether the upload remains steady rather than briefly reaching the required rate and then falling away.

Test the point where the file loops. A file can play correctly from its first frame and still produce an awkward transition at the end. Listen for a click, silence gap or sudden change in volume, and look for a visible jump. If the loop is for meditation or ambience, the guide to avoiding silence gaps in a looping stream covers a related problem. If you need different files rather than one repeated file, see how to schedule different videos in an FFmpeg stream.

To end the broadcast, stop sending content and use the relevant end-stream control in Live Control Room. YouTube says streams under 12 hours are automatically archived. Do not assume the same archival result for a longer broadcast without checking the current YouTube guidance.

Protect the stream key

Treat the stream key like a password for the encoder connection. It belongs in private configuration, not in the article you publish, a public Git repository, a screenshot, a terminal recording or a shared chat message. The URL may be less sensitive than the key, but keep the complete destination private while troubleshooting.

Do not place the key directly in a script that will be uploaded with other project files. If you keep a local script, restrict access to it and avoid printing the command into logs that are copied elsewhere. Be careful with shell history as well: a command containing the full RTMPS destination may remain in the Pi user's history after the stream stops.

If the key is exposed, use YouTube's controls to reset or replace it and update the private command on the Pi. A key shown in a tutorial should always be a placeholder. This article deliberately uses <STREAM_KEY> and does not expose a real value.

The same rule applies when asking for help. Share the FFmpeg version, non-sensitive error text, media properties and general network symptoms, but redact the stream key and any complete private destination. If a support person needs to see the command structure, replace the secret with a label before sending it.

Make the setup survivable overnight

A terminal command that works during a ten-minute test is not yet an unattended channel. Decide what should happen after a power cut, a network interruption, a Pi restart or an FFmpeg error. A process supervisor or service can start FFmpeg again, but an automatic restart cannot repair a bad file, an invalid key or an upload connection that is consistently too slow.

First, prove the basic command manually. Then consider running it through the startup and supervision method appropriate to your Raspberry Pi OS setup. Keep the media path stable, make sure the device reconnects to the network, and record the non-secret settings so you can reproduce the test.

Keep an eye on the first long run. Check the YouTube stream health, public playback, audio continuity and the Pi's CPU and temperature behaviour. A small local display or a separate device can help you confirm that the broadcast is still visible, but it should not replace checking Live Control Room messages.

If the Pi is kept in a home or office, remember that its local power and internet connection are part of the broadcast path. When the channel needs a machine that can be left on elsewhere, or when repeated local interruptions are the main problem, StreamNeo removes the need to keep this encoder computer running: you upload the video, provide the YouTube stream key privately, and the channel can continue from the cloud with monitoring and automatic restarts.

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 a Raspberry Pi stream a video file without FFmpeg?

It can use other software, but this setup uses FFmpeg because it can read a local file at real-time speed, repeat it and send an encoded feed to YouTube. The important requirement is not the brand of tool but that the output behaves like a live stream and meets YouTube's current ingest requirements.

Does -stream_loop -1 make the YouTube broadcast endless?

It asks FFmpeg to repeat the selected input indefinitely. The broadcast can still stop because of a Pi restart, a network interruption, an FFmpeg error, a YouTube action or a problem with the media file, so test supervision and recovery separately.

Can I use the example command on any Raspberry Pi?

No. The command is a starting point, not a guaranteed fit for every Pi, media file or network. Test the actual file, monitor CPU use and dropped frames, and lower the output demands if the device cannot encode and upload in real time.

Is it safe to put the stream key in a public script?

No. Keep it private and redact it from screenshots, logs, shell history and repositories. If it is exposed, replace or reset it through YouTube's controls and update the private encoder configuration.

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 ↗