1. Overview

In this tutorial, we’ll dive into the conversion process of MKV (Matroska Video) to MP4 (MPEG-4 Part 14) with no or negligible loss of quality. First, we’ll discuss the differences between the two containers.

Then, we’ll have a hands-on approach to the actual conversion process through FFmpeg.

2. Why MP4 Over MKV?

MP4 and MKV are both popular container formats for storing video and audio files. However, there are some key differences between the two.

2.1. MP4

MP4 is probably the most popular video format based on the MPEG-4 standard. Apart from media tracks, it can also include subtitles and metadata.

In addition, it provides high compatibility with devices, operating systems, application software, and media players. Therefore, it’s the go-to choice for online streaming, video-sharing platforms, and mobile devices.

While MP4 may not be as flexible as MKV, they are far more efficient in terms of size and quality.

2.2. MKV

MKV is a flexible container format that can hold a wide range of audio, video, and subtitle tracks. Like MP4, it also contains metadata. Unlike MP4, MKV isn’t as popular because it falls short in terms of compatibility.

When the MKV format came out, most of the devices and software were highly optimized for MP4 playback. In addition, the MKV files contain a variety of codecs, which can lead to decoding issues on devices that might not support all the codecs used inside MKV files.

Moreover, the MKV files tend to be larger in size as compared to MP4 at a similar level of compression.

In the next sections, we’ll learn how to carry out the conversion of MKV to MP4 with no to minimal loss.

3. Converting MKV to MP4

We’ll carry out the process through FFmpeg, which can be installed from the official package repositories under its canonical name ffmpeg:

$ sudo apt install ffmpeg -y

Once installed, we’ll get three binaries: ffmpegffplay, and ffprobe. However, we’re interested in ffmpeg:

$ ffmpeg --version
ffmpeg version 5.1.2-3ubuntu1 Copyright (c) 2000-2022 the FFmpeg developers

3.1. Demo Clip

For our use case, we’ll process a 28-second MKV clip:

$ mediainfo --Inform="General" media.mkv
General
Unique ID                                : 295603423856445336919090671606321279870 (0xDE6326087A2ABA65DA17F2C0ECFA737E)
Complete name                            : media.mkv
Format                                   : Matroska
Format version                           : Version 4
File size                                : 16.6 MiB
Duration                                 : 28 s 237 ms
Overall bit rate                         : 4 939 kb/s
Writing application                      : Lavf57.83.100
Writing library                          : Lavf57.83.100
ErrorDetectionType                       : Per level 1

3.2. Lossless Conversion to MP4

It’s very straightforward to convert an MKV to MP4 with FFmpeg:

$ ffmpeg -i media.mkv -codec copy media.mp4

Let’s break this down:

  • -i specifes the input file media.mp4
  • -codec specifies the codec to use, which is copy in this case

Aptly, the copy option copies or “remuxes” the codecs inside the original container to the output container. As a result, it makes the process faster because there is no re-encoding to carry out.

In addition, the -codec encapsulates both the audio and video codecs. Conversely, we can specify individual codecs with -c:a and -c:v for video and audio, respectively.

Let’s take a look at the output detail:

$ mediainfo --Inform="General" media.mp4
General
Complete name                            : media.mp4
Format                                   : MPEG-4
Format profile                           : Base Media
Codec ID                                 : isom (isom/iso2/avc1/mp41)
File size                                : 16.6 MiB
Duration                                 : 28 s 236 ms
Overall bit rate                         : 4 941 kb/s
Writing application                      : Lavf59.27.100

Here, we can observe that the file size and bit rate remain the same, which implies that video stream quality is more or less the same.

Moreover, this method should work most of the time. However, there are a few caveats, which we’ll go over next.

3.3. Stream Selection

By default, when converting MKV to MP4, FFmpeg selects a single video stream for each type.

For instance, if we have two video streams in the MKV file, then FFmpeg selects the video stream that has a larger frame size. Similarly, for audio streams, FFmpeg selects the audio stream with index 0.

However, we can rectify this behavior by specifying -map 0 to FFmpeg:

$ ffmpeg -i media.mkv -codec copy -map 0 media.mp4

-map 0 essentially copies all the audio, video, and subtitle tracks from the MKV container to the MP4 container.

Conversely, we can also select individual streams. For instance, we can select the second stream from the MKV container to be copied to the output container:

$ ffmpeg -i media.mkv -map 0:a:1 media.mp4

Similarly, we can use 0:v:1 for selecting the second video track from the input stream:

$ ffmpeg -i media.mkv -map 0:a:1 -map 0:v:1 media.mp4

3.4. File and Codec Support

As we know, MKV supports a wide variety of codecs and file formats. However, it’s not true for MP4 containers. For instance, MP4 doesn’t natively support SubRip (.srt) subtitle format.

So, before conversion, we should first understand the formats that are supported by our target container. For instance, in the case of subtitles, we should first extract the .srt from the MKV container and convert this to an MP4-supported format like TTML and WebVTT. Next, we can embed the subtitle in the final MP4 output.

In the case of the audio and video streams, we might need to transcode them into MP4-supported formats like H.264 and AAC. Indeed, it can lose quality. However, it’s possible to transcode them in such a way that it’s not perceptible to most viewers:

$ ffmpeg -i media.mkv -c:v libx264 -crf 18 -c:a aac -b:a 128k -strict experimental media.mp4

Here’s the breakdown:

  • -c:v libx264 sets the codec for the video stream to H264
  • -crf 18 specifies CRF (Constant Rate Factor) value of 18 for the video stream, which is a good balance between quality and file size
  • -c:a aac and -b:a sets the codec and audio bit rate for the audio stream, respectively
  • strict experimental enables support for experimental codecs like AAC

The most interesting bit in the command is the CRF value. We can tweak this value to match our requirements. However, we should know that the lower the CRF value, the higher the file size.

As a final step, let’s check the details of the output:

$ mediainfo --Inform="General" media.mkv
General
Complete name                            : media.mp4
Format                                   : MPEG-4
Format profile                           : Base Media
Codec ID                                 : isom (isom/iso2/avc1/mp41)
File size                                : 22.2 MiB
Duration                                 : 28 s 237 ms
Overall bit rate                         : 6 609 kb/s
Writing application                      : Lavf59.27.100

Notably, the file size did go up along with the bit rate. We can improve this by setting the CRF value a bit higher.

4. Conclusion

In this article, we explored the conversion process from MKV to MP4. First, we learned the key differences between the MP4 and MKV containers. Then, we saw how we could carry out the conversion process using FFmpeg.

In the process, we also looked at a couple of edge cases like stream selection and codec support.