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


31

我的H.265编码文件占用大量资源,因此无法正常播放,而且我的转换软件(编码器)不(当前)不支持H.265格式。我可以在命令行批处理文件中将它们转换为H.264,以使用Devede / OGMrip快速转换文件以进行重新压缩吗?在搜索该站点时,我没有找到讨论的内容,因此我将发布我认为有用的问题并回答该问题。

Answers:


37

是的,使用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

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

命令开关的说明:

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

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

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

    • -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有时间将下一个文件排队


3
优秀!现在,我们可以删除问题下方的评论。我想说这sleep 3是不必要的(但对于终止循环可能很有用),并且INPUT=$1没有意义,因为您是直接在交互式shell中运行它的。
muru

11
考虑使用流复制音频-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(假设它被标记)。
llogan

1
@LordNeckbeard,我将投票给您,以写出完整的答案。
Fran Marzoa

1
@Fran没有注意到有太多关于该评论的投票。我使用更简单,更不易出错且更有效的方法添加了答案
llogan

1
我完全愿意ffmpeg -i $INPUT -vcodec h264 -acodec copy $OUTPUT。我每天都会用到的东西,实际上可以记住,而不是像每个ffmpeg答案那样臭名昭著的无意义的标志。
本·辛克莱

20

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
  • 本示例将输出到名为的目录h264vids

  • 本示例假定您的输入为.mp4。如果不是,请将.mp4示例中的实例更改为您的输入文件类型,或者仅使用贪婪*本身。

  • 调整-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
  • 本示例将输出到名为的目录h264vids

  • 本示例假定您的输入为.mkv。如果不是,请将.mkv示例中的实例更改为您的输入文件类型,或者仅使用贪婪*本身。

  • 有关-crf和的信息,请参见上面的注释-preset

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


0

考虑到先前的答案,我提出了以下内容:

for file in *265.mkv; do nice -n19 ffmpeg -i $file -c copy -c:v libx264 ${file/%265.mkv/264.mkv}; done

假设文件的名称始终以结尾265.mkv。此结尾将替换为264.mkv

如果文件命名不同,则需要相应地调整命令。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.