使用ffmpeg批量转码倒放视频,转换视频为720p分辨率

⌚Time: 2024-07-18 10:46:00

👨‍💻Author: Jack Ge

把指定目录的所有视频倒放


setlocal

set "input_folder=%1"  // 输入目录参数

if "%input_folder%"=="" (
    echo 请指定输入目录!
    exit /b
)

mkdir %input_folder%\reversed

for /r "%input_folder%" %%G in (*) do (
    ffmpeg -i "%%G" -vf reverse -af areverse -threads 1 "%input_folder%\reversed\%%~nG_reverse.mp4"
)

echo 完成任务!

endlocal

在当前目录下把所有视频转码为720p

for /r "./" %%G in (*) do (
    ffmpeg -i "%%G" -vf scale=1280:720 "%%~nG_720p.mp4"
)

我发现有时候如果原始视频并不是标准的1280:720比例,这样转码后会进行缩放导致画面不协调

可以加上一个参数:force_original_aspect_ratio= 。这个参数是用来控制视频在缩放时如何保持原始宽高比。

三个选项对比

参数 行为 结果
decrease 选最小缩放比例 视频完整显示在框内,可能有黑边
increase 选最大缩放比例 视频填满框,可能被裁剪
不设置 直接拉伸到目标尺寸 视频填满框,可能变形

比如:

ffmpeg -i input.mp4 -vf "scale=1280:720:force_original_aspect_ratio=decrease" -c:v libx264 -c:a aac output.mp4

具体逻辑:

  1. 计算原始视频的宽高比
  2. 分别计算"宽度缩放到1280"和"高度缩放到720"的缩放比例
  3. 选择较小的那个比例(所以叫 decrease = 减小/缩小)
  4. 这样视频刚好完全显示在目标框内,不会溢出

如果原始视频并非标准比例: 1000x800,目标720p是 1280x720(横屏):

视频完整显示在720p框内,左右有黑边。

一般就设置force_original_aspect_ratio=decrease:保留画面比例缩放,宁可留黑边也不裁画面。

但是我后来又发现一个问题。就是ffmpeg有时候会转码时报错退出

Press [q] to stop, [?] for help
[swscaler @ 0x7f1bcc011c00] deprecated pixel format used, make sure you did set range correctly
[libx264 @ 0x5564764e9440] width not divisible by 2 (405x720)
[vost#0:0/libx264 @ 0x55647653cb80] Error while opening encoder - maybe incorrect parameters such as bit_rate, rate, width or height.
[vf#0:0 @ 0x55647653ca40] Error sending frames to consumers: Generic error in an external library
[vf#0:0 @ 0x55647653ca40] Task finished with error code: -542398533 (Generic error in an external library)
[vf#0:0 @ 0x55647653ca40] Terminating thread with return code -542398533 (Generic error in an external library)
[vost#0:0/libx264 @ 0x55647653cb80] Could not open encoder before EOF
[vost#0:0/libx264 @ 0x55647653cb80] Task finished with error code: -22 (Invalid argument)
[vost#0:0/libx264 @ 0x55647653cb80] Terminating thread with return code -22 (Invalid argument)
[out#0/mp4 @ 0x5564764eed00] Nothing was written into output file, because at least one of its streams received no packets.
frame=    0 fps=0.0 q=0.0 Lsize=       0KiB time=N/A bitrate=N/A speed=N/A    
[aac @ 0x556476537540] Qavg: 2622.238
Conversion failed!

这个错误的意思是:视频宽度(405像素)不是偶数,导致x264编码器无法处理。H.264编码器(特别是yuvj420p像素格式)要求视频宽度和高度都必须是偶数(能被2整除)。如果视频宽度最后计算得到是405,奇数,所以编码器直接报错退出。

使用force_original_aspect_ratio=decrease参数自动宽高的时候,如果是计算出奇数它不会自动取偶,就会发生这个错误。

解决办法是让scale自动取偶数,在 scale 参数里用 -2 代替具体宽高值,FFmpeg会自动计算并确保是偶数。比如高度固定720,宽度自动根据比例计算:

ffmpeg -i input.mp4 -vf "scale=-2:720,format=yuv420p" -c:v libx264 -c:a aac output.mp4

如果需要自动分辨是横屏还是竖屏的视频并转化成720p,可以设置横屏宽1280。竖屏高1280。宽高自动计算:

ffmpeg -i input.mp4 -vf "scale='if(gte(iw,ih),1280,-2)':'if(gte(iw,ih),-2,1280)',format=yuv420p" -c:v libx264 -c:a aac output.mp4