如何简单地转换视频文件(例如:MKV 转 MP4)?

我只是想转换文件,任何格式到任何格式(目前,我需要将MKV转换为MP4-h264),而不会损失质量。我不想调整视频的大小,也不想改变其宽高比,更不想让它失去质量(这非常重要);我只想“改变格式”,仅此而已。原因是我的DVD播放器只能识别AVI或MP4格式,其他格式都不行。我不在乎文件大小,除非输入和输出文件之间的差异非常巨大。那么,我该怎么做呢?
我已经尝试过WinFF、Arista、Format Junkie等程序,但它们的预设总是改变了我不想改变的东西(大小、宽高比等)。我不太确定,但我认为实现我想要的最好方法是使用纯粹的ffmpeg命令。但是如何操作呢?
顺便说一下,我使用的是Ubuntu 13.04(64位)。谢谢大家抽出时间帮助我。

关于http://www.noobslab.com/2013/06/ff-multi-converter-for-ubuntu.html 这个网址怎么样? - vivid_vibe
看起来很有趣,充满活力的氛围。我会试一试的。让我们看看它能做什么。谢谢。 :) - user229552
Dumindu Mahawela,我按照你提供的链接,并找到了这个命令:“avconv -i input.mkv -codec copy output.mp4”。对我来说,这个命令非常好用。感谢你的时间。 :) - user229552
在此将内容翻译为中文,仅以答案形式发布。 - user224082
2个回答

如果你只想将MKV转换为MP4,那么只需更改容器格式就能保留视频质量并节省大量时间。这两种格式只是对同一内容的封装,因此CPU只需要进行少量处理工作。不要重新编码,否则会明显降低视频质量。
使用ffmpeg非常简单:
ffmpeg -i LostInTranslation.mkv -codec copy LostInTranslation.mp4

在这里,你正在复制视频编解码器和音频编解码器,所以没有进行任何编码。
提示:要转换当前目录中的所有MKV文件,请在终端中运行一个简单的循环。
for i in *.mkv; do
    ffmpeg -i "$i" -codec copy "${i%.*}.mp4"
done

对于将来的转换,比如从AVI到MP4,请查看HandBrake


Sayem,我试了你的建议,但是得到了这个结果:“[mp4 @ 0x134da20] Application provided invalid, non monotonically increasing dts to muxer in stream 0: -2 >= -2 av_interleaved_write_frame(): Invalid argument”。不过,我用下面的命令得到了我想要的结果:“avconv -i input.mkv -codec copy output.mp4”,这个命令和你建议的相当类似。非常感谢你的时间。 :) - user229552
1当文件名中有空格时,那个for循环就会出问题了。;-; - EaterOfCode
11不要忘记加上-movflags +faststart,因为mp4格式很糟糕;如果没有这个选项,你将无法播放尚未完全写入的部分文件。 - Peter Cordes
为什么当我将MKV文件“重新封装”成MP4文件时,原始MKV文件中的字幕没有被传输过去呢? - oldboy
@Anthony:可能是因为FFmpeg命令没有包含转换字幕流的指令。我的更改(-codec copy)应该会解决这个问题,因为它们告诉FFmpeg复制所有遇到的数据流和编解码器。 - David Foerster
3Windows用户可能需要在输入文件后添加“-strict experimental”标志,以使其正常工作:“ffmpeg -i LostInTranslation.mkv -strict experimental -codec copy LostInTranslation.mp4”。根据此错误报告,必须在输入文件之后指定“-strict”选项;否则,它将无法识别您指定的选项。我花了相当长的时间才找到这个方法。 - Alexander
2@Alexander 我使用的是Windows 10,没有使用-strict标志,并且没有遇到任何问题。顺便说一下,这个错误报告已经有9年了,并且在9年前就已经关闭了。 - Sabuncu
太棒了。这刚刚为我节省了一个小时的转换时间。有没有办法让 ffmpeg 在任何转换中选择最快的选项?我想改变例如 .mov.mp4 可能需要不同的选项,而一个能猜测出最佳命令的指令将会非常棒。 - nicusor
不确定是否相关,但重写了这段代码以在Windows上运行:for %%f in (.\*.mkv) do ( ffmpeg -i "%%~nf.mkv" -codec copy "%%~nf.mp4" ) - FamousSnake
如果您的视频有多个音轨,请添加选项“-map 0”。否则,这将只复制第一个音轨。 - Michael Yaworski
天哪,我在没有得知这个之前已经把我的 CPU 毫不留情地炸了很多个小时。 - max pleaner

这是一个你还没有尝试过的。Handbrake

TheHerk,我无法安装它。添加了PPA,更新了源,尝试安装“handbrake”软件包,但它说没有这样的软件包可供安装。真是让人费解! - user229552
3没关系,TheHerk。我找到了正确的软件包名称:handbrake-gtk。已经安装了,但是不喜欢它。无论如何还是谢谢你。 :) - user229552
2Handbrake无法进行无损视频转换,正如OP的问题所指明的那样。它没有视频的“复制”选项。它只能进行转码,这将始终导致质量损失。 - Kurt Fitzner
1可能事实是手刹没有无损选项,但第二个说法绝对不正确。只要第二个数据类型能够存储比第一个更多的信息,您就可以在转换时不损失质量。https://video.stackexchange.com/a/21623 - theherk
1手刹太慢了,用下面的Python脚本...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
1@PanDe 通常不推荐直接将字符串放入命令中,所以对于可能对Python不熟悉的人来说,不应该建议这种做法;更好的方式是导入subprocess并使用files = [ f for f in os.listdir() if os.path.isfile(f) and f[-4:] == '.mkv' ],然后使用for f in files: subprocess.Popen([ 'ffmpeg', '-i', f, '-codec', 'copy', f[:-4] + '.mp4' ]) - SliceThePi