Skip to content
streamneo.
Setup Guides12 min read

How to Stream Local Media from Linode to YouTube with FFmpeg Concat

Use FFmpeg’s concat demuxer on Linode to stream authorised local files to YouTube Live, with checks for manifests, compatibility and ingest settings.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

FFmpeg’s concat demuxer can send a sequence of local media files from a Linode instance to YouTube Live. It reads a text manifest of file paths; it does not accept a YouTube playlist URL or fetch videos from YouTube.

This guide assumes you already have the media files on the instance and permission to rebroadcast them. You will prepare compatible inputs, validate the manifest, check FFmpeg’s output support, then use the current ingest URL and stream key shown in YouTube Live Control Room.

Understand what concat can accept

The concat demuxer treats a text file as an ordered list of media files and presents their packets as a sequence. The FFmpeg formats documentation describes it as reading a list of files and directives from a text file, then demuxing them one after another. In practical terms, you write the order yourself in a manifest such as playlist.ffconcat.

That manifest is not a playlist page from YouTube. Pasting a URL such as a YouTube playlist address into a file line will not make FFmpeg resolve the playlist into its constituent videos. This workflow neither downloads YouTube videos nor bypasses access or copyright restrictions. If what you have is a YouTube playlist URL rather than files you are authorised to use, stop here: concat is not the tool that turns it into local media.

The distinction matters because a working chain has separate parts: files that exist on the Linode instance, a manifest FFmpeg can parse, streams compatible with the concat demuxer, an encoder or stream-copy path, and YouTube’s active ingest details. A failure at any one stage can look like a generic live-stream failure, so test each part in order.

A cloud instance changes where the process runs, not what concat accepts. You manage the files, operating system, FFmpeg build and process on the VM. If you want a broader comparison of local and hosted approaches, see how a playlist-based 24/7 stream differs between OBS and a cloud service.

Prepare authorised local media files

Put the files you control in a stable location on the instance, for example /srv/media. Avoid paths inside a temporary directory or a mounted location that may disappear after a restart. Give the files names that make their order obvious, such as morning-01.mp4, morning-02.mp4 and morning-03.mp4, rather than relying on shell sorting to create the intended sequence.

The source may be a recording you made, commissioned content, or material for which you have the required rebroadcast permission. Owning a copy does not necessarily mean you have permission to broadcast it. Check the rights and the current YouTube rules that apply to your material and account; a correct FFmpeg command does not settle those questions.

Copying files to the server is a separate task from streaming them. You might transfer them over a secure administrative connection or use another method appropriate to your setup. Once copied, check that the files are complete and readable before building a long-running job. A file that is still transferring, truncated or unreadable can break the sequence after the feed has started.

Keep the working directory and permissions predictable. The account that runs FFmpeg needs to read every listed file, but it generally does not need permission to alter your source media. If you replace a file while a stream is running, first consider whether the process has already opened it; safer practice is to stage a revised playlist separately and validate it before switching over.

If you are building an always-on devotional, ambience or spoken-word channel, plan the editorial sequence as well as the file sequence. A recurring order can be perfectly valid technically and still be confusing to viewers if titles, visuals or transitions do not match. These considerations also apply to a continuous Marathi bhajan stream, though the mechanics here are specific to a local FFmpeg manifest.

Create a concat-demuxer manifest

Create a plain UTF-8 text file with one file directive for each input, in playback order. The optional header ffconcat version 1.0 identifies the script format and must be the first line, with no leading blank line. For example:

ffconcat version 1.0
file '/srv/media/morning-01.mp4'
file '/srv/media/morning-02.mp4'
file '/srv/media/morning-03.mp4'

Save this as /srv/media/playlist.ffconcat. The quoted paths above are illustrative; use paths that exist on your instance. The manifest is a text file, not a shell script, so shell variables and shell quoting rules do not automatically apply. Follow FFmpeg’s manifest escaping rules if a filename contains quotes, backslashes or other special characters. The simplest way to reduce avoidable errors is to use plain filenames without spaces or unusual punctuation.

