Skip to content
streamneo.
Setup Guides13 min read

How to Make a 24/7 Study Playlist Stream with FFmpeg

Build a repeatable FFmpeg study playlist stream with concat, infinite looping, real-time pacing and RTMP publishing.

sn.
StreamNeoPublished 3 October 2026
Worth sharing?

A repeatable 24/7 study playlist stream with FFmpeg starts with a concat list of your video files. You then loop that list with -stream_loop -1, pace the input in real time with -re, and publish it to the live destination using the protocol that destination supports.

The difficult part is not making FFmpeg repeat a file. It is preparing files with compatible streams, choosing whether to re-encode, keeping the output at real-time speed, and separating FFmpeg mechanics from YouTube's own live-streaming and content requirements.

Prepare the lecture or study-video files

Start with the material that will make up the broadcast: recorded lectures, study-with-me sessions, timer videos, quiet desk footage or other content for which you have the necessary rights. Put the files in one working folder and give them simple names such as study-video-01.mp4 and study-video-02.mp4.

Simple filenames are not mandatory, but they reduce errors in the concat file. Spaces and special characters can be used when they are quoted or escaped correctly. A filename such as Math Lecture - Week 1.mp4 is more likely to cause trouble than math-week-01.mp4, particularly when you are editing the playlist by hand.

Before building the stream, decide whether the clips should play in a fixed order. A study channel might begin with a short welcome, continue through several lecture recordings, then play a longer quiet revision session before returning to the welcome. FFmpeg will follow the order in the list, not the order in which files happen to appear in your folder.

Check each file on its own first. Look for missing audio, a black opening frame, a visible change in aspect ratio, a different frame rate, or a sudden change in volume. These problems may not prevent FFmpeg from running, but they can make the transitions unpleasant or cause the concat demuxer to reject the input.

A consistent frame rate is useful for long unattended loops. If you are deciding between ordinary video frame rates for a mostly static study stream, the explanation in this guide to why 30fps can be more practical than 60fps for 24/7 loops is relevant. The point is not that every channel must use one setting, but that a lighter, consistent format is usually easier to maintain than a mixture of files.

Keep an untouched copy of the original recordings. If you need to normalise them later, work on copies with new filenames. That makes it possible to identify whether a transition problem comes from the original file, the converted file or the playlist command.

Build the FFmpeg concat list

The playlist is a text file read by FFmpeg's concat demuxer. It is not an M3U playlist and it is not a shell script. Create a file named playlist.ffconcat in the same working folder as the media files:

ffconcat version 1.0
file 'study-video-01.mp4'
file 'study-video-02.mp4'
file 'quiet-revision-session.mp4'

The first line is optional in some workflows, but when you use it for automatic format recognition it must be exactly ffconcat version 1.0 and it must be the first line. Each file directive names one input. FFmpeg's formats documentation describes this demuxer as reading the listed files and demuxing them one after another.

Relative paths are convenient when the playlist and media files live together. If the files are elsewhere, use paths that your operating system and FFmpeg build can read. With absolute paths, you may need -safe 0 on the command line. That option is included in the example later, but it does not repair a wrong path or a permissions problem.

Quote paths containing spaces. In the concat file, single quotes are commonly used, as in:

file 'lectures/week 01 - algebra.mp4'
file 'lectures/week 02 - geometry.mp4'

A quote or backslash inside a filename needs the appropriate escaping. If you are generating the list with a script, make the script handle those characters rather than assuming every filename is plain text.

The list can be inspected without publishing anything. Run a short command that reads the concat input and writes a local output, or open the first few files in your normal media player and compare their properties. The exact diagnostic command depends on your FFmpeg build, so do not treat the publishing command as a substitute for checking the inputs.

The concat demuxer joins files at the packet level. It is therefore convenient when the files already have compatible stream structures and you want to avoid re-encoding them. It is different from the concat protocol, which is another file-level method with narrower container suitability. The concat filter is a separate option used when you need filtering or re-encoding.

Check stream layouts, codecs and time bases

This is the stage that determines whether the simple concat workflow is appropriate. FFmpeg's concat demuxer expects the files to have the same streams, including compatible codecs and time bases. In practical terms, your clips should have the same basic video and audio arrangement rather than alternating between, for example, one video-only file and one file with stereo audio.

Inspect the files with ffprobe, which is normally distributed with FFmpeg. You are looking for differences in at least these areas:

Property What to compare Why it matters
Video stream Codec, dimensions, pixel format and frame rate Prevents visible changes and stream incompatibility at transitions
Audio stream Codec, sample rate, channel layout and presence Keeps audio present and structurally consistent
Stream count Number and order of streams The concat demuxer expects the files to line up
Time base and timestamps Per-stream timing information Helps avoid jumps, gaps or unexpected duration behaviour
Container metadata Duration and other timing details Incorrect duration metadata can affect transitions

A file can look normal when played by itself and still be a poor match for a concat list. Media players are often forgiving. A demuxer working through a long sequence has less room for an inconsistent stream layout.

If the files match, stream copying may be possible. That means FFmpeg passes the encoded streams through without creating new video and audio. It can reduce computer load and avoid another generation of quality loss, but it leaves the input compatibility requirements in place.

If the files do not match, re-encoding is the more flexible route. The concat filter is designed for workflows where re-encoding is needed, and it can help you normalise dimensions, frame rates, audio layouts and other properties before the output is sent onward. It uses more processing and may take careful testing to avoid introducing blur, sync problems or an unnecessarily large output.

Do not add a re-encoding command simply because it looks more complete. First decide what the inputs require. A copied stream is attractive when the files already match. A normalised output is more appropriate when your source library contains recordings made with different software or devices.

Duration information also matters. FFmpeg adjusts timestamps globally across the concatenated input, but mismatched stream lengths can create gaps. Incorrect duration metadata can produce artefacts. The concat demuxer supports a duration directive when a file's duration is unavailable or known to be wrong, but use it only when you have a reliable duration to enter.

This preparation is also where you should decide how much visual variation your audience will tolerate. A study stream may contain several aspect ratios because lectures were recorded on different screens. Normalising the canvas before the 24/7 process is usually cleaner than discovering a different layout every time the playlist cycles.

Loop the concat input with -stream_loop -1

Once the list is ready, infinite repetition is an input setting. FFmpeg documents -stream_loop -1 as infinite looping of the input. Place it before the relevant -i input so it applies to the concat playlist rather than being mistaken for an output option.

A basic RTMP-family structure looks like this:

ffmpeg -re -stream_loop -1 -f concat -safe 0 -i playlist.ffconcat \
  -c:v libx264 -c:a aac -f flv "rtmps://INGEST_HOST/APP/STREAM_KEY"

This is an illustrative starting point, not a universal preset or a tested command for every file set and destination. The codec choices, output profile, bitrate, protocol acceptance, URL shape and credentials depend on your FFmpeg build and the live destination.

The important parts are the relationship between the options. -stream_loop -1 repeats the concat input indefinitely. -f concat tells FFmpeg how to read the playlist. -i playlist.ffconcat names that input. The output options after the input select how the published stream is encoded and packaged.

Do not put a real stream key in a public article, screenshot, support post or shell history that other people can access. Treat it as a password. If you expose it, use the destination's process for replacing or revoking it before starting again.

Looping the input does not supervise the process. It does not make a computer immune to sleep settings, power loss, network failure, encoder errors or a destination disconnect. It also does not establish that YouTube permits every pre-recorded 24/7 broadcast. FFmpeg is repeating media; the platform still has its own policies, account requirements and content rules.

The loop also repeats your content exactly as listed. If you do not want a welcome card or a spoken introduction every time the cycle begins, remove it from the list or arrange the sequence differently. If a transition should be silent, that needs to be handled in the media or filter workflow rather than assumed from the loop option.

Pace and publish the output in real time

A file can be decoded and sent faster than its recorded duration unless you tell FFmpeg to read it at its natural rate. The -re option is used for real-time input in this type of publishing command. Without real-time pacing, a local test may consume the playlist quickly and send data at a rate the live destination cannot treat as a normal live programme.

Real-time pacing is not the same as a guarantee of smooth delivery. Your computer still has to decode the files, encode the selected output, maintain the network connection and keep the process running. Watch for sustained CPU pressure, memory problems, dropped network connectivity and messages in the FFmpeg log.

The output container also matters. FFmpeg documents RTMP publishing with real-time input and FLV output. RTMPS is RTMP over an encrypted SSL connection. Use the exact ingest URL supplied by the destination instead of guessing the host, application path or stream-key position. FFmpeg's protocol documentation explains the RTMP URL structure and the RTMPS distinction.

Do not confuse the media workflow with a platform's delivery requirements. RTMP and RTMPS are ingest paths. YouTube HLS is a separate configuration with its own segment and playlist rules. Choosing -f flv for an RTMP-family command does not create a YouTube HLS stream.

A stable command needs an output format the destination actually accepts. If the output contains codecs or a profile the ingest service rejects, changing -re or the concat list will not solve the problem. Confirm the current destination documentation before settling on encoder options, and keep a copy of the command that last worked.

