使用 ffmpeg 和/或 python 进行 2 遍批量视频编码

使用 ffmpeg 和/或 python 进行 2 遍批量视频编码

我有一大堆视频文件,想在 Windows 机器上将它们编码为较小的文件。

我想使用 4K 恒定视频比特率并复制音频。我决定使用 2-pass FFmpeg 来获得最佳质量的视频,使用这个特定的比特率,并且我编写了一个可以工作的批处理文件,除非有多个视频需要转换:

for %%a in (*.mp4 *.mkv) do ffmpeg -y -i ^"%%a^" -c:v libx264 -b:v 4000k -preset fast -pass 1 -an -f mp4 NUL && ^

for %%a in (*.mp4 *.mkv) do ffmpeg -i ^"%%a^" -c:v libx264 -b:v 4000k -preset fast -pass 2 -c:a copy ^"converted/%%~na.mp4^"
  • 当我向目录添加其他视频文件时,此命令会尝试对每个视频运行第一遍,删除之前的第一遍,然后再对所有视频进行第二遍,从而违背了两次运行的目的。

我对 Python 还比较陌生,但我认为通过 Python 实现这一点可能会更容易。

答案1

Windows 10 64 位

使用 cmd 和 ffmpeg 进行 2 次视频编码,使用 4K 恒定视频比特率并复制音频。

下载 1MB 样本 .mkv 文件appsloveworld.com-示例视频_1280x720_1mb.mkv

命令:

if not exist converted (md converted)
for %g in (*.mp4 *.mkv) do (
ffmpeg -y -i "%g" -c:v libx264 -b:v 4000k -preset fast -pass 1 -an -f mp4 NUL
ffmpeg -i "%g" -c:v libx264 -b:v 4000k -preset fast -pass 2 -c:a copy "converted\%~ng.mp4"
)
rem delete ffmpeg temp files
del ffmpeg2pass*
exit /b 

脚本:

if not exist converted (md converted)
for %%g in (*.mp4 *.mkv) do (
ffmpeg -y -i "%%g" -c:v libx264 -b:v 4000k -preset fast -pass 1 -an -f mp4 NUL
ffmpeg -i "%%g" -c:v libx264 -b:v 4000k -preset fast -pass 2 -c:a copy "converted\%%~ng.mp4"
)
rem delete ffmpeg temp files
del ffmpeg2pass*
exit /b 

两遍批量转换 .mp4 和 .mkv 使用 cmd 和 ffmpeg 两遍批量转换 .mp4 和 .mkv。

答案2

如果有人正在寻找完整的 Python 实现:

import ffmpeg

def abr_vbr_1st_pass(inputPath, params):

    params.update({
                    'maxrate': params['b:v'],
                    'bufsize': params['b:v'] * 2,
                    'pass': 1,
                    'f': 'null'
                    })
    ffInput = ffmpeg.input(inputPath)
    ffOutput = ffInput.output('pipe:', **params)
    ffOutput = ffOutput.global_args('-loglevel', 'error')
    std_out, std_err = ffOutput.run(capture_stdout=True)

    return params

def abr_vbr_2nd_pass(inputPath, outputPath, params):

    params.update({
                    'pass': 2,
                    'f': 'mp4'
                    })
    ffInput = ffmpeg.input(inputPath)
    ffOutput = ffInput.output(
                              outputPath,
                              **params
                              )
    ffOutput = ffOutput.global_args('-loglevel', 'error')
    ffOutput.run(overwrite_output=True)

intputPath = '/path/to/source/media.mkv'
outputPath = '/path/to/output/media.mp4'

params =    {
            'threads': 4,
            'c:v': 'libx264',
            'c:a': 'copy',
            'f': 'mp4',
            'b:v': 3000000
            }

params = abr_vbr_1st_pass(inputPath, params)
abr_vbr_2nd_pass(inputPath, outputPath, params)

相关内容