The order of the file lines is the order FFmpeg attempts to read. It is worth opening the manifest and checking it line by line before running the encoder, particularly after adding or removing items. If the stream needs to repeat the sequence, a looping strategy is required in addition to a valid manifest; do not assume a list of files repeats forever simply because the destination is a live stream.

Use a distinct filename for a revised manifest rather than editing a file under an active process without understanding when FFmpeg reads it. For a planned update, prepare and test a new manifest, then make a controlled restart or cutover. This helps distinguish an ordering problem from a connection problem.

Check file paths and media compatibility

First verify that each path resolves from the manifest and that FFmpeg can inspect each input. A typo, case mismatch or unreadable file is enough to prevent the sequence from starting. Linux paths are case-sensitive, so Bhajan.mp4 and bhajan.mp4 are not interchangeable. Check file access using the same account that will run the service, not only an administrator account.

Next inspect the streams in every file. The concat demuxer expects the inputs to have matching stream structures, codecs and time bases. Two files both ending in .mp4 can still differ in video codec, resolution, frame rate, audio layout or timestamps. A matching filename extension is not evidence that the files are compatible.

A media inspection utility such as ffprobe can show the stream layout and duration. Compare the output for each input: note whether video and audio are present, their codec names, dimensions, sample rate and channel layout. If one item lacks audio and another has it, or their stream layouts otherwise differ, the concat demuxer may not join them cleanly. A filter-based concat workflow that decodes and re-encodes the sources may be more appropriate, but that is a different pipeline and requires testing.

Duration information matters because concat uses it to place the next file in the sequence. Incorrect or missing durations can lead to timestamp problems, jumps or gaps. Do not add guessed duration directives to conceal a problem; establish the actual media duration and test transitions, especially around files with variable frame timing or unusual timestamps.

There are two broad ways to get compatible output. Stream copy avoids decoding and re-encoding, which can reduce CPU work, but only works when the inputs and output requirements line up. Transcoding can standardise media to a chosen output profile, but uses CPU and must be sized and tested for the instance. A small Linode may be adequate for one workload and inadequate for another; no single instance size follows from the word “concat”.

Before relying on a long-running schedule, test a short run that crosses at least one file boundary. Listen and watch the preview for missing audio, black frames, a sudden resolution change or a timestamp jump. This is more informative than checking that FFmpeg printed a successful connection message at startup.

Confirm FFmpeg protocol support

FFmpeg is often installed from a distribution package or compiled with a particular feature set. The executable on your Linode must support the input demuxer and the output protocol you intend to use, and it needs the selected encoder if you plan to transcode. Check the installed build’s configuration and available formats, codecs and protocols rather than assuming every package includes every option.

For YouTube Live, the destination is commonly an RTMP or RTMPS ingest address with a stream key. RTMPS is RTMP carried over TLS, so it encrypts the connection between the encoder and ingest service. YouTube recommends using the RTMPS endpoint when it is available to you. Check FFmpeg’s protocol documentation and the build’s reported support; a command using an rtmps:// target cannot succeed if the installed binary lacks the necessary protocol support.

A cloud firewall or host firewall can also affect the connection. Allow outbound traffic needed for the endpoint and port YouTube currently supplies, while keeping rules limited to what your setup requires. Do not copy a port number from an old tutorial as if it applies to every ingest endpoint. If a connection fails, check the URL, scheme, endpoint details, network rules and FFmpeg support together.

Schedule YouTube Live and retrieve ingest details

In YouTube Studio, open Live Control Room and create or select the live stream you intend to use. Copy the server URL and stream key displayed for that stream. YouTube’s encoder setup guidance explains where the encoder connects; its RTMPS instructions cover the secure endpoint. Use the current details in your own account, not a URL copied from a tutorial or another channel.

Treat the stream key like a password. Anyone who obtains it may be able to send a feed to your event. Do not publish it in a blog post, paste it into a public support request, commit it to source control or leave it in a shared screenshot. Avoid commands that expose the key in shell history or process listings; use a protected configuration approach suitable for your account and operating system, and restrict access to it.

Check the event’s visibility, title, schedule and stream settings before sending the feed. If live streaming is not already enabled on the channel, account activation can take time; YouTube says first-time activation may take up to 24 hours. Confirm the current eligibility and access status in YouTube Studio rather than planning a broadcast around an assumption.

Choose encoding settings based on YouTube’s current recommendations and the material you actually have. YouTube’s live encoder settings describe supported codecs and recommend a two-second keyframe interval and constant bitrate. They also provide bitrate guidance by resolution. Treat these as platform guidance to verify when you configure the encoder, not as a guarantee that any particular VM or network will sustain the stream.

Run and verify the continuous feed

A command for transcoding might look like this, with placeholders for the ingest URL and key. It is an example shape, not a universal profile; confirm option availability and order against the FFmpeg version installed on your instance and YouTube’s current settings:

ffmpeg -re -f concat -safe 0 -i /srv/media/playlist.ffconcat \
  -c:v libx264 -preset veryfast -b:v 2500k -maxrate 2500k -bufsize 5000k \
  -g 60 -c:a aac -b:a 128k -f flv 'rtmps://CURRENT_YOUTUBE_INGEST/STREAM_KEY'

The bitrate, buffer and GOP values shown are illustrative only, not a recommended setting for every resolution or frame rate. Replace the destination with the exact active endpoint and key from Live Control Room, and do not publish a real key. The -re option reads the input at its native rate rather than sending the media as fast as possible. The command transcodes to H.264 video and AAC audio; that work costs CPU. If you intend to stream-copy compatible inputs, configure that deliberately and test that the output is acceptable to YouTube.

Start the process in a way that suits your operations and lets you inspect its logs. A process that runs only in an interactive SSH terminal may stop when the session ends. A process supervisor or carefully managed service can restart it after a failure, but it does not replace monitoring: repeated restarts can leave the event offline or replay the wrong portion of the sequence. Keep logs useful without recording secrets.

Before you depend on the feed, watch the YouTube preview and confirm both video and audio. Check that the event is receiving a stable signal, the files change in the expected order and the transitions are acceptable. YouTube recommends upload capacity above the total stream bitrate and suggests roughly 20% upload headroom; treat that as guidance and test from the actual instance and network path. For multiple simultaneous outputs, account for their combined bitrate.

Monitor CPU use, outbound throughput, FFmpeg errors and YouTube stream health during a representative test. If frames drop or the preview buffers, consider reducing the output demands or using an instance with sufficient encode capacity and network throughput. Do not select a larger machine on guesswork alone: measure the actual process and test under the workload you will run.

After the test, review the event and any archive YouTube makes available. Confirm the broadcast ends or continues as intended, and that the saved material plays through the relevant transitions. For a longer discussion of symptoms such as rejected ingest or missing audio, see how to troubleshoot YouTube rejecting an FFmpeg stream from a cloud server. If maintaining a VM, file set, key and monitor is more operational work than you want, StreamNeo can remove the need to keep your own computer on for a file-based YouTube stream.

A useful preflight is to start with a short, unlisted or otherwise appropriately controlled test event, if your channel workflow permits it. Verify the key, endpoint, video and audio, then make any needed adjustments before scheduling a public broadcast. Keep checking YouTube’s current help pages: ingest options, account access and encoder guidance can change.

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 I paste a YouTube playlist URL into the concat manifest?

No. The concat demuxer expects a text manifest listing local files and directives, not a YouTube playlist URL. This workflow does not resolve, download or extract videos from YouTube.

Do all the files need to use the same format?

They need compatible streams, codecs and time bases for the concat demuxer to join them reliably. Files with different layouts may need a separate filter-based workflow that normalises them, which can require re-encoding and more CPU.

Should I use RTMP or RTMPS?

Use the current endpoint provided by YouTube for the event, and prefer RTMPS when your FFmpeg build supports it. Verify the scheme, URL and key in Live Control Room rather than relying on an old command or copied endpoint.

What Linode size do I need?

There is no universally correct instance size: needs depend on whether you stream-copy or transcode, the output settings, concurrent jobs and network capacity. Test the exact workload, monitor CPU and outbound throughput, and adjust based on what the test shows.

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 ↗