批量转换 .mkv 为 .mp4

批量转换 .mkv 为 .mp4

我想使用 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

相关内容