Skip to content
streamneo.
Streaming Settings14 min read

How to Stream Mixed MP4 and MKV Files to YouTube with an FFmpeg Playlist

Learn how to inspect MP4 and MKV streams, build an FFmpeg concat playlist, choose stream copy or transcoding, and prepare YouTube Live output.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

Use FFmpeg’s concat demuxer to read MP4 and MKV files sequentially, then send the resulting stream to YouTube. The important test is not the file extension: compare the contained streams first, because files with different containers may work together and files with the same extension may not.

If the streams do not match closely enough, make them consistent before building the final playlist. Use stream copy only when the codecs, time bases, stream layout and output container are suitable; -c copy does not repair incompatibilities.

Why MP4 and MKV extensions are not enough

MP4 and MKV are containers. They are wrappers that hold video, audio, subtitles, metadata and timing information. The extension tells you which wrapper is being used, but it does not tell you whether the video and audio inside two files can be joined without re-encoding.

For example, an MP4 file may contain H.264 video and AAC audio at 1080p, while an MKV file may contain H..265 video and Opus audio at 720p. The containers are only part of the difference. The codecs, dimensions, frame rates, pixel formats, channel layouts, time bases and other stream details also differ.

The reverse can happen too. An MP4 and an MKV can contain compatible H.264 video and AAC audio, with matching dimensions and timing. In that case, the mixed extensions are not automatically a problem. FFmpeg still has to read the files and the selected output muxer must be able to carry the resulting streams.

The concat demuxer works by reading one file after another as though they form a single input. FFmpeg’s documentation states that all files must have the same streams, including the same codecs and time bases. That requirement is why a playlist should be treated as the final stage of preparation, not as a tool for making unrelated files compatible.

A useful workflow is:

  1. Inspect every file.
  2. Group files that share a suitable profile.
  3. Normalise or transcode the outliers.
  4. Build the concat list from the prepared files.
  5. Test the complete output before using it for an overnight or 24/7 channel.

This is different from simply placing every file in a text file and hoping the output remains stable. If you are building a longer pre-recorded channel, the practical considerations in how to stream multiple videos continuously with FFmpeg concat are useful, but the same stream-compatibility check still applies.

Inspect streams, codecs and time bases

Use ffprobe, which is normally installed with FFmpeg, to inspect each input. A compact summary can show the information that matters for comparison:

ffprobe -v error \
  -show_entries stream=index,codec_type,codec_name,profile,width,height,pix_fmt,r_frame_rate,avg_frame_rate,time_base,sample_rate,channels,channel_layout \
  -of default=noprint_wrappers=1 \
  clip-one.mp4

Run the same inspection for every MP4 and MKV file. You do not need to memorise every field. Put the results side by side and look for differences in the following areas.

Property Video question Audio question Why it matters
Stream layout Does every file have the same video stream arrangement? Does every file have the same number and type of audio streams? The demuxer expects a consistent stream layout.
Codec Are the video codecs the same? Are the audio codecs the same? Different codecs normally require transcoding for a common output.
Dimensions and pixel format Are width, height and pixel format consistent? Not usually applicable A change can cause problems when copying packets or switching profiles.
Frame rate and time base Do frame-rate values and time bases align? Are audio sample rates and timing consistent? Timestamp changes can produce glitches, drift or failed concatenation.
Audio parameters Not usually applicable Do sample rate, channel count and channel layout match? Audio may fail or behave unevenly when layouts change.
Duration metadata Is the reported duration plausible? Is the reported duration plausible? Incorrect duration information can create timestamp gaps or overlaps.

The exact output varies by FFmpeg version and by the file. A file can also contain extra streams such as a second language track, commentary, subtitles or attached images. Two files that both show H.264 video and AAC audio may still differ in stream count or mapping.

Pay particular attention to codec_name, profile, width, height, pix_fmt, r_frame_rate, avg_frame_rate, time_base, sample_rate, channels and channel_layout. If one file has stereo AAC and another has five-channel audio, they do not present the same audio stream even if both use AAC.

You can inspect the container and format as well:

ffprobe -v error \
  -show_entries format=format_name,duration,size \
  -of default=noprint_wrappers=1 \
  clip-one.mkv

Do not use this second command as a compatibility test by itself. It tells you about the wrapper and basic file metadata, while the stream inspection tells you what the concat demuxer must handle.

A practical decision rule is simple. If every file has the same intended video and audio streams, with matching technical parameters, test the demuxer. If there is a meaningful mismatch, prepare the files into a common profile before you rely on the playlist.

Build a concat-demuxer file list

The concat demuxer reads a plain-text script. Create a UTF-8 text file such as playlist.txt:

file '/media/clip-one.mp4'
file '/media/clip-two.mkv'
file '/media/clip-three.mp4'

The order is the order in which FFmpeg will read the files. Use one file line per input. Paths containing spaces can be quoted, as in the example. Follow the syntax documented for your installed FFmpeg version rather than copying a list that uses unrelated shell quoting rules.

For a simple local playlist, an input command begins like this:

