A playlist file lets FFmpeg join relaxation clips in a chosen order, then repeat that sequence while it processes the input. To make a YouTube upload, however, you must also set a finite output duration; an endless input loop is not a finished file.
The concat demuxer is convenient when clips have compatible streams, but it is not a universal joiner. Check codecs, stream layout, time bases and durations first: stream-copy concatenation expects matching streams, and unequal durations can leave gaps. If you only want viewers to replay a video or playlist on YouTube, its player has loop controls, so you may not need to export a longer file.
Prepare and order the relaxation clips
Start with the actual clips you intend to use, not a folder you have not reviewed. Decide the sequence before creating the playlist: for example, place a quiet dawn scene before a longer rain view, then follow it with a low-motion night scene. A predictable order is easier to inspect and makes repeated transitions less surprising to a viewer who joins at any point.
Keep the source files together in a working folder, or use clear paths to their locations. Give each file a recognisable name such as misty-hills-01.mp4 rather than relying on names like final2.mp4. Avoid renaming or moving files after the playlist is made, because the playlist refers to paths, not to media embedded inside it.
Listen to the audio as well as watching the picture. A clip that seems calm visually can contain a sudden loud bird call, a cut in music, or silence at its tail. If the clips are meant to form a continuous ambience, listen across the exact joins you plan to use. A source that ends abruptly will still end abruptly when repeated; a playlist does not blend its boundaries for you.
Check that you own the source material or have permission for the planned use, including any music. Keep a record of licences and their conditions. The licence documentation checklist for a YouTube livestream is useful when several clips or tracks come from different sources. This is a practical rights check, not a guarantee of how YouTube will assess an upload.
If your real goal is simply continuous playback of existing material, compare that with a new export before spending time encoding. YouTube’s loop controls for videos and playlists let a viewer repeat playback from the player. A new file is useful when you want one long upload or a file for another workflow, but it takes processing time and storage and creates another asset to check.
Create the concat-demuxer playlist file
The concat demuxer reads a text file containing one directive per input file. Create a plain-text file in the working folder called relaxation.ffconcat and put the clips in the order you want them to appear:
ffconcat version 1.0
file 'misty-hills-01.mp4'
file 'rain-window-02.mp4'
file 'night-lake-03.mp4'
The FFmpeg Project documents this as a list of files demuxed one after another. The first line is optional for a plain text list, but if you include ffconcat version 1.0 for automatic format recognition, it must be the exact first line. Do not add a blank line, spaces before it, or a byte-order mark ahead of it.
Relative paths are resolved from the process working directory, which is not necessarily the directory where the playlist sits. For a first test, run FFmpeg from the folder containing both the playlist and the clips. If you prefer absolute paths, use the full locations and be precise about quoting. A path containing spaces must be quoted or escaped according to the concat file syntax; do not assume shell quoting rules and playlist quoting rules are identical.
The examples use single quotes around simple filenames. If a filename itself contains a single quote, backslash, or other special character, escape it as required by the FFmpeg concat syntax, or rename the file to a simpler name before building the list. Simpler filenames reduce transcription mistakes and make it easier to verify that each directive points to the intended clip.
A basic playlist does not need a duration line for each file. Do not add guessed duration values to paper over a mismatch: the demuxer uses file durations to place later timestamps, and inaccurate duration information can contribute to timing problems. For an initial check, use a small subset of clips and a short output rather than starting a long encode with an unverified list.
The -safe 0 option in the examples below relaxes path safety checks, which can be useful for trusted local paths that FFmpeg otherwise rejects. It is not a reason to process a playlist supplied by someone you do not trust. Playlist directives can reference files beyond the intended folder, so inspect the text file and use trusted inputs only.
Check streams and durations before joining
Before using the concat demuxer, compare the streams in every clip. The relevant properties include the presence and order of video and audio streams, codecs, time bases, dimensions, frame rate and audio parameters. Concat demuxer stream-copying is not a way to reconcile different formats. If one clip has video and stereo audio while another has no audio, or their codecs and stream parameters do not match, do not assume the join will work cleanly.
Inspect the files with a media information tool or FFmpeg’s input reporting, then note the differences. Also check whether audio and video run for the same length within each clip. A clip with a longer audio tail or a shorter video track can shift the practical boundary. The FFmpeg demuxer documentation warns that files with unequal durations may cause gaps, because timestamps for following files depend on the preceding file’s duration.
That warning matters for a relaxing loop: a small black pause, frozen frame or silent interval can be conspicuous when the rest of the channel is steady. Do not confuse “the command completed” with “the clips form a seamless sequence”. Render a short sample that crosses at least one transition and inspect it with sound before committing to the full runtime.
If the streams are compatible and you do not need to alter them, stream copy can avoid decoding and re-encoding the media. But the conditions matter. Stream-copy concatenation expects compatible streams and does not correct differing dimensions, codec settings, missing audio, or timing problems. Where sources differ, normalise them to a consistent set of streams and re-encode, or use FFmpeg’s concat filter in a decode-and-encode workflow. The FFmpeg FAQ on concatenation explains the distinction between joining compatible inputs without re-encoding and using the concat filter when re-encoding is needed.
A re-encode takes longer and uses more processing than simply copying packets, but it gives you a chance to make all segments consistent. Choose a common frame size, frame rate and audio layout that suit the source and intended video. Avoid forcing a frame rate or size without a reason: for a peaceful landscape clip, unnecessary conversion can add work without improving the source picture.
Loop the playlist during processing
To repeat the playlist indefinitely as an input while FFmpeg runs, use -stream_loop -1 before the input it applies to. A representative command for compatible clips is:
ffmpeg -stream_loop -1 -f concat -safe 0 -i relaxation.ffconcat \\
-t 02:00:00 -c:v libx264 -c:a aac -ar 48000 \\
-movflags +faststart relaxation-loop.mp4
Here the playlist is the input, -stream_loop -1 tells FFmpeg to repeat it without a set count, and -t 02:00:00 sets the output duration to two hours. The input loop and output duration serve different purposes: the first supplies repeated content, while the second ends the export. Without an output limit or another stopping condition, an infinite input loop does not produce a finite YouTube-ready file.
FFmpeg options apply according to where they appear. -stream_loop is an input option, so placing it after -i relaxation.ffconcat would not apply it to that input as intended. Likewise, output settings belong after the input they configure. Check the command against the installed FFmpeg version and your actual files, particularly if you adapt it to use multiple inputs or a filter graph.
This command re-encodes video with H.264 and audio with AAC; it is not a stream-copy example. That makes it suitable as a basic output pattern when you want common upload codecs, but it does not normalise every possible mismatch automatically. A missing audio stream, differing dimensions, or troublesome timing may require explicit filters and a more deliberate re-encode workflow. Test first and read FFmpeg’s output for warnings.
If you do not need an export and only want a viewer to repeat playback, YouTube’s own loop controls avoid rendering and storing another file. Conversely, if you need a single long asset to upload, the finite export route is the relevant one. For a continuous news format made from recorded pieces, this guide to a recorded-clip replay channel covers the larger channel workflow; this article is about constructing and checking the media sequence.
Set a finite export duration
Choose the intended runtime before rendering. The example’s -t 02:00:00 asks FFmpeg to stop output at two hours; replace it with the duration you actually need. If the playlist’s total duration is shorter than that, the loop supplies additional repetitions. If the requested duration ends partway through a repeated cycle, the final clip may be cut at the endpoint.
That final cut deserves attention. For a two-hour relaxation video, cutting during a quiet sustained shot may be acceptable, but ending on a sudden movement or a sharp sound may not be. If you want a clean ending, arrange the sequence so likely endpoints fall at a natural boundary, or produce and inspect a short test at the chosen duration. A duration flag does not create a fade or a musical resolution.
For a fixed number of repetitions rather than a fixed runtime, another approach is to make a finite playlist with enough repeated entries. That can be useful when every cycle must end at the same clip boundary, but you still need to know how long the output will be and avoid an accidental overlong file. A fixed duration is usually easier when the target is a planned runtime; repeated entries are easier when boundaries matter more than exact length.
Rendering time and output size depend on the clips, chosen encoding settings, computer and other factors. Do not infer that a two-hour target will finish in two hours. Give the process room to complete, make sure the destination has adequate storage, and keep the source files unchanged until you have checked the export. If you are building a 24/7 channel rather than a single upload, also plan how the finished file will be sent to YouTube and what happens if the live broadcast stops; encoding a file and maintaining a live channel are separate tasks.
Choose YouTube-compatible output settings
For an upload, YouTube’s published recommended encoding settings list an MP4 container and H.264 video, with AAC-LC or Opus audio, 48 kHz audio, progressive scan and a frame rate matching the source. Treat these as upload guidance, not a promise about processing time, playback quality or acceptance. YouTube converts uploaded videos for playback, and its processing can depend on file properties and traffic.
The sample command uses MP4 output by the .mp4 filename, H.264 through libx264, AAC through -c:a aac, and 48 kHz through -ar 48000. It does not specify a frame rate, so FFmpeg’s handling depends on the input and output path. Check the resulting file’s properties and preserve the source frame rate unless you have a specific reason to change it. If your inputs do not share a frame rate, choose a consistent output approach and inspect motion around transitions.
Progressive scan is the typical choice for contemporary relaxation footage. If your sources have interlaced video, decide how to handle it deliberately rather than assuming the output will be progressive simply because the extension is MP4. Resolution and bitrate should reflect the source and desired quality. YouTube publishes resolution-specific bitrate guidance, but there is no single rate to apply regardless of resolution and frame rate.
Do not add settings simply because they sound professional. A very high bitrate cannot restore detail absent from a low-resolution source, and a low bitrate may make gradients in a dim sky or water more visibly blocky. Make a short encode, inspect dark areas and moving textures, and adjust if the image shows visible artefacts. These checks are more useful than treating a command copied from another project as universally correct.
Check the finished file for gaps and audio
Play the exported file from beginning to end if practical, and always inspect the start, at least one internal playlist join, and the final section. Look for black frames, freezes, jumps in brightness, duplicated frames or a brief pause. Listen for silence where ambience should continue, clicks at audio boundaries, sudden level changes and audio that drifts away from the picture.
For a long relaxation upload, small imperfections can become a repeated interruption. A join that occurs once in the playlist will recur every cycle in an endless live loop or a longer finite export. If a gap is present in the source or is introduced by duration/timestamp differences, repeating the playlist repeats the problem; looping does not repair it. Return to the source durations and stream compatibility before encoding again.
Check the file’s reported duration and confirm it is the length you intended. A command can finish successfully while producing an unexpected endpoint due to an option placed in the wrong position or an input that did not repeat as expected. Review FFmpeg’s log for errors and warnings, then play the actual output rather than relying only on metadata.
For audio-heavy material, use headphones or speakers that make low-level noise and transitions audible. A phone speaker may hide a low hum or a click that remains obvious on other devices. The guide to fixing desynced audio in a 24/7 YouTube music stream is relevant if picture and sound gradually separate during longer playback; first confirm whether the offset already exists in the source or appears in the render.
Keep a known-good export separate from experiments. Use a new output filename for each test so you do not mistake an older file for the latest result. Once the file is checked, upload it and review YouTube’s processed playback as well, since the uploaded version is what viewers will receive.
Decide whether a long export is necessary
A long file is not the only way to provide continuous playback. YouTube’s player can loop an individual video, and its playlist controls can repeat a playlist. That approach leaves the original videos separate and avoids an encode, but it depends on viewer-side playback controls and does not create a single long asset.
A finite export is useful if you specifically need one long upload or one file for a scheduled workflow. It takes render time and storage, and each clip must be compatible or normalised through re-encoding. A player loop is simpler for someone watching on YouTube, but it is not a substitute for a continuous live channel or a new upload file.
| Need | Better fit | Main trade-off |
|---|---|---|
| Repeat one existing YouTube video | Player loop | No new file, but it repeats that video only |
| Repeat an existing YouTube playlist | Playlist repeat control | Keeps clips separate; it is playback control rather than a new export |
| Upload one longer relaxation video | Finite FFmpeg export | Requires a duration, checking and potentially a lengthy encode |
| Combine sources with differing streams | Normalise and re-encode | More processing, but stream-copy compatibility is not assumed |
If you plan to run a live channel from a finished recording, treat that as a further decision beyond the file export. The Windows Task Scheduler restart guide for a lofi stream covers a local-computer approach and its restart considerations. For a workflow where you want the uploaded file to run as a YouTube live stream without leaving your own computer on, StreamNeo removes that particular overnight-running burden; it is YouTube-only, and the source file still needs to be prepared and checked.
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 use -stream_loop -1 to create a file that ends?
It makes the input repeat indefinitely during processing; by itself, that does not specify a finite output. Add an output duration such as -t 02:00:00, or otherwise set a finite stopping condition, if you need a completed upload file.
Can I concatenate clips with different codecs or audio streams by copying them?
Do not assume so. The concat demuxer expects compatible streams, and mismatched layouts or parameters can fail or produce unreliable results. Normalise the sources and re-encode, or use a concat-filter workflow when inputs need conversion.
Why does a gap appear between clips?
The demuxer places later timestamps using file durations, so unequal audio and video lengths or inaccurate duration information can leave a gap. Inspect the relevant source boundaries and stream compatibility, then test a short render across the join before making the full export.
Do I need FFmpeg if I only want to replay a YouTube video?
No. YouTube provides loop controls for an individual video and for a playlist. FFmpeg is useful when you need a new, single, finite video file rather than viewer-side repetition.