You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写Bash脚本实现MPEG-DASH直播流的视频编码与拼接自动化

MPEG-DASH直播流视频编码与拼接Bash脚本实现

我帮你编写了一个完全适配MPEG-DASH直播场景的Bash脚本,它能处理输入文件夹内的所有视频文件,完成编码、拼接及你提到的所有辅助功能。下面是完整实现和细节说明:

核心功能清单

  • 批量读取输入文件夹内的视频文件
  • 将所有视频编码为1080p、720p、480p三种分辨率格式,生成对应MPEG-DASH适配集
  • 自动检查所有输入视频的帧率一致性,不一致时抛出提示并终止(避免拼接后播放异常)
  • 强制将非1920×1080的输入视频缩放至1080p基准分辨率
  • 为所有视频添加频道Logo图片(支持自定义位置和透明度)
  • 自动裁剪视频结尾部分,确保所有视频以closed GOP结束,消除播放异常
  • 最终将同分辨率的编码视频拼接为完整的适配集流

完整脚本实现

#!/bin/bash

# 配置参数
INPUT_DIR="./input_videos"
OUTPUT_DIR="./dash_output"
LOGO_PATH="./channel_logo.png"
LOGO_POS="10:10"  # 左上角坐标,格式为x:y
LOGO_OPACITY=0.8  # Logo透明度(0-1)
TARGET_RES=("1920x1080" "1280x720" "854x480")
TARGET_FPS=25  # 目标帧率,可根据需求修改
GOP_SIZE=50    # GOP大小,通常为2倍帧率

# 创建输出目录
mkdir -p "${OUTPUT_DIR}/temp" "${OUTPUT_DIR}/adaption_sets"

# 检查依赖
if ! command -v ffmpeg &> /dev/null; then
    echo "错误:未找到ffmpeg,请先安装ffmpeg"
    exit 1
fi

if [ ! -f "${LOGO_PATH}" ]; then
    echo "警告:未找到Logo文件 ${LOGO_PATH},将跳过Logo添加步骤"
    SKIP_LOGO=true
fi

