A playlist can mean a text file containing local media paths, an HLS .m3u8 manifest, or another web-based format. For a VPS-to-YouTube workflow, identify that format first: FFmpeg’s concat demuxer is designed for a trusted list of compatible local files, not every playlist found on the web.
The reliable sequence is to confirm YouTube access, download media you are authorised to use, create a local file list, check timestamps and codecs, then encode the result to YouTube over RTMPS. FFmpeg can send the feed, but it does not make an account eligible, repair incompatible source files, or guarantee that YouTube will accept a broadcast.
Identify what kind of playlist you have
Before choosing an FFmpeg input, open the playlist in a text editor or inspect its file extension. A simple local playlist might contain lines such as:
/home/channel/media/morning.mp4
/home/channel/media/episode-02.mp4
/home/channel/media/evening.mp4
That is the type of input used by the concat demuxer. It is a script that reads one local file after another and presents the sequence as a single input. The files still need to be compatible with one another, as explained later.
An HLS playlist is different. A .m3u8 file normally describes media segments, their order, and timing. It may be a local manifest, a remote stream, or a manifest that requires authentication. It has its own demuxing behaviour and should not be treated as a text list of complete video files. YouTube’s HLS ingest documentation also describes HLS as a separate delivery method with segment and playlist requirements.
Other formats can describe playlists too. A media player’s export file, an XML catalogue, a JSON queue, and a provider’s authenticated API response may all use the word playlist without being directly usable by -f concat. Check the format documentation before passing a remote URL to FFmpeg. Do not assume that adding -f concat will retrieve, authenticate, or interpret an arbitrary web playlist.
If your source is already one long local file, you do not need a playlist at all. If it is a list of separate MP4 files, the concat demuxer may be appropriate. If it is an HLS or other remote playlist, use the input method documented for that format and its access arrangement, or first obtain authorised local files in a way permitted by the owner.
A useful distinction is whether you control the files. A local list is easier to test because you can inspect file sizes, codecs, durations, and permissions before the stream starts. A remote manifest adds network, authentication, expiry, and availability concerns that are separate from YouTube ingest.
Check YouTube live-stream eligibility and create a stream
Do this before preparing hours of media. YouTube says live streaming requires a verified channel with no live-streaming restrictions in the prior 90 days. Review the current requirements in YouTube’s live-streaming eligibility guidance, because platform requirements can change.
In YouTube Studio, open Live Control Room and create or schedule the broadcast. The control room supplies the current server or ingest URL and the stream key. Copy both carefully. Treat the stream key like a password: do not put it in a public script, paste it into a repository, or include it in a screenshot.
The current YouTube help pages list a maximum of 10 active streams per channel and 3 active streams per stream key. Check the limits shown by YouTube when you configure your account, particularly if the VPS will be one of several continuous channels. A stream limit is an account or platform matter, not something FFmpeg can override.
Choose whether YouTube should start the broadcast automatically when the encoder connects or whether you will preview it and select Go live manually. A scheduled stream that is waiting for a manual action can look like an encoder problem when the encoder is actually sending data correctly.
For the first test, use a separate stream or a carefully chosen scheduled event. Keep the Live Control Room open so that you can see the preview, warnings, connection state, and audio and video indicators while FFmpeg is running.
Download authorised media to the VPS
Only download media that you own, have licensed, or have explicit permission to use in this way. A playlist URL is not proof that its contents may be copied to a VPS or rebroadcast. This matters for devotional music, films, recorded classes, local news clips, and material supplied by another organisation.
Create a clear directory structure on the VPS before transferring anything:
/home/channel/media/
/home/channel/lists/
/home/channel/logs/
/home/channel/scripts/
The exact path is your choice. What matters is that the account running FFmpeg can read the media and write its logs, while unrelated users cannot read files containing credentials.
Check available disk space before downloading. A local copy of a playlist needs room for the original media, temporary files, logs, and any converted versions you create. Do not give a universal VPS size recommendation based only on the phrase “24/7 stream”. The requirement changes with source resolution, frame rate, codec, output bitrate, and whether FFmpeg copies or transcodes the video.
Check sustained outbound bandwidth as well. The VPS must send the encoded stream continuously, and the connection should have room beyond the target stream bitrate. YouTube recommends 20% upload headroom in its streaming tips, so treat the target bitrate as something that must fit comfortably inside the available upload capacity rather than as the connection’s maximum.
After downloading, inspect the files instead of trusting their names. ffprobe is useful for checking duration, streams, codec, frame rate, pixel format, and time base:
ffprobe -v error \
-show_entries format=filename,duration:stream=index,codec_type,codec_name,width,height,r_frame_rate,time_base \
-of default=noprint_wrappers=1 \
/home/channel/media/morning.mp4
Run it against every file, or write a small inspection script that records the results. A file named episode-02.mp4 might have a different audio layout or frame rate from the other episodes. Finding that before the overnight run is much easier than diagnosing a frozen or silent section after viewers report it.
If you need a workflow that avoids keeping a personal computer switched on, a cloud-based service can remove the repeated upload and process-management work. StreamNeo is intended for the specific case where you upload a video once, provide the YouTube stream key, and let the feed run while your computer is off, with monitoring and automatic restart for drops.
Build a local file list for the concat demuxer
The concat demuxer reads a text script. The usual first line is ffconcat version 1.0, followed by file directives:
ffconcat version 1.0
file '/home/channel/media/morning.mp4'
file '/home/channel/media/episode-02.mp4'
file '/home/channel/media/evening.mp4'
Save this as /home/channel/lists/stream.ffconcat. Use absolute paths while testing so that a change of working directory does not select the wrong files. Quote paths containing spaces and special characters according to FFmpeg’s concat script syntax. A simple filename such as morning.mp4 is easier to maintain than a path containing several layers of shell quoting.
You can also create a plain list with file lines if that is more convenient, but keep the syntax consistent and validate the result before starting the encoder. The FFmpeg concat demuxer documentation describes the script format, path handling, stream requirements, and duration directive.
The safe option deserves attention. FFmpeg’s safe-path behaviour is enabled by default and rejects some paths considered unsafe. If your trusted list uses absolute paths and FFmpeg reports a safe-path error, -safe 0 permits them. Use it only when you control and have inspected the list. It broadens which paths FFmpeg will accept; it does not make an untrusted playlist safe.
For a repeating sequence, you have several choices. You can place the same entries in the list more than once, generate a new list for each cycle, or use a looping strategy that you have tested with your exact FFmpeg build and input. Repeating the entries is easy to understand, but a long list can become awkward to maintain. A list that ends will end the input, so do not mistake a finite test sequence for a continuous channel.
Avoid generating the list from unchecked filenames or web responses. A malicious or malformed entry could point outside the intended media directory, and an accidental quote or newline can change how the script is parsed. Treat the list as configuration that deserves the same review as the stream command.
Check compatibility and timestamps
The concat demuxer is not a general-purpose converter. Its files need matching streams, codecs, and time bases for the joined packet sequence to behave predictably. In practical terms, check that each video has a compatible frame size, frame rate, pixel format, codec, and time base, and that the audio streams use compatible codecs, sample rates, channel layouts, and time bases.
A group of files that all end in .mp4 is not necessarily compatible. Two MP4 files can contain different H.264 profiles, different audio codecs, or different frame rates. They may play normally one at a time but produce timestamp warnings, a broken transition, missing audio, or a stream that stops when joined.
When the files do not match, transcode them to a common intermediate format before building the final list. For example, you might create standardised copies with the same resolution, frame rate, video codec, audio codec, sample rate, and channel layout. The exact settings depend on the source and target, so test a short pair rather than applying a universal command to every channel.
The demuxer also relies on duration metadata. If a file reports an inaccurate duration, the next file can begin at an unexpected timestamp or show a visible or audible discontinuity. FFmpeg supports a duration directive in the concat script when you know a file’s intended duration is more reliable than its embedded metadata:
ffconcat version 1.0
duration 3600.000
file '/home/channel/media/morning.mp4'
duration 1800.500
file '/home/channel/media/episode-02.mp4'
Use measured or deliberately prepared values, not guesses. An incorrect override can create a different timing problem. Inspect the output around every transition during a test.
If a file has variable frame rate, damaged timestamps, or an unusual edit list, it may need to be remuxed or transcoded first. Do not hide repeated warnings by adding options at random. Find out whether the issue is an input timestamp, a codec mismatch, a permission problem, or a network problem.
Configure FFmpeg output for YouTube Live
For prerecorded files being emitted as a live feed, -re tells FFmpeg to read at the native rate rather than consuming the files as quickly as possible. FFmpeg documents this as useful for simulating a live input from a file and cautions against using it for actual live capture devices or live streams. It is therefore relevant here because the source is prerecorded media on disk.
A basic RTMPS command might look like this:
export YOUTUBE_URL='rtmps://your-current-ingest-url'
export STREAM_KEY='keep-this-private'
ffmpeg -re \
-f concat -safe 0 -i /home/channel/lists/stream.ffconcat \
-c:v libx264 -preset veryfast -b:v 4500k -maxrate 4500k -bufsize 9000k \
-pix_fmt yuv420p -g 60 \
-c:a aac -b:a 128k -ar 44100 -ac 2 \
-f flv "${YOUTUBE_URL}/${STREAM_KEY}"
Treat the bitrate, GOP length, and other values as starting points for testing, not as a guarantee for every source or account. YouTube’s current encoder guidance recommends H.264, constant bitrate, and a 2-second keyframe interval, with intervals not exceeding 4 seconds. The -g value is expressed in frames, so -g 60 corresponds to 2 seconds only when the output is 30 frames per second. Set the frame rate and GOP calculation deliberately for your chosen output.
For a 25 fps output, a 2-second keyframe interval would require a different GOP value. If your source frame rate is inconsistent, explicitly choose and test an output frame rate rather than assuming that the source will supply one. A command that happens to work for a 30 fps file may not express the same keyframe interval at another rate.
The example transcodes video and audio, which costs CPU. If all inputs are compatible and YouTube accepts the source codecs and layout, stream copying can reduce CPU use, but it gives you less control over frame rate, keyframes, bitrate, and timestamps. Copying also does not repair an incompatible concatenation. Benchmark the exact media and command on the selected VPS.
Use the current rtmps URL shown in Live Control Room rather than copying an ingest address from an old tutorial. RTMPS is RTMP over TLS/SSL. If an SSL connection fails, YouTube’s troubleshooting guidance discusses port 443 as part of diagnosis; confirm the URL and firewall rules supplied for your stream instead of changing ports blindly.
HLS can be the better ingest route when HDR or a codec outside RTMP support is required. YouTube describes HLS ingest using HTTPS POST/PUT, TS segments of 1 to 4 seconds, no byte ranges, and a rolling playlist with no more than 5 outstanding segments. It also notes that HLS has higher latency than RTMP. For a straightforward prerecorded feed, RTMPS is usually the simpler path when the required codecs and output settings fit.
Test the sequence and monitor stream health
Start with a short list containing two or three files, including a transition that represents the hardest case. Watch the local FFmpeg output for non-monotonic timestamp warnings, repeated reconnect messages, encoder overload, audio errors, and unexpected end-of-file messages.
At the same time, check the preview in Live Control Room. Confirm that the preview shows the intended video, audio is present, the connection health is acceptable, and the broadcast starts as you expect. YouTube advises testing the encoder and monitoring the stream rather than assuming that a successful process launch means viewers are receiving a good feed.
Watch the VPS process and network from a separate session. Useful checks include CPU usage, memory pressure, disk space, the FFmpeg log, and the process’s outbound traffic. A command that uses nearly all available CPU may survive a short test but fail when a different source causes a more expensive encode. A full disk can stop logging or prevent the next downloaded file from being prepared.
Keep credentials outside the command history where practical. Environment variables can reduce accidental exposure in a working session, but they still need appropriate permissions and handling. Do not place a stream key in a public monitoring URL or send full command output to a shared support channel.
A process supervisor can restart FFmpeg after a crash, but restarting is not the same as recovery. The stream may have a gap, YouTube may require a new connection state, and a failed input may fail again immediately. FFmpeg has protocol-specific reconnect options and a FIFO muxer recovery mechanism, but their usefulness depends on the protocol and failure type. Read the relevant FFmpeg protocol documentation and test the failure you care about.
A VPS reboot, network outage, expired remote URL, unreadable file, or encoder crash needs a different response. For a local concat list, the media may still be available after the network returns. For a remote playlist, the manifest or credentials may have expired. Document what should happen in each case instead of adding a blanket retry loop and calling the channel reliable.
If you are maintaining a long-running channel, the troubleshooting guide on why an FFmpeg YouTube stream stops after a few hours can help you separate process exits, input exhaustion, network interruptions, and YouTube-side state. For a VPS-specific deployment, compare the operational steps in how to host a continuous YouTube gaming stream on a VPS, while remembering that your playlist format and encoder settings may differ.
Decide whether this workflow suits your channel
This VPS method is useful when you need control over local files, FFmpeg settings, logs, and the exact order of playback. It also lets you standardise media before it reaches YouTube. The cost is operational work: downloading files, checking rights, maintaining disk space, protecting the key, supervising the process, and responding when a stream ends or a source changes.
It is a poor fit if the media is not stable enough to download, the files have widely different technical formats, or nobody can check the channel after a failure. In that case, first simplify the library and make a short sequence reliable. A larger playlist does not fix a faulty transition or an exhausted input.
For channels built from recorded lessons or revision material, playback order matters as much as encoding. The advice in how to run a 24/7 CBSE revision stream from recorded videos is relevant to planning the programme, but the concat compatibility checks still apply to the files you actually place on the VPS.
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 pass any .m3u8 playlist to the concat demuxer?
No. An HLS .m3u8 manifest describes segments and uses a different input path from a text list of local files. Identify the playlist type, then follow the documentation for that format, its authentication method, and its network behaviour.
Can FFmpeg stream files with different codecs in one concat list?
Do not rely on that. The concat demuxer expects compatible streams, codecs, and time bases, and mismatches can cause timestamp, audio, or transition problems. Standardise the files first, or use a different workflow that decodes and re-encodes each item into a common output.
Does -re make a VPS stream live forever?
No. It paces prerecorded input at its native rate, but it does not loop an exhausted list, repair a failed download, or restart a crashed process. Build and test the looping and recovery behaviour separately.
Will this command guarantee YouTube acceptance?
No. Account eligibility, current platform limits, stream settings, content rights, network conditions, and the actual encoder output all matter. Use Live Control Room to verify the current requirements, preview the feed, and investigate any warnings before relying on the channel.