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

如何修复Bash脚本+FFmpeg添加MP4章节的时间戳错误

问题修复:Bash+FFmpeg 给MP4添加章节的时间戳错误问题

问题根源总结

  1. 原脚本未正确关联前一章节结束时间与后一章节开始时间,导致时间戳偏移、Intro章节无法正常显示。
  2. 未处理最后一个章节的结束时间,生成了无标题的无效章节。
  3. 时间戳转换逻辑错误,未将HH:MM:SS格式正确转为FFmpeg要求的微秒整数(FFmetadata的时间基准为1/1000000)。
  4. FFmpeg报错“Chapter end time 0 before start”是因为章节时间戳赋值颠倒或顺序处理混乱。

修复后的完整add_chapters.sh脚本

#!/bin/bash

# 检查输入参数:必须传入目标MP4文件路径
if [ $# -ne 1 ]; then
    echo "用法: $0 <目标MP4文件>"
    exit 1
fi

VIDEO_FILE="$1"
CHAPTERS_TXT="chapters.txt"
FFMETADATA_FILE="chapters.ffmetadata"

# 检查章节配置文件是否存在
if [ ! -f "$CHAPTERS_TXT" ]; then
    echo "错误:$CHAPTERS_TXT 文件不存在"
    exit 1
fi

# 把HH:MM:SS格式时间转成FFmpeg要求的微秒(1秒=1000000微秒)
time_to_us() {
    local time_str="$1"
    IFS=':' read -r h m s <<< "$time_str"
    echo $(( (h * 3600 + m * 60 + s) * 1000000 ))
}

# 获取视频总时长(取整数秒)并转成微秒
VIDEO_DURATION=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$VIDEO_FILE" | cut -d. -f1)
VIDEO_DURATION_US=$(( VIDEO_DURATION * 1000000 ))

# 读取章节配置到数组
mapfile -t CHAPTER_LINES < "$CHAPTERS_TXT"
CHAPTER_COUNT=${#CHAPTER_LINES[@]}

# 生成标准FFmetadata文件头
cat > "$FFMETADATA_FILE" << EOF
;FFMETADATA1
TIMEBASE=1/1000000
EOF

# 遍历生成每个章节的元数据
for (( i=0; i<CHAPTER_COUNT; i++ )); do
    CURRENT_LINE=${CHAPTER_LINES[$i]}
    IFS='=' read -r CURRENT_TIME CURRENT_TITLE <<< "$CURRENT_LINE"
    
    # 当前章节开始时间
    START_US=$(time_to_us "$CURRENT_TIME")
    
    # 当前章节结束时间:最后一个章节用视频总时长,否则用下一章节的开始时间
    if [ $i -eq $((CHAPTER_COUNT - 1)) ]; then
        END_US=$VIDEO_DURATION_US
    else
        NEXT_LINE=${CHAPTER_LINES[$((i+1))]}
        IFS='=' read -r NEXT_TIME _ <<< "$NEXT_LINE"
        END_US=$(time_to_us "$NEXT_TIME")
    fi
    
    # 写入章节信息
    cat >> "$FFMETADATA_FILE" << EOF
[CHAPTER]
START=$START_US
END=$END_US
TITLE=$CURRENT_TITLE
EOF
done

echo "已生成正确的 $FFMETADATA_FILE 文件"

# 自动执行FFmpeg添加章节(生成新文件,不修改原视频)
echo "正在为视频添加章节..."
ffmpeg -i "$VIDEO_FILE" -i "$FFMETADATA_FILE" -map_metadata 1 -codec copy "${VIDEO_FILE%.mp4}_with_chapters.mp4"

if [ $? -eq 0 ]; then
    echo "章节添加完成,输出文件:${VIDEO_FILE%.mp4}_with_chapters.mp4"
else
    echo "FFmpeg执行失败,请检查错误信息"
fi

使用步骤

  1. 确保chapters.txt格式正确(每行HH:MM:SS=章节标题),与脚本、目标MP4文件在同一目录。
  2. 给脚本添加执行权限:chmod +x add_chapters.sh
  3. 运行脚本:./add_chapters.sh your_video.mp4

关键修复点

  • 时间戳标准化:通过time_to_us函数将常规时间格式转为FFmpeg兼容的微秒整数,彻底解决格式不匹配问题。
  • 章节时间关联:自动将前一章节的结束时间设为后一章节的开始时间,最后一个章节使用视频实际总时长,避免生成无效空章节。
  • 顺序处理逻辑:从第一个章节开始遍历,确保Intro章节的起始时间为0且与后续章节正确衔接,解决“end time before start”的报错。
  • 参数校验:增加文件存在性和输入参数检查,提前规避无意义错误。

内容的提问来源于stack exchange,提问作者Rick T

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 12:35:54