Send it to the supported live ingest destination

For a YouTube RTMP or RTMPS broadcast, create or select the live event in YouTube Studio, obtain the current ingest details, and paste the stream key into your local command. Keep the key private. The endpoint is supplied by YouTube, not by FFmpeg, and it may not have the same shape as an endpoint from another service.

Start with an unlisted or otherwise private test where the destination offers that choice. This lets you confirm the relationship between the FFmpeg process and the live control room without treating a first attempt as a public launch. Check that the destination sees the broadcast, that audio is present and that the preview advances rather than freezing on one frame.

YouTube's HLS path should be handled separately. Its official HLS setup guidance specifies TS segments, segment durations from one to four seconds, HTTPS POST or PUT, and a rolling playlist with no more than five outstanding segments. YouTube also explains that HLS has higher latency than RTMP because it sends segments rather than one continuous stream.

That means the RTMP/FLV example above should not be presented as an HLS command. If your destination specifically requires HLS, follow its current HLS documentation and build the segmenting and upload process it describes. Do not infer HLS settings from a working RTMP command.

There is also a policy boundary here. A technically valid connection only shows that the ingest path accepted data. It does not show that the particular study playlist meets YouTube's current requirements for live broadcasts, repetitive content, rights, monetisation or account eligibility. Check the relevant official pages before committing to an unattended public channel.

If you are deciding between running FFmpeg on your own computer and moving the repeating job away from your desk, compare the practical trade-offs in OBS and a cloud streaming service. A local FFmpeg process gives you direct control and uses equipment you already have. A managed workflow can remove the need to leave your personal computer switched on, but it does not remove the need to prepare suitable media or follow the destination's rules.

Test the feed and monitor it

Run the complete workflow for a short private test before relying on it overnight. Use enough of the playlist to cross at least one file transition, because a command that works for the first clip has not yet proved that the concat list works.

Check these points in order:

  1. The first video starts with the expected frame and audio.
  2. The transition to the next file occurs without a freeze, black screen or audio gap.
  3. The output reaches the live control room and remains in a live state.
  4. The programme plays at real-time speed rather than racing through the source files.
  5. The FFmpeg log shows no recurring decode, timestamp, connection or encoder errors.
  6. The computer remains awake and the network connection stays available.
  7. The stream key is not visible in saved logs, screenshots or shared commands.

The first repeat is worth observing as well. Some mistakes remain hidden until the final file hands control back to the first file. If the return to the beginning produces a timestamp jump, inspect the source durations and stream layouts before changing random command options.

For longer operation, decide what you will do when the process stops. FFmpeg's input loop does not itself promise reconnection, process supervision or automatic recovery after a host restart. A separate operating-system service, wrapper or monitoring arrangement may be appropriate, but the correct design depends on your operating system and the failure you want to handle. Test recovery rather than assuming it.

If a YouTube broadcast drops, the FFmpeg reconnection guide can help you think through the difference between a network reconnect and a full process restart. A connection that returns is not necessarily the same as a cleanly resumed live event.

A cloud-based workflow can also remove one specific operational burden: keeping your own computer running for the media loop. StreamNeo removes that particular unattended-computer problem by taking an uploaded video, your YouTube stream key and the repeating broadcast out of the local-machine routine, while you still need to make your media and destination choices carefully.

Finally, distinguish technical continuity from content suitability. A playlist can repeat without interruption and still need review for copyright, rights to lecture recordings, repetitive-content concerns and current platform requirements. The article “Fake” live streams and when YouTube allows them is useful background, but check YouTube's current official guidance before making a policy decision.

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 FFmpeg play several MP4 files continuously?

Yes, when you put the files in a concat demuxer list and the files meet the demuxer's matching-stream requirements. Add -stream_loop -1 before the concat input to repeat the list indefinitely. The files still need compatible streams, timing and usable duration information.

Do I need to re-encode every study video?

No. If the files are compatible, stream copying may be possible and can reduce processing. When the files differ, re-encoding or the concat filter can normalise them, but it costs more processing and may change quality.

Is -stream_loop -1 enough for a 24/7 YouTube channel?

No. It repeats the media input, but it does not provide process supervision, host uptime, network availability or automatic recovery. It also does not prove that YouTube permits a particular pre-recorded 24/7 broadcast.

Can I use the RTMP command for YouTube HLS?

Not directly. RTMP or RTMPS with an FLV output is a different ingest path from YouTube HLS, which has its own segment format, upload method, duration and playlist requirements. Follow the current documentation for the path your destination requests.

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 ↗