使用 ffmpeg 将 H.265 mkv 批量转换为 H.264,使文件兼容重新编码

The*_*ith 36 command-line ffmpeg batch h264

我有 H.265 编码的文件,这些文件非常占用资源,无法正常播放,而且我的转换软件 (mencoder)(当前)不支持 H.265 格式。我可以在命令行批处理文件中将它们转换为 H.264 以使用 Devede/OGMrip 快速转换文件以进行重新压缩吗?在搜索这个网站时,我没有发现它被讨论过,所以我会发布我认为有用的问题和问题的答案。

The*_*ith 40

是的,使用ffmpeg.

打开终端并将其定向到包含 H.265 编码文件的目录,假设您已经ffmpeg安装了适当的库并假设它们是 MKV 格式,请将以下内容复制并粘贴到终端窗口中。

INPUT="$1"
for i in *.mkv ; do
    ffmpeg -i "$i" -bsf:v h264_mp4toannexb -sn -map 0:0 -map 0:1 -vcodec libx264 "$i.ts"
    mv "$i.ts" "$i.mpg"
    sleep 3
done
Run Code Online (Sandbox Code Playgroud)

你有它。这将在同一目录中的 MPG 容器中转换为 h.264。

命令开关说明:

  • for i in *.mkv ; do ... done

    这将在要包含在批处理中的目录中设置所有 .mkv 文件。这可能会更改以适应您要处理的文件的容器扩展名。

  • ffmpeg -i "$i" 执行程序 ffm​​peg 并调用要处理的文件。

    • -bsf:v 激活要使用的视频比特流过滤器。

    • h264_mp4toannexb - 是被激活的比特流过滤器。

      将 H.264 比特流从长度前缀模式转换为起始码前缀模式(如 ITU-T H.264 规范的附件 B 中所定义)。

      这是某些流格式所要求的,通常mpegts处理 MKV h.264(当前)的 MPEG-2 传输流格式 ( ) 需要这样做,如果不包括在内,您将在终端窗口中收到一条错误消息,指示您使用它。

    • -sn 停止字幕流的流式传输(对于那些不想在视频中使用字幕的人)这是可选的,可以删除。

    • -map 0:0 -map 0:1告诉 ffmpeg 只处理文件的前两个流(0:0是视频流,0:1是文件的第一个音频流)。这做了两件事,去除多余的音频流,通常第一个音频流是英语,但并非总是如此。其他流(如嵌入字幕)被删除以减少文件大小。这也是一个可选字符串。您可以使用ffprobe来查看文件中可用的流。-map是可选的,可以从命令中丢弃。

    • -vcodec libx264 这告诉 ffmpeg 将输出编码为 H.264

    • "$i.ts" 将输出保存为 .ts 格式,这很有用,以免覆盖您的源文件。

  • mv "$i.ts" "$i.mpg"将文件扩展名转换为同一目录中的 MPG。这可以设置为将其发送到您喜欢的任何目录。

  • sleep 3 - 允许进程休息,让 ffmpeg 有时间将下一个文件排队

  • 考虑 [流复制](http://ffmpeg.org/ffmpeg.html#Stream-copy) 使用 `-c:a copy` 而不是重新编码的音频。此外,`0:0` 可能并不总是指视频,而 `0:1` 可能并不总是指音频。您可以使用流说明符来避免潜在问题:`-map 0:v -map 0:a` 如果您想要来自输入 0 的所有视频和音频流,或者 `-map 0:v:0 -map 0:a`: 0` 如果您只想要来自输入 0 的第一个视频和音频流。如果您只想要英文音频流:`-map 0:m:language:eng`(假设它被标记)。 (11认同)
  • 优秀!现在我们可以删除问题下方的评论。我会说 `sleep 3` 是不必要的(但可能对终止循环有用),而 `INPUT=$1` 是没有意义的,因为你直接在交互式 shell 中运行它。 (3认同)
  • 我完全会选择“ffmpeg -i $INPUT -vcodec h264 -acodec copy $OUTPUT”。我每天都使用并且实际上可以记住的东西,而不是每个 ffmpeg 答案都因无意义的标志而臭名昭著的弹幕。 (2认同)

llo*_*gan 22

H.265 到 H.264 的批量转换

这些示例是为最近编写的ffmpeg。为自己省去一些麻烦并下载最新版本。然后将ffmpeg二进制文件放入~/bin/usr/local/bin(您可能必须注销然后登录才能被注意到)。

Matroska 输出

mkdir h264vids
for f in *.mp4; do ffmpeg -i "$f" -map 0 -c copy -c:v libx264 -crf 23 -preset medium h264vids/"${f%.*}.mkv"; done
Run Code Online (Sandbox Code Playgroud)
  • 此示例将输出到名为h264vids.

  • 此示例假设您的输入为.mp4. 如果没有,请将.mp4示例中的实例更改为您的输入文件类型,或者仅使用 greedy*本身。

  • 调整-crf质量和-preset编码速度/效率。或者只是删除这些选项并使用相当好的默认值并且应该足够大多数(示例使用这些选项的默认值)。有关这些选项的更多信息,请参阅FFmpeg Wiki:H.264

MP4 输出

这个稍微复杂一点。这将根据输入音频是否为 AAC 执行条件编码。如果输入音频是 AAC,则音频将按原样进行流复制(重新混合),避免不必要的重新编码。如果输入音频不是AAC,那么它将被重新编码为 AAC。

这是一个简单的脚本,演示了如何使用ffprobe和执行此操作ffmpeg。将其复制并保存到包含要转换的视频的目录中,使用 授予它执行权限chmod +x yourscriptname,然后使用./yourscriptname.

#!/bin/bash

mkdir h264vids

for f in *.mkv
do
  audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
  if [ "$audioformat" = "aac" ]; then
    ffmpeg -i "$f" -c:v libx264 -crf 23 -preset medium -c:a copy -movflags +faststart h264vids/"${f%.*}.mp4"
  else
    ffmpeg -i "$f" -c:v libx264 -crf 23 -preset medium -c:a aac -movflags +faststart h264vids/"${f%.*}.mp4"
  fi
done
Run Code Online (Sandbox Code Playgroud)
  • 此示例将输出到名为h264vids.

  • 此示例假设您的输入为.mkv. 如果没有,请将.mkv示例中的实例更改为您的输入文件类型,或者仅使用 greedy*本身。

  • 请参阅上面关于-crf和 的注释-preset

  • 您可以使用ctrl+暂停编码z并使用 恢复fg