186

I simply want to convert files, any format to any format (at the moment, I need to convert MKV to MP4-h264), without losing quality. I don't want to resize (scale) the video, I don't want to change its aspect ratio and I don't want it to lose quality (this is very important); all I want is "to change the format", that's all. Reason: my DVD player won't recognize any formats other than AVI or MP4. I don't care about file size, unless the difference between the input and the output files is absurdly huge. So, how do I do that?

I've already tried programs such as WinFF, Arista, Format Junkie, but their presets always change something which I don't want to be changed (size, aspec ratio, etc.). I'm not really sure, but I think the best way to get what I want is to go with the pure ffmpeg commands. But how?

By the way, Ubuntu 13.04 (64-bit), here. Thanks for your time, guys.

4
  • It seems to be interesting, vivid_vibe. I'll give it a try. Let's see what it can do. Thanks. :)
    – user229552
    Dec 28, 2013 at 17:42
  • Dumindu Mahawela, I followed the link you provided and came across this command: "avconv -i input.mkv -codec copy output.mp4". This worked like a charm for me. Thanks for your time. :)
    – user229552
    Dec 28, 2013 at 18:46
  • Post it as a answer here.
    – user224082
    Dec 29, 2013 at 3:58

2 Answers 2

301

If you only want to convert MKV to MP4 then you will save quality and a lot of time by just changing the containers. Both of these are just wrappers over the same content so the CPU only needs to do a little work. Don't re encode as you will definitely lose quality.

It's very straight forward using ffmpeg:

ffmpeg -i LostInTranslation.mkv -codec copy LostInTranslation.mp4

Here, you are copying the video codec and audio codec so nothing is being encoded.

Tip: To convert all MKV files in the current directory, run a simple loop in terminal:

for i in *.mkv; do
    ffmpeg -i "$i" -codec copy "${i%.*}.mp4"
done

For future conversions, like from AVI to MP4, check out HandBrake.

8
  • Sayem, I tried your suggestion, but got this result: "[mp4 @ 0x134da20] Application provided invalid, non monotonically increasing dts to muxer in stream 0: -2 >= -2 av_interleaved_write_frame(): Invalid argument". Anyway, I've got what I want with the following command: "avconv -i input.mkv -codec copy output.mp4" which is pretty similar to the one you suggested. Thanks a lot for your time. :)
    – user229552
    Dec 28, 2013 at 18:45
  • 1
    That for-loop dies when there are spaces in the file names ;-; Sep 26, 2014 at 10:54
  • 6
    And don't forget -movflags +faststart because mp4 sucks; without that, you can't play a partial file (where the end of the file isn't written yet). Jan 15, 2015 at 2:44
  • 2
    Windows users may need to add the -strict experimental flag after the input file for this to work: ffmpeg -i LostInTranslation.mkv -strict experimental -codec copy LostInTranslation.mp4. According to this bug report, the -strict option must be specified after the input file; otherwise, it will not recognize that you specified the option. That took me quite a while to find out.
    – Alexander
    Feb 18, 2019 at 8:20
  • 2
    @Alexander I am on Windows 10, did not use the -strict flag, and had no problems. FYI. In any case, the bug report is 9 years old and was closed 9 years ago.
    – Sabuncu
    Mar 21, 2020 at 15:10
17

Here is one you haven't tried. Handbrake

6
  • 2
    Never mind, TheHerk. I found the correct name of the package: handbrake-gtk. Installed it, but didn't like it. But thanks anyway. :)
    – user229552
    Dec 28, 2013 at 20:05
  • 2
    Handbrake is incapable of lossless video conversion, as specified in the OP's question. It has no "copy" option for video. It is only capable of transcoding, which will always cause a loss of quality. Apr 22, 2020 at 2:08
  • 1
    It may be true that handbrake doesn't have any lossless options, but the second statement is absolutely not true. You can convert from one data type to another without losing quality as long as the second can store more information that the first. video.stackexchange.com/a/21623
    – theherk
    Apr 23, 2020 at 17:30
  • 1
    Handbrake is slow as H3ll, use the below python script ... import os files = [f for f in os.listdir('.') if os.path.isfile(f)] for f in files: if 'mkv' in f: os.system('ffmpeg -i "' + str(f) + '" -codec copy "' + str(f).split('.mkv')[0] + '.mp4"')
    – PanDe
    Jun 6, 2021 at 6:56
  • 1
    @PanDe Generally bad practice to just plop strings directly into a command, so probably shouldn't suggest it to someone who might be unfamiliar with python; a better way would be to also import subprocess and use files = [ f for f in os.listdir() if os.path.isfile(f) and f[-4:] == '.mkv' ] followed by for f in files: subprocess.Popen([ 'ffmpeg', '-i', f, '-codec', 'copy', f[:-4] + '.mp4' ])
    – SliceThePi
    Sep 15, 2021 at 0:43

Not the answer you're looking for? Browse other questions tagged or ask your own question.