Skip to content

Instantly share code, notes, and snippets.

@dericed
Created April 10, 2019 18:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dericed/abf66e6d4fe72f15395b9c044b652f48 to your computer and use it in GitHub Desktop.
Save dericed/abf66e6d4fe72f15395b9c044b652f48 to your computer and use it in GitHub Desktop.
broken attempt to convert timecode data into a vtt file
#!/bin/bash
# these two functions cross-convert between frame number and timecode value
# borrowed from https://github.com/yamaq/timecode/blob/master/timecode
function convToFN() {
# Convert to frame number(1800) from timecode(00:01:00:00)
# $1 --> tc
# $2 --> fpsHz
# $3 --> fpsCalc
local tc frames frameBase
if [ $2 -eq 29 -o $2 -eq 59 ]; then # DF
if [ $2 -eq 29 ]; then
if [[ "$1" =~ ([0-1][0-9]|[2][0-3]):[0-5][^0]:00:0[0-1] ]]; then
tc="${1:0:10}2" # 00:01:00:00 --> 00:01:00:02
else
tc="$1"
fi
else # 59
if [[ "$1" =~ ([0-1][0-9]|[2][0-3]):[0-5][^0]:00:0[0-3] ]]; then
tc="${1:0:10}4" # 00:01:00:00 --> 00:01:00:04
else
tc="$1"
fi
fi
frameBase=$(( ($3 * 60 - $3 / 15) * 9 + $3 * 60 ))
frames=$(( 10#${tc:0:2} * 6 * $frameBase + ${tc:3:1} * $frameBase ))
if [ ${tc:4:1} -eq 0 ]; then
frames=$(( $frames + 10#${tc:6:2} * $3 + 10#${tc:9:2} ))
else
frames=$(( $frames + ${tc:4:1} * ($3 * 60 - $3 / 15) ))
frames=$(( $frames + 10#${tc:6:2} * $3 + 10#${tc:9:2} ))
fi
else # NDF
tc="$1"
frames=$(( 10#${tc:0:2} * 60 * 60 * $3 )) # hour
frames=$(( $frames + 10#${tc:3:2} * 60 * $3 )) # minute
frames=$(( $frames + 10#${tc:6:2} * $3 )) # second
frames=$(( $frames + 10#${tc:9:2} )) # frame
fi
echo "$frames"
return 0
}
function convToTC() {
# Convert to timecode(00:01:00:00) from frame number(1800)
# If fn is over 24H, will be returned 0H.
# $1 --> fn
# $2 --> fpsHz
# $3 --> fpsCalc
local hh mm m10 m1 ss ff tc fn dfSequence
if [ $2 -eq 29 -o $2 -eq 59 ]; then
fn=$(( $1 % (86400 * $3 - ($3 / 15 * 1296)) )) # To fn is under 24H
dfSequence=$(( $fn / (($3 * 60 - $3 / 15) * 9 + $3 * 60) ))
hh=$(( $dfSequence / 6 ))
m10=$(( $dfSequence % 6 ))
fn=$(( $fn % (($3 * 60 - $3 / 15) * 9 + $3 * 60) ))
if [ $fn -lt $(( $3 * 60 )) ]; then
m1=0
ss=$(( $fn / $3 ))
ff=$(( $fn % $3 ))
else
fn=$(( $fn - $3 * 60 ))
for i in $(seq 1 9); do
if [ $fn -lt $(( $3 * 60 - $3 / 15 )) ]; then
m1=$i
fn=$(( $fn + $3 / 15 ))
ss=$(( $fn / $3 ))
ff=$(( $fn % $3 ))
break
fi
fn=$(( $fn - ($3 * 60 - $3 / 15) ))
done
fi
printf "%02d:%01d%01d:%02d:%02d\n" $hh $m10 $m1 $ss $ff
else
hh=$(( ($1 / (3600 * $3)) % 24 ))
mm=$(( $1 % (3600 * $3) / (60 * $3) ))
ss=$(( ($1 % (3600 * $3)) % (60 * $3) / $3 ))
ff=$(( ($1 % (3600 * $3)) % (60 * $3) % $3 ))
printf "%02d:%02d:%02d:%02d\n" $hh $mm $ss $ff
fi
return 0
}
# dave rice created convToTS by modifying convToTC
function convToTS() {
# Convert to timecode(00:01:00:00) from frame number(1800)
# If fn is over 24H, will be returned 0H.
# $1 --> fn
# $2 --> fps
local hh mm m10 m1 ss ff tc fn dfSequence
echo "1 $1 2 $2"
time=$(echo "scale=3; $1 / ($2)" | bc)
hh=$(echo "$time / (60 * 60)" | bc)
mm=$(echo "$time % (60 * 60) / 60" | bc)
ss=$(echo "$time % 60" | bc)
ff=$(echo "$time" | cut -d . -f2)
echo
echo "===="
echo "time $time tc $hh $mm $ss $ff"
printf "%02d:%02d:%02d.%04d\n" $hh $mm $ss $ff
return 0
}
MEDIAFILE="${1}"
# trying to grab timecode using ffmpeg alone, resourcespace-style
TIMECODE=$(ffmpeg -i "${MEDIAFILE}" 2>&1 | grep timecode | head -n 1 | cut -d : -f2- | sed 's/ //g')
if [[ -n "${TIMECODE}" ]] ; then
DUARTION_TC=$(ffmpeg -i "${MEDIAFILE}" 2>&1 | grep "Duration: " | head -n 1 | cut -d : -f2- | cut -d , -f1 | sed 's/ //g')
DUARTION_FN=$(convToFN "${DUARTION_TC}" 100 30)
echo "Timecode value is ${TIMECODE}"
echo "Duration as time is ${DUARTION_TC}"
echo "Duration as frame number is ${DUARTION_FN}"
FRAME_START=$(convToFN "${TIMECODE}" 29 30)
VTT_NAME="${MEDIAFILE%.*}.vtt"
echo "WEBVTT" > "${VTT_NAME}"
echo >> "${VTT_NAME}"
COUNTER="0"
while [ "$COUNTER" -lt "$DUARTION_FN" ] ; do
FRAME_VALUE="$(echo ${FRAME_START} + $COUNTER | bc)"
convToTC "$FRAME_VALUE" 29 30
VTT_FRAME_START=$(convToTS "$COUNTER" "30000/1001")
COUNTER=$[$COUNTER+1]
VTT_FRAME_END=$(convToTS "$COUNTER" "30000/1001")
echo "$VTT_FRAME_START -> $VTT_FRAME_END"
done
else
echo "sorry, no timecode"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment