Skip to content
streamneo.
Setup Guides12 min read

How to Create a 24/7 YouTube Radio Stream from an MP4 Playlist Using FFmpeg

Build a looped MP4 playlist stream with FFmpeg, configure YouTube Live and RTMPS, and test delivery before relying on it.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

To create a 24/7 YouTube radio stream from MP4 files, configure a YouTube Live broadcast, list compatible files in an FFmpeg concat-demuxer playlist, then loop that input and send the encoded output to YouTube over RTMPS. The encoder must keep delivering a live feed; this is not the same as uploading a video and letting YouTube play it.

Treat the setup as a chain that needs checking: your channel must be able to go live, the files must work together, the output must match YouTube’s current ingest guidance, and the connection must stay usable. A command can start successfully and still encounter bad transitions, network drops or account-state problems later.

Prepare the files and check channel access

Start with the video files, not the FFmpeg command. Make a working folder and put the MP4s in the intended playback order. Give files clear names such as track-001.mp4 and track-002.mp4; a numbered order is easier to inspect than relying on whatever order a file manager happens to show.

For the concat demuxer, the files should have compatible stream layouts, codecs and time bases. In practice, also compare dimensions, frame rates, pixel formats, audio sample rates and channel layouts. MP4 is a container, not a guarantee that the video and audio inside every file are encoded alike. A set of MP4s can therefore be incompatible even when they all play normally on a computer.

Inspect the files with a media-information tool such as ffprobe, or use a media application that reports the stream details. If the files differ, make consistent working copies before building the playlist. You can either transcode them to a common format or use a filter-based concat workflow that re-encodes the combined output. Transcoding uses more processing capacity, but gives you more control over output consistency. For a closer comparison of FFmpeg setups, see streaming pre-recorded video at 4K and 60 fps.

Check that you have the necessary rights to stream each file. Technical compatibility does not settle rights questions, and this guide cannot determine what permissions apply to a particular playlist.

Also check your channel in YouTube Studio before preparing a long-running session. Confirm that Live streaming is available to the account and that the current Live Control Room lets you create or select the broadcast you intend to use. An FFmpeg command does not enable Live access, create a broadcast, or guarantee that the account is ready to publish. Follow the current YouTube instructions for live streaming with an encoder and check the account’s actual state in Studio rather than relying on an assumed activation time.

Create the Live broadcast in YouTube Studio

YouTube Live has two related pieces: the broadcast viewers watch, and the incoming stream feed that your encoder sends. The Live Control Room is where you set up or select the broadcast and obtain the connection details for the encoder. The YouTube Live API describes the stream as the feed delivered to YouTube and associated with a live broadcast; it is not a stored playlist that YouTube fetches on its own. See the YouTube Live API resource model.

In Live Control Room, create or select the broadcast, then open the stream settings and use the ingest details shown there. YouTube’s interface can change, so take the URL and key from the current session rather than copying values from an old tutorial. Select RTMPS where it is offered for this encoder workflow. YouTube describes RTMPS as RTMP over an SSL connection and recommends it for live streaming.

Set the broadcast visibility and scheduling details deliberately. An unlisted or private test can help you inspect the feed without making a public launch your first validation run. Keep the broadcast and incoming stream associated as the Control Room indicates; starting an encoder process alone does not necessarily mean viewers have a ready, correctly configured live page.

Do not leave the broadcast setup until you know which stream key belongs to this session and where you will enter it. If you need context on the key field in another encoder workflow, the guide to where to paste a YouTube Live stream key in OBS explains the same credential concept, though FFmpeg uses an output URL instead of an OBS form.

Build the concat-demuxer playlist

Create a plain-text file named playlist.ffconcat in the working folder. The signature must be the first line, exactly as shown, so FFmpeg can recognise the format automatically. Add one file directive for each MP4 in playback order:

ffconcat version 1.0
file 'track-001.mp4'
file 'track-002.mp4'
file 'track-003.mp4'

Relative paths make the playlist easier to move with the media. If you use spaces or special characters in file names, quote or escape paths correctly. Test the list from the directory where you intend to run FFmpeg, and make sure each named file exists with the exact spelling and letter case used in the playlist.

FFmpeg’s concat demuxer presents the listed files as one sequential input. Its input files need compatible streams, including codecs and time bases, and the demuxer adjusts timestamps based on reported file durations. Read the FFmpeg concat demuxer documentation for the details and current options.

The demuxer’s safe option defaults to 1, which rejects unsafe paths or directives. Prefer relative paths that pass that check. The example command below uses -safe 0 to allow a playlist that may contain absolute paths; only do that when you trust the playlist file and its contents. A playlist is executable input in the sense that it directs FFmpeg to open paths, so do not use an unknown list without reviewing it.

Do not assume that a playlist will be seamless just because every item appears in sequence. If stream durations differ, the next file’s timestamps are based on the preceding file’s duration; gaps can result. Incorrect duration metadata can create visible or audible artefacts. Test files with their actual encodings and durations, not just a short placeholder list.

Loop the playlist input with FFmpeg

For compatible MP4s, a basic approach is to use the concat demuxer as the input and request infinite input looping with -stream_loop -1. Put input options before the corresponding -i, and use real-time pacing so FFmpeg reads media files at playback speed rather than consuming them as quickly as the machine can process them.

ffmpeg -re -stream_loop -1 -f concat -safe 0 -i playlist.ffconcat \
  -c:v libx264 -preset veryfast -pix_fmt yuv420p \
  -b:v 4500k -maxrate 4500k -bufsize 9000k -g 60 \
  -c:a aac -b:a 128k -ar 44100 \
  -f flv 'rtmps://YOUR_CURRENT_INGEST_URL/YOUR_STREAM_KEY'

This is an illustrative starting point, not a tested universal command. Replace the output URL with the current ingest URL and key shown in YouTube Studio. The example re-encodes to H.264 video and AAC audio; it does not simply copy the original MP4 streams. Re-encoding helps produce a consistent output when the sources need it, but it costs processing capacity.

The shown values are not a recommendation for every channel or file. In particular, do not copy the example’s video bitrate or GOP value without checking your chosen frame rate, resolution, source material and upload connection. YouTube’s guidance calls for constant bitrate (CBR) and a two-second keyframe interval, with intervals no longer than four seconds. At 30 frames per second, a 60-frame GOP corresponds to about two seconds; use a value that fits the frame rate you actually send. Check your installed FFmpeg manual as option behaviour can differ by build and version.

If your files are already compatible, packet copying may reduce the encoder’s workload, but it gives you less control over differences between sources and their transitions. If they are mixed, re-encode a consistent set first or use a concat-filter workflow. The concat demuxer and concat filter are different tools: the demuxer joins compatible inputs at the input stage, while the filter can combine streams for re-encoding. Choose based on the files you have and the processing capacity you can sustain.

Set compatible video and audio output

Choose output settings from YouTube’s current encoder settings and bitrates guidance, not from a copied command alone. YouTube’s recommendations cover supported codecs, bitrate mode, keyframe interval and quality settings. The settings depend on the resolution and frame rate you plan to send, and the best choice is one your connection can deliver steadily.

The example uses H.264 video, AAC audio and yuv420p, a common compatibility choice. It sets a 44.1 kHz audio sample rate and 128 kbps AAC audio. YouTube lists 128 kbps for stereo audio; do not treat those example audio values as appropriate for a 5.1 mix, for which YouTube lists a different sample-rate recommendation. If you are making a devotional or lofi radio channel, check whether the files are stereo and preserve the intended channel layout.

The video bitrate in the example is only illustrative. Add the audio bitrate and account for protocol overhead when thinking about required upload capacity. Select a connection with dependable headroom above the total output rate, and test it with the actual stream settings. A link that can briefly reach the target rate may still struggle over a long session. YouTube advises testing upload bitrate and choosing a quality level that remains reliable on the connection.

The choice between transcoding and copying is a trade-off rather than a universal rule. Transcoding can make mismatched material more consistent, but consumes CPU and may reduce quality if you re-encode already compressed media. Packet copy avoids that encoding work, but it does not repair incompatible streams or duration metadata. If you are comparing an always-on computer with another operating arrangement, VPS and managed streaming trade-offs can help frame the operational choice without changing the need to validate the feed itself.

