ffmpeg转码脚本


1. Windows 增强版脚本 (convert.bat)

代码段

@echo off
:: 开启变量延迟扩展,确保在 for 循环中能动态更新和读取变量(如 !dur! 和 !fade_st!)
setlocal enabledelayedexpansion

:: ================= 配置区 =================
:: ORI_DIR: 存放相机原始大码率素材的路径
set "ORI_DIR=D:\downloads\ffmpeg\video-ori"
:: OUT_DIR: 处理后用于上传 VPS 且符合 YouTube 直播规范的瘦身素材路径
set "OUT_DIR=D:\downloads\ffmpeg\video-out"

:: 如果输出目录不存在,则静默创建
if not exist "%OUT_DIR%" mkdir "%OUT_DIR%"

:: ================= 执行区 =================
:: 遍历指定目录下所有的 mp4 文件
for %%f in ("%ORI_DIR%\*.mp4") do (
    echo 正在处理: %%~nxf
    
    :: 使用 ffprobe 获取视频总时长(秒),用于精确计算结尾淡出的时间点
    for /f "tokens=*" %%i in ('ffprobe -v error -show_entries format^=duration -of default^=noprint_wrappers^=1:nokey^=1 "%%f"') do set "dur=%%i"
    
    :: 调用 PowerShell 计算淡出起始点(总时长减去 2 秒),并存入变量 !fade_st!
    for /f "tokens=*" %%a in ('powershell !dur! - 2') do set "fade_st=%%a"

    :: 核心 FFmpeg 转码逻辑
    ffmpeg -i "%%f" ^
    -s 1920x1080 ^
    -r 30 ^
    -filter_complex "[0:v]hqdn3d,setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,fade=t=in:st=0:d=2,fade=t=out:st=!fade_st!:d=2[v];[0:a]aresample=44100:async=1,afade=t=in:st=0:d=2,afade=t=out:st=!fade_st!:d=2[a]" ^
    -map "[v]" ^
    -map "[a]" ^
    -c:v libx264 ^
    -preset slow ^
    -crf 18 ^
    -pix_fmt yuv420p ^
    -g 60 ^
    -keyint_min 60 ^
    -sc_threshold 0 ^
    -vsync cfr ^
    -c:a aac ^
    -b:a 128k ^
    -ar 44100 ^
    -f mp4 ^
    -y "%OUT_DIR%\%%~nxf"
)

echo 处理完成!所有素材已标准化。
pause

2. Linux 增强版脚本 (convert.sh)

Bash

#!/bin/bash

# ================= 配置区 =================
# 原始大文件目录
ORI_DIR="/opt/ffmpeg/video-ori"
# 处理后用于推流的小文件目录
OUT_DIR="/opt/ffmpeg/video-out"

# 创建输出目录(如果不存在)
mkdir -p "$OUT_DIR"

# ================= 执行区 =================
# 循环处理所有 mp4 文件
for file in "$ORI_DIR"/*.mp4; do
    # 容错处理:如果目录下没有 mp4 文件则跳过
    [ -e "$file" ] || continue
    
    # 提取纯文件名(不含路径)
    filename=$(basename "$file")
    echo "Processing: $filename"
    
    # 利用 ffprobe 提取视频时长,确保淡出效果在视频结束前 2 秒准确触发
    duration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$file")
    # 计算淡出开始的时间点(利用 bc 进行浮点数运算)
    fade_out_start=$(echo "$duration - 2" | bc)

    ffmpeg -i "$file" \
        -s 1920x1080 \
        -r 30 \
        -filter_complex \
        "[0:v]hqdn3d,setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,fade=t=in:st=0:d=2,fade=t=out:st=$fade_out_start:d=2[v]; \
         [0:a]aresample=44100:async=1,afade=t=in:st=0:d=2,afade=t=out:st=$fade_out_start:d=2[a]" \
        -map "[v]" \
        -map "[a]" \
        -c:v libx264 \
        -preset slow \
        -crf 18 \
        -pix_fmt yuv420p \
        -g 60 \
        -keyint_min 60 \
        -sc_threshold 0 \
        -vsync cfr \
        -c:a aac \
        -b:a 128k \
        -ar 44100 \
        -f mp4 \
        -y "$OUT_DIR/$filename"
done

echo "Standardization complete."

3. 核心参数注释详解 (Technical Breakdown)

参数详细注释
-s 1920x1080分辨率标准化。将 4K 等超大画幅降至 1080p,极大减少带宽压力和文件体积。
-r 30帧率标准化。统一为 30fps,避免高帧率(60fps)在直播时占用过多计算资源。
hqdn3d高画质 3D 降噪。平滑画面噪点,不仅让雨景更清爽,且噪点越少,压缩效率越高。
setparams=...色彩空间重定义。强制声明为 Rec.709 (BT.709),防止在播放平台上出现对比度丢失或颜色发灰的情况。
fade / afade音视频淡入淡出。实现“黑场入-黑场出”,为循环直播提供丝滑的视觉缓冲。
aresample=async=1异步音频重采样。通过微调采样率对齐视频时间戳,是防止直播长时间运行后音画不同步的利器。
-g 60强制 GOP 长度。每 2 秒产生一个 I 帧,这是流媒体分片传输(DASH/HLS)的基础要求。
-vsync cfr恒定帧率模式。将变帧率(VFR)强制拉直为恒定帧率,解决直播流抖动的根本手段。
-pix_fmt yuv420p像素格式标准化。最通用的 8-bit YUV 4:2:0 格式,确保所有终端设备都能解码。
-f mp4封装容器强制定义。明确输出为 MP4 容器格式。

给博主的特别建议:

在本地用这套脚本处理出的 video-out 文件,其编码属性已经达到了“直播参考级”集成了瘦身、降噪、色彩标准化、音画同步、淡入淡出、以及严格的关键帧控制。这套配置生成的 MP4 文件上传到 VPS 后,使用 -c copy 推流将非常丝滑。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部