Skip to content

Instantly share code, notes, and snippets.

@donnaken15
Created January 10, 2025 18:49
Show Gist options
  • Save donnaken15/ccc1d1197b9a011d49cb28f2f1196824 to your computer and use it in GitHub Desktop.
Save donnaken15/ccc1d1197b9a011d49cb28f2f1196824 to your computer and use it in GitHub Desktop.
Embed YouTube timestamps/Audacity label track as chapters in audio
#!/bin/zsh
[ $# -lt 1 -a $# -gt 2 ] && {
echo "Inadequate amount of arguments"
return 1
}
tab=$'\t'
dig='[0-9]+'
dec="$dig\.$dig"
cr=$'\r'
lf=$'\n'
ds=$'\$'
i=0
fmt="($dig):($dig):($dig)(\.$dig)?"
timecode="%d:%02d:%06.3f"
stofmt() {
[[ "$1" =~ "^$fmt$ds" ]] && {
printf "$timecode" "${match[1]}" "${match[2]}" "$((${match[3]}+${match[4]:-0.000}))"
return 0
}
! [[ "$1" =~ "^$dec$ds" ]] && {
echo "Invalid input: $1" 1>&2
return 1
}
t="$(printf "%0.3f" "${match[1]}")" # avoid writing 0:60.000 :l
printf "$timecode" $(($t/3600)) $(($t/60%60)) $(($t%60))
return 0
}
{
while read -r inp; do
! [[ "$inp" =~ "^($fmt)[ $tab]([^$cr$lf]+)" ]] && {
! [[ "$inp" =~ "^($dec)$tab$dec$tab([^$cr$lf]+)" ]] && {
printf "Invalid line: %s" "$inp$lf" 1>&2
continue
}
}
printf "CHAPTER%03d=%s\nCHAPTER%03dNAME=%s\n" $i "$(stofmt "$match[1]")" $i "${match[6]:-${match[2]}}"
((i++))
done
while [ $i -lt 1000 ]; do # erase previous ones...
printf "CHAPTER%03d=\nCHAPTER%03dNAME=\n" $i $i
((i++))
done
} | ffmpeg -hide_banner -i "$1" \
-f ffmetadata -i - -c copy -map_metadata 1 \
"${2:-${1:t:r}_chapters.${1:t:e}}" -y 2>&1 | \
grep -Uv -e '\s\+CHAPTER[0-9]\+' -e '^$' --color=always
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment