![批量转换 .mkv 为 .mp4](https://linux22.com/image/1319593/%E6%89%B9%E9%87%8F%E8%BD%AC%E6%8D%A2%20.mkv%20%E4%B8%BA%20.mp4.png)
我想使用 VLC 将文件夹中的所有 .mkv 文件批量转换为 .mp4。
它应该使用原始视频/音频流,如果可能的话,还应该使用 .mkv 的 .ass 字幕。这实际上不是转换,更像是更改容器——我的播放器无法读取 MKV 视频。
如果我手动进行此转换,它可以工作,但我有很多 MKV 文件需要转换,因此这将花费很多时间。
我在网上搜索了批处理文件来执行此操作,并找到了几个。我尝试根据自己的意愿进行修改,但我尝试的所有尝试都只是创建了一个不包含音频流的 .mp4 文件,并且 PC 上的所有媒体播放器也无法呈现视频流。
那么有人可以告诉我批次应该是什么样子,以便它可以与原始视频和音频流(也许还有 .ass 字幕)一起工作吗?
答案1
mkvtomp4
好像mkvtomp4
是你想要的吗?
使用 mpeg4ip 或 GPAC 的 MP4Box、mkvtoolnix 和 ffmpeg 来将麻烦的 mkv 文件转换为 mp4. 转换不会对视频重新编码并且仅当不使用 AAC 编解码器时才重新编码音频(可以使用 --audio-codec 覆盖此行为)。
您可以在 Google Code 页面上下载 Windows 和 Linux 版本。不过,您还需要其他软件。
访问网站获取适用于 Windows 或 Linux 的下载。在 OS X 上,你只brew install mkvtoolnix mp4box
需要自制。
但这不会复制您的字幕。您还需要执行额外的步骤。
FFmpeg 批处理
如果 mkvtomp4 不适合您,一个简单的FFmpeg批处理文件也可以做到。
安装 ffmpeg(例如通过自制或选项https://ffmpeg.org/download.html)然后,只需调用:
ffmpeg -i input.mkv -c:v copy -c:a copy output.mp4
这将创建一个有效的 MP4 容器,无需重新编码。根据需要循环遍历文件并由您的操作系统提供。但是,此批处理不会复制字幕。
在 *nix 中,你可以执行以下操作。只需创建一个文件convert.sh
:
#!/bin/bash
find /path/to/input/folder -iname '*.mkv' -print0 | while read -d '' -r file; do
ffmpeg -i "$file" -c:v copy -c:a copy ${file%%.mkv}.mp4
done
在此处替换视频文件夹的路径。使用 使其可执行chmod +x convert.sh
,然后使用 运行它./convert.sh
。
在 Windows 中,您可能需要两个批处理文件(来自这里的无耻插件),其中之一就是startconvert.bat
:
for %%i IN (*.mkv) DO (convert-to-mp4.bat "%%i")
pause
并执行转换:
IF EXIST "%1.mp4" GOTO exit
@echo Conversion for %1 started on %DATE% %TIME%
ffmpeg -i %1 -c:v copy -c:a copy %1.mp4
:exit
@echo %1.mp4 already exists
将两者保存在视频文件夹中。只需startconvert.bat
从要开始转换的文件夹运行即可。
字幕
如果您想添加字幕,如果以下方法不适合您,您可能需要手动操作:
ffmpeg -i input.mkv -c:a copy -c:v copy -map 0 output.mp4
要提取字幕,请使用:
mkvextract tracks input.mkv 3:subtitles.srt
这是假设您的文件确实包含轨道 ID 号 3 处的字幕,并且可以将其导出为 SRT 格式。要检查文件是否确实包含轨道 3 处的字幕,请使用mkvmerge -i input.mkv
。
然后,使用MP4Box将字幕重新添加到MP4文件。
mp4box -add input.mp4 -add subtitles.srt -new output.mp4
答案2
这是对 slhck 给出的部分答案的调整(感谢 slhck!)因为我发现该命令对最新的(在撰写本文时)ffmpeg 不起作用——也许参数在不同版本之间发生了变化?
在 Windows 7 上,使用ffmpeg v.20130103-git-9e36d9e-win64-静态(使用 7zip 实用程序解压缩),通过以下方式找到http://ffmpeg.zeranoe.com/builds/反过来通过http://ffmpeg.org/download.html,以下命令将 .mov 文件(取自 iPhone)转换为 .mp4 文件:
ffmpeg -i test.mov -vcodec copy -acodec copy test.mp4
我发现将 .mp4 部分更改为 .avi 也有效,可以将其更改为 .avi 容器。对于任何目标容器,使用这些“-vcodec copy -acodec copy”参数似乎只会将源流复制到新容器(在目标中),因此这是无损转换(我猜各种目标容器也是如此)。
slhck 给出的这些批次的调整对我也有用:
调用转换脚本:
for %%i IN (*.mov) DO (convert.bat "%%i")
pause
转换.bat:
IF EXIST %1.mov GOTO exit
@echo Conversion for %1 started on %DATE% %TIME%
ffmpeg -i %1 -vcodec copy -acodec copy %1.avi
:exit
@echo %1.avi already exists
答案3
这是一个老问题,但这是我的答案,仅供参考。MP4 不能制作字幕,除非它们是视频帧的一部分,但这是我将 .mkv 文件转换为 .mp4 的方法:
foreach($inputFile in get-childitem -recurse -Filter *.mkv) {
$outputFileName = [System.IO.Path]::GetFileNameWithoutExtension($inputFile.FullName) + ".mp4";
$outputFileName = [System.IO.Path]::Combine($inputFile.DirectoryName, $outputFileName);
$progDir = ${env:ProgramFiles(x86)};
if ($progDir -eq $null) {
$progDir = $env:ProgramFiles;
}
$processName = $progDir + "\VideoLAN\VLC\vlc.exe";
$processArgs = "-I dummy -v `"$($inputFile.FullName)`" --sout=#transcode{}:standard{access=`"file`",mux=`"mp4`",dst=`"$outputFileName`"} vlc://quit"
start-process $processName $processArgs -wait
}
将其另存为 mkv2mp4.ps1 并将其放入您正在使用的文件夹中。右键单击并“在 Powershell 中打开”,它就会执行操作。
这是我第一次查看 Powershell(我希望也是最后一次 - 为什么 MS 不能直接移植 Bash?!)但它对我有用,并且基于我在此处找到的代码:https://wiki.videolan.org/How_to_Batch_Encode/#Powershell