# 第一步:检查所有输入视频的帧率一致性
echo "正在检查输入视频帧率..."
REFERENCE_FPS=$(ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate -of default=noprint_wrappers=1:nokey=1 "${INPUT_DIR}"/* | head -n1)
REFERENCE_FPS_NUM=$(echo "${REFERENCE_FPS}" | cut -d'/' -f1)
REFERENCE_FPS_DEN=$(echo "${REFERENCE_FPS}" | cut -d'/' -f2)
REFERENCE_FPS_DEC=$(echo "scale=2; ${REFERENCE_FPS_NUM}/${REFERENCE_FPS_DEN}" | bc)

for VIDEO in "${INPUT_DIR}"/*; do
    CURRENT_FPS=$(ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate -of default=noprint_wrappers=1:nokey=1 "${VIDEO}")
    CURRENT_FPS_NUM=$(echo "${CURRENT_FPS}" | cut -d'/' -f1)
    CURRENT_FPS_DEN=$(echo "${CURRENT_FPS}" | cut -d'/' -f2)
    CURRENT_FPS_DEC=$(echo "scale=2; ${CURRENT_FPS_NUM}/${CURRENT_FPS_DEN}" | bc)
    
    if [ "${CURRENT_FPS_DEC}" != "${REFERENCE_FPS_DEC}" ]; then
        echo "错误:视频 ${VIDEO} 帧率(${CURRENT_FPS_DEC})与基准帧率(${REFERENCE_FPS_DEC})不一致"
        exit 1
    fi
done
echo "所有输入视频帧率一致,继续执行..."

# 第二步:处理每个视频(缩放、添加Logo、裁剪至closed GOP)
echo "正在处理输入视频..."
for VIDEO in "${INPUT_DIR}"/*; do
    VIDEO_NAME=$(basename "${VIDEO}" | cut -d'.' -f1)
    
    # 获取视频总帧数和时长
    TOTAL_FRAMES=$(ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=noprint_wrappers=1:nokey=1 "${VIDEO}")
    # 计算需要裁剪的帧数,确保最后一个GOP是closed
    FRAMES_TO_KEEP=$(( (TOTAL_FRAMES / GOP_SIZE) * GOP_SIZE ))
    
    for RES in "${TARGET_RES[@]}"; do
        # 构建ffmpeg命令参数
        FFMPEG_CMD="ffmpeg -i \"${VIDEO}\" -vf "
        # 添加缩放滤镜
        FFMPEG_CMD+="scale=${RES}:force_original_aspect_ratio=decrease,pad=${RES}:(ow-iw)/2:(oh-ih)/2,"
        # 添加Logo(如果存在)
        if [ -z "${SKIP_LOGO}" ]; then
            FFMPEG_CMD+="movie=${LOGO_PATH},format=rgba,colorchannelmixer=aa=${LOGO_OPACITY} [logo]; [in][logo] overlay=${LOGO_POS} [out],"
        fi
        # 裁剪至closed GOP
        FFMPEG_CMD+="trim=end_frame=${FRAMES_TO_KEEP} "
        # 编码参数(适配MPEG-DASH)
        FFMPEG_CMD+="-c:v libx264 -preset fast -crf 23 -g ${GOP_SIZE} -keyint_min ${GOP_SIZE} -sc_threshold 0 "
        FFMPEG_CMD+="-c:a aac -b:a 128k "
        FFMPEG_CMD+="-r ${TARGET_FPS} "
        FFMPEG_CMD+="-y \"${OUTPUT_DIR}/temp/${VIDEO_NAME}_${RES}.mp4\""
        
        # 执行命令
        echo "正在处理 ${VIDEO_NAME} -> ${RES}"
        eval "${FFMPEG_CMD}"
    done
done

# 第三步:拼接同分辨率的视频,生成适配集
echo "正在拼接视频生成适配集..."
for RES in "${TARGET_RES[@]}"; do
    # 生成拼接列表文件
    echo "file '${OUTPUT_DIR}/temp/'\$(basename %f)" > "${OUTPUT_DIR}/temp/concat_list_${RES}.txt"
    ls "${OUTPUT_DIR}/temp/"*"${RES}.mp4" | sort >> "${OUTPUT_DIR}/temp/concat_list_${RES}.txt"
    
    # 执行拼接
    ffmpeg -f concat -safe 0 -i "${OUTPUT_DIR}/temp/concat_list_${RES}.txt" -c copy -y "${OUTPUT_DIR}/adaption_sets/adaption_set_${RES}.mp4"
done

# 清理临时文件
echo "清理临时文件..."
rm -rf "${OUTPUT_DIR}/temp"

echo "处理完成!适配集已保存至 ${OUTPUT_DIR}/adaption_sets/"

关键模块详解

1. 帧率一致性检查

脚本通过ffprobe读取第一个视频的帧率作为基准,遍历所有输入视频对比帧率,不一致时直接终止,避免拼接后出现播放跳帧或卡顿问题。

2. 分辨率强制缩放

使用ffmpeg的scale和pad滤镜,将非1080p的视频缩放至目标分辨率,同时保持原始宽高比,空白区域自动填充黑边,确保所有视频分辨率统一。

3. Logo添加功能

通过movie滤镜加载Logo图片,配合colorchannelmixer调整透明度,再用overlay滤镜将Logo放置在指定位置(默认左上角),如果未找到Logo文件会自动跳过该步骤。

4. Closed GOP裁剪

计算视频总帧数与GOP大小的整数倍,裁剪掉多余的结尾帧,确保每个视频都以完整的closed GOP结束,这是MPEG-DASH直播流避免播放异常的关键要求。

5. MPEG-DASH适配编码

使用libx264编码器,设置固定的GOP大小和keyint_min,关闭场景切换自动关键帧(sc_threshold 0),确保编码后的视频符合DASH直播的分段要求。

内容的提问来源于stack exchange,提问作者Massimo Vantaggio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:17:47