I want to simulate a playhead moving over a waveform, like when playing a track in an audio editor. As far as I understand, I can generate this effect if I have both the audio file and an image of the waveform.
declare -r DURATION=$(ffprobe -i audio.flac -show_entries format=duration -v quiet -of csv="p=0")
ffmpeg -hide_banner -loop 1 -framerate 30 -i waveform.png -i audio.flac \
-filter_complex "
drawtext=text='%{pts\\:hms} -- %{n} -- %{pts\\:flt}':x=32:y=32:fontsize=24:fontcolor=black@0.75:box=1,
drawbox=x=t*${DURATION}/iw/10000000:y=0:w=16:h=ih:color=CC1144@0.5:t=fill
" \
-map 1:a -shortest -t 5 -pix_fmt yuv420p playhead.mp4
What it does:
audio.flac
.waveform.png
as a static background and audio.flac
as the audio track. Using drawtext
, I overlay time information on the video, and with drawbox
I attempt to render the moving playhead. (For quicker testing, I limit the video to the first 5 seconds.)Note that I divide t
by 10000000 just to make the box appear at all (otherwise it seems to be so big that it cannot fit the viewport). For whatever reason the box remains static, and I don't think that t
even changes.
What detail am I missing, and how can I at least obtain the value of t
(for debug), so I can make the box move in sync with the current timestamp?
drawbox does not support animation. The variable t
is for box thickness, not time.
Instead, generate a color box and then animate the overlay.
-filter_complex "
color=c=CC1144@0.5:s=16x16:r=30,format=yuva420p[ph];
[ph][0]scale=iw:rh,setsar=1[ph];
[0]drawtext=text='%{pts\\:hms} -- %{n} -- %{pts\\:flt}':x=32:y=32:fontsize=24:fontcolor=black@0.75:box=1[v];
[v][ph]overlay=x=W*t/${DURATION}:y=0
"