如何修复Bash脚本+FFmpeg添加MP4章节的时间戳错误
问题修复:Bash+FFmpeg 给MP4添加章节的时间戳错误问题
问题根源总结
- 原脚本未正确关联前一章节结束时间与后一章节开始时间,导致时间戳偏移、Intro章节无法正常显示。
- 未处理最后一个章节的结束时间,生成了无标题的无效章节。
- 时间戳转换逻辑错误,未将
HH:MM:SS格式正确转为FFmpeg要求的微秒整数(FFmetadata的时间基准为1/1000000)。 - 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
使用步骤
- 确保
chapters.txt格式正确(每行HH:MM:SS=章节标题),与脚本、目标MP4文件在同一目录。 - 给脚本添加执行权限:
chmod +x add_chapters.sh - 运行脚本:
./add_chapters.sh your_video.mp4
关键修复点
- 时间戳标准化:通过
time_to_us函数将常规时间格式转为FFmpeg兼容的微秒整数,彻底解决格式不匹配问题。 - 章节时间关联:自动将前一章节的结束时间设为后一章节的开始时间,最后一个章节使用视频实际总时长,避免生成无效空章节。
- 顺序处理逻辑:从第一个章节开始遍历,确保Intro章节的起始时间为0且与后续章节正确衔接,解决“end time before start”的报错。
- 参数校验:增加文件存在性和输入参数检查,提前规避无意义错误。
内容的提问来源于stack exchange,提问作者Rick T
相关产品推荐
相关产品推荐