ffmpeg -re -f concat -safe 0 -i playlist.txt ...

Here, -f concat selects the concat demuxer. -re asks FFmpeg to read the input at approximately its native rate rather than sending a pre-recorded file as quickly as the machine can process it. -safe 0 permits paths outside FFmpeg’s restricted safe subset. Use it only with a playlist you created or otherwise control, because the list can point to local files.

Absolute paths are convenient on a personal machine, but they make a playlist less portable. Relative paths can be easier to move between folders if the files and the list have a predictable layout. Whichever approach you choose, test the list from the same working directory and user account that will run the live process.

The list is not a conversion step. It does not make an MKV file look like an MP4 file, change H.265 into H.264, turn Opus into AAC, or align different time bases. If the source files are not suitable for one logical input, changing the text file will not solve the underlying issue.

When a file has an unusual path or metadata, first test a short list containing only two representative files. This narrows the cause if FFmpeg reports a parsing error, timestamp problem or stream mismatch.

Test whether the files are compatible

Before connecting the command to a public broadcast, test the playlist locally. Start with a short section of the content and observe whether the transition between files is clean. Listen for missing audio, sudden changes in channel layout, frozen video, timestamp warnings and unexpected jumps in duration.

A diagnostic test can write to a local output instead of YouTube. For example, if the files are already prepared for a suitable MP4 output, you might test with:

ffmpeg -re -f concat -safe 0 -i playlist.txt \
  -map 0:v:0 -map 0:a:0 \
  -c copy -t 00:10:00 test-output.mp4

This is only a compatibility test, not a universal command. test-output.mp4 must be able to carry the copied streams, the input must expose the requested video and audio streams, and your installed FFmpeg build must support the selected options. If the sources contain additional streams, explicit mapping helps you choose the intended ones, but it does not resolve incompatible codecs or timing.

Read the console output carefully. A warning is not automatically harmless just because FFmpeg continues running. Look for non-monotonic timestamps, invalid durations, missing streams, packets that cannot be written to the output container, and audio or video that stops at a transition.

Test representative content, not only the easiest clip. Include a file with quiet audio, a file with speech or music, fast movement if your channel contains it, and the longest or most unusual item. A devotional channel might test a bhajan with continuous audio and a still-image video, while a local news loop might test a clip with speech, graphics and several scene changes.

Once the local output is stable, test the actual YouTube route privately or with the visibility and account settings appropriate to your channel. YouTube’s encoder guidance recommends testing before going live and monitoring stream health. The FFmpeg bitrate and keyframe checklist for YouTube Live can help you organise that test, but use YouTube’s current Live Control Room guidance for the final settings.

A clean first file does not prove that the whole playlist is safe. The failure may occur only when the second or third file begins, so leave the test running across several transitions.

Use stream copy when streams match

Stream copy passes encoded packets through without decoding, filtering or encoding them. It is attractive for a long playlist because it avoids the processing and quality changes associated with a new encode. In FFmpeg, the usual option is -c copy.

A simplified output shape might look like this:

ffmpeg -re -f concat -safe 0 -i playlist.txt \
  -map 0:v:0 -map 0:a:0 \
  -c copy -f flv "OUTPUT_URL_AND_KEY"

Treat this as a structure to adapt, not a guaranteed complete command. The correct output format, protocol, stream mapping and codecs depend on your FFmpeg build, source streams and YouTube configuration. The output URL and key should come from YouTube Studio, and the key should be treated like a password.

Stream copy is appropriate only when the files present compatible streams and the destination container can carry those streams. It cannot filter frames, resize video, change a frame rate, convert audio channels or repair timestamps by itself. If one file uses a different video codec or lacks the audio stream mapped from the first file, -c copy may fail or produce a stream that is unsuitable for the intended output.

It is also possible for a command to start successfully and still be a poor live test. A container may accept packets at the beginning and reveal a problem at a later transition. That is why the local multi-file test and YouTube stream-health test are both necessary.

Compare the trade-offs before choosing this route:

Choice Main benefit Main limitation Suitable when
Stream copy Low processing load and no decode/re-encode quality loss Cannot repair mismatches or apply filters Every input has a common, tested profile and the output muxer supports it
Transcode each file first Produces a predictable common profile Takes time and requires enough processing capacity Files differ in codec, dimensions, frame rate or audio parameters
Concat filter with re-encoding Can combine inputs after decoding and apply transformations More complex and requires encoding during the run You need scaling, filtering or per-input preparation in one FFmpeg graph

For a small computer that is already close to its processing limit, stream copy may be appealing. For a playlist assembled from files collected over several years, normalising them first can be the less fragile choice even though it takes more preparation.

Normalise or transcode incompatible files

When inspection finds mismatches, create consistent working files before making the final playlist. A normalised profile might specify one video codec, one resolution, one frame rate, one pixel format, one audio codec, one sample rate and one channel layout. Choose the profile for the channel and the YouTube ingest settings you intend to use.

For example, a preparation command could resemble this:

ffmpeg -i source.mkv \
  -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" \
  -r 30 -pix_fmt yuv420p \
  -c:v libx264 -preset medium -b:v 8M \
  -c:a aac -ar 48000 -ac 2 -b:a 128k \
  prepared-source.mp4

This is an example of a possible 720p preparation profile, not a promise that it suits every source, connection or YouTube channel. Check the capabilities of your installed FFmpeg build and adjust the video bitrate, frame rate, audio settings and scaling policy to the content. If your inputs are already 1080p or have a different purpose, use a profile that reflects that choice.

Do not blindly stretch a vertical or square source to fill a widescreen frame. Decide whether to preserve the aspect ratio with padding, crop the image, or keep a different output layout. A devotional image, classroom slide or local-news graphic may contain text near the edges, so inspect the result rather than assuming the scale filter made the correct editorial choice.

Prepare every incompatible item, not just the first file. Then inspect the prepared outputs again and build a new playlist from those outputs:

file '/media/prepared/clip-one.mp4'
file '/media/prepared/clip-two.mp4'
file '/media/prepared/clip-three.mp4'

A concat filter is another route when you need to decode, scale, pad, resample or otherwise transform inputs during one FFmpeg process. It is more flexible than the concat demuxer, but it also means encoding is part of the live or preparation workflow. FFmpeg’s documentation distinguishes this filter-based approach from the demuxer’s stream-copy-oriented use.

If a file has damaged timestamps, missing metadata or a broken stream, do not assume transcoding will make the content correct. First determine whether the source itself needs repair or replacement. A normalised file that still contains silence, clipped audio or a bad final frame will carry those content problems into the playlist.

For a recurring channel, keep the prepared files in a separate folder and retain a note of the profile used. This avoids rebuilding the same source every time and makes it easier to identify which item needs replacement when the playlist changes.

Apply YouTube Live encoder guidance

YouTube’s current live-encoder guidance for RTMP and RTMPS lists H.264, H.265 and AV1 video, and AAC or MP3 audio. It also specifies constant bitrate encoding and recommends a two-second keyframe interval that should not exceed four seconds. These are YouTube-published recommendations, not a guarantee that a particular FFmpeg command or network connection will be accepted or remain healthy.

For H.264, YouTube’s table lists these examples: 1080p at 30 frames per second with 14 Mbps recommended and 5 Mbps minimum; 1080p at 60 frames per second with 17 Mbps recommended and 6 Mbps minimum; and 720p at either 30 or 60 frames per second with 8 Mbps recommended and 3 Mbps minimum. YouTube also recommends 128 Kbps stereo audio, square pixels, progressive scan and Rec. 709 for SDR. Check the complete official YouTube live encoder settings before configuring a broadcast, because guidance and available options can change.

The bitrate table is not a measure of what your broadband connection can sustain. Leave room for ordinary network variation and test the actual upload route. A connection that briefly reaches a target bitrate may still produce dropped frames if it cannot maintain that rate during a long broadcast.

In YouTube Studio, copy the selected stream URL and stream key into the encoder configuration. YouTube explains the live-stream setup and key workflow in its official live streaming help. Do not paste the key into a public script repository, screenshot or support message. Reset it if you believe it has been exposed.

The output container and protocol must match the configuration you selected. A conventional H.264 and AAC route in an FLV output is common, but confirm that the codecs, muxer and protocol supported by your FFmpeg build match the current YouTube instructions. Do not infer compatibility from the source extension or from a command copied from a different machine.

If maintaining a local encoder overnight is the part that repeatedly fails, StreamNeo removes the need to keep your own computer running after you upload the prepared video, provide the YouTube stream key and start the channel; it also monitors the broadcast and restarts it automatically if it drops.

For a 24/7 setup, document the playlist path, the FFmpeg version, the output profile and the YouTube settings. Watch stream health after each material change. If the broadcast stops, the guide to recovering a YouTube live stream after a dropped connection covers the operational checks, while how to automate a 24/7 YouTube stream with FFmpeg in India discusses the wider local-machine workflow.

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 mix MP4 and MKV in an FFmpeg concat list?

Yes, but the extensions do not establish compatibility. Inspect the streams inside each file and confirm that the codecs, stream layout, time bases and other relevant parameters form a common profile before relying on the concat demuxer.

Do I need to re-encode every file before streaming it to YouTube?

No. If the streams match and the selected output container supports them, stream copy may be suitable. Re-encode or otherwise normalise the files when their codecs, dimensions, timing or audio parameters differ, or when you need filtering and format conversion.

Does -c copy fix an incompatible playlist?

No. Stream copy copies packets without decoding or changing them. It cannot make H.265 become H.264, convert Opus to AAC, align different stream layouts or apply a scale filter.

Should I test the playlist before using it for a 24/7 channel?

Yes. Test across several file transitions with representative audio and motion, then test the actual YouTube ingest path and monitor stream health. A command that starts correctly can still fail when a later file introduces different timing or stream parameters.

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 Streaming Settings guides ↗ · All topics ↗