Connect over RTMPS and protect the key

Use the RTMPS endpoint provided for the current YouTube Live stream. The output URL in the example is a placeholder: join the current endpoint and the stream key in the format expected by the Control Room. Never publish a real key in a public script repository, shared command, tutorial, terminal screenshot or support post. Treat it like a password that can let someone else send content to your stream.

A command typed directly into a terminal can remain in shell history, and process listings or logs may expose the full output URL depending on your system and how you run it. Limit access to the machine and scripts that hold credentials. Avoid writing the key into a file that is synced or shared, and redact it from logs before sending them to anyone. If you think it has been exposed, use YouTube Studio to replace or reset it, then update the encoder configuration.

RTMPS is the typical choice for an FFmpeg encoder path. YouTube also documents HLS ingestion for certain workflows, including cases where supported codecs or HDR needs differ from RTMP; HLS sends media in segments and has higher latency. It requires an HLS-capable configuration and should not be confused with sending ordinary FFmpeg FLV output to an RTMPS URL. See YouTube’s HLS ingestion guidance if that path is relevant to your encoder. For a standard playlist-to-live setup, use the RTMPS ingest settings shown in the current Live Control Room.

Once connected, look for the incoming feed and stream-health status in Live Control Room. A process that has not exited is not proof that YouTube is receiving a healthy stream. If the endpoint rejects the connection or the key is wrong, check the current settings in Studio before changing unrelated encoding parameters.

Test transitions and monitor delivery

Before relying on a 24/7 YouTube stream with FFmpeg, run a private or unlisted test using representative files. YouTube recommends testing with similar audio and movement to what you intend to broadcast. Include the loudest or most complex audio, a file with motion, and any source that differs from the rest of the playlist. Check Live Control Room’s stream-health messages while the encoder runs.

Watch at least one complete pass through the playlist and the transition back to its first file. Listen for silence, abrupt cuts, duplicated sound or level changes, and look for black frames, frozen images or unexpected aspect changes. The point is to see what happens at boundaries and at the loop wrap, not just to confirm that the first few seconds play. If the transition is poor, inspect durations, timestamps and stream compatibility before concluding that the output bitrate is the cause.

Also test failure cases in a controlled way. Confirm what happens if a source path is missing or a file is damaged, and whether the process exits or continues in a state that needs attention. Review FFmpeg logs and keep them somewhere persistent enough to diagnose a later interruption. Do not expose the stream key when sharing a log or screenshot.

For unattended operation, keep the FFmpeg process under a suitable process supervisor or service manager, configure what should happen after an exit, and arrange an alert for process failure or loss of ingest. Assign a person to check stream health; automatic restarts do not identify every cause or guarantee a clean return to viewers. YouTube’s stream-health view is useful, but it does not replace checking the programme, sound and transitions yourself.

When the specific burden is keeping a computer powered and the encoder process running through the night, StreamNeo can remove that local-computer task by taking an uploaded video and running it as a YouTube live stream; you still need to prepare the media, configure the channel and check the result.

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

Is this a normal YouTube video upload?

No. FFmpeg reads the playlist and continuously sends an encoded live feed to YouTube’s ingest endpoint. The broadcast must be configured in YouTube Live, and the encoder needs to keep delivering; it is different from uploading a video file for on-demand playback.

Can I use MP4 files with different formats in one concat playlist?

The concat demuxer is intended for inputs with compatible streams, codecs and time bases. If the files differ, normalise or transcode them, or use a concat-filter workflow that re-encodes. Test the resulting transitions rather than assuming that matching file extensions mean matching media streams.

Why might the playlist have a gap between files?

The concat demuxer uses file durations when adjusting timestamps for the next input. Different stream lengths or inaccurate duration metadata can result in gaps or artefacts. Inspect the source files and watch a full playlist cycle before leaving the stream unattended.

Does -stream_loop -1 mean the stream will run indefinitely without attention?

It requests infinite looping of the input, but it does not ensure the computer, connection, encoder or YouTube ingest will remain available. Monitor the process and Live Control Room stream health, keep useful logs, and arrange a response to failures. A loop option is not an uptime guarantee.

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 ↗