=== date and environment 2026-10-26T08:14:21Z Linux 6.8.0-139-generic x86_64 ffmpeg version 6.1.1-3ubuntu5 Copyright (c) 2000-2023 the FFmpeg developers font used: /usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf T.C drawtext V->V Draw text on top of video frames using libfreetype library. === download inputs === ffprobe inputs $ ffprobe -v error -show_entries format=duration,size,format_name -show_entries stream=codec_name,width,height,avg_frame_rate -of default=nw=1 src-dark.webm codec_name=vp9 width=1920 height=1080 avg_frame_rate=30000/1001 codec_name=opus avg_frame_rate=0/0 format_name=matroska,webm duration=28.001000 size=14571919 $ ffprobe -v error -show_entries format=duration,size,format_name -show_entries stream=codec_name,width,height,avg_frame_rate -of default=nw=1 src-bright.ogv codec_name=unknown avg_frame_rate=0/0 codec_name=theora width=1920 height=1080 avg_frame_rate=24000/1001 codec_name=vorbis avg_frame_rate=0/0 format_name=ogg duration=14.222542 size=14443027 === centre-crop both clips to 1080x1920 (9:16) $ ffmpeg -v error -y -i src-dark.webm -t 4 -vf crop=608:1080:656:0,scale=1080:1920:flags=lanczos,fps=30 -c:v libx264 -preset veryfast -crf 18 -pix_fmt yuv420p -an out5/dark-9x16.mp4 $ ffmpeg -v error -y -i src-bright.ogv -t 4 -vf crop=608:1080:656:0,scale=1080:1920:flags=lanczos,fps=30 -c:v libx264 -preset veryfast -crf 18 -pix_fmt yuv420p -an out5/bright-9x16.mp4 $ ffprobe -v error -show_entries stream=width,height,nb_frames -of default=nw=1 out5/dark-9x16.mp4 width=1080 height=1920 nb_frames=120 $ ffprobe -v error -show_entries stream=width,height,nb_frames -of default=nw=1 out5/bright-9x16.mp4 width=1080 height=1920 nb_frames=120 === measurement 1: cap height at 7 font sizes $ ffmpeg -v error -y -f lavfi -i color=c=black:s=1080x1920:d=1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=32:x=(w-text_w)/2:y=1180 -frames:v 1 -f rawvideo -pix_fmt rgb24 out5/size-32.raw $ ffmpeg -v error -y -f lavfi -i color=c=black:s=1080x1920:d=1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=32:x=(w-text_w)/2:y=1180 -frames:v 1 out5/size-32.png $ ffmpeg -v error -y -f lavfi -i color=c=black:s=1080x1920:d=1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=40:x=(w-text_w)/2:y=1180 -frames:v 1 -f rawvideo -pix_fmt rgb24 out5/size-40.raw $ ffmpeg -v error -y -f lavfi -i color=c=black:s=1080x1920:d=1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=40:x=(w-text_w)/2:y=1180 -frames:v 1 out5/size-40.png $ ffmpeg -v error -y -f lavfi -i color=c=black:s=1080x1920:d=1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:x=(w-text_w)/2:y=1180 -frames:v 1 -f rawvideo -pix_fmt rgb24 out5/size-48.raw $ ffmpeg -v error -y -f lavfi -i color=c=black:s=1080x1920:d=1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:x=(w-text_w)/2:y=1180 -frames:v 1 out5/size-48.png $ ffmpeg -v error -y -f lavfi -i color=c=black:s=1080x1920:d=1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=56:x=(w-text_w)/2:y=1180 -frames:v 1 -f rawvideo -pix_fmt rgb24 out5/size-56.raw $ ffmpeg -v error -y -f lavfi -i color=c=black:s=1080x1920:d=1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=56:x=(w-text_w)/2:y=1180 -frames:v 1 out5/size-56.png $ ffmpeg -v error -y -f lavfi -i color=c=black:s=1080x1920:d=1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=64:x=(w-text_w)/2:y=1180 -frames:v 1 -f rawvideo -pix_fmt rgb24 out5/size-64.raw $ ffmpeg -v error -y -f lavfi -i color=c=black:s=1080x1920:d=1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=64:x=(w-text_w)/2:y=1180 -frames:v 1 out5/size-64.png $ ffmpeg -v error -y -f lavfi -i color=c=black:s=1080x1920:d=1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=72:x=(w-text_w)/2:y=1180 -frames:v 1 -f rawvideo -pix_fmt rgb24 out5/size-72.raw $ ffmpeg -v error -y -f lavfi -i color=c=black:s=1080x1920:d=1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=72:x=(w-text_w)/2:y=1180 -frames:v 1 out5/size-72.png $ ffmpeg -v error -y -f lavfi -i color=c=black:s=1080x1920:d=1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=96:x=(w-text_w)/2:y=1180 -frames:v 1 -f rawvideo -pix_fmt rgb24 out5/size-96.raw $ ffmpeg -v error -y -f lavfi -i color=c=black:s=1080x1920:d=1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=96:x=(w-text_w)/2:y=1180 -frames:v 1 out5/size-96.png === measurement 2: pick the frame where plain white text has the least room second 0: brightest pixel in the caption band YMAX=211 second 1: brightest pixel in the caption band YMAX=217 second 2: brightest pixel in the caption band YMAX=219 second 3: brightest pixel in the caption band YMAX=222 chosen second: 3 (brightest pixel YMAX=222) === measurement 2: caption styles on 2 real frames $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:x=(w-text_w)/2:y=1180 -f rawvideo -pix_fmt rgb24 out5/dark-white-plain.raw $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:x=(w-text_w)/2:y=1180 out5/dark-white-plain.png $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:borderw=6:bordercolor=black:x=(w-text_w)/2:y=1180 -f rawvideo -pix_fmt rgb24 out5/dark-white-outline.raw $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:borderw=6:bordercolor=black:x=(w-text_w)/2:y=1180 out5/dark-white-outline.png $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:box=1:boxcolor=black@0.6:boxborderw=24:x=(w-text_w)/2:y=1180 -f rawvideo -pix_fmt rgb24 out5/dark-white-box60.raw $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:box=1:boxcolor=black@0.6:boxborderw=24:x=(w-text_w)/2:y=1180 out5/dark-white-box60.png $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:box=1:boxcolor=black@0.8:boxborderw=24:x=(w-text_w)/2:y=1180 -f rawvideo -pix_fmt rgb24 out5/dark-white-box80.raw $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:box=1:boxcolor=black@0.8:boxborderw=24:x=(w-text_w)/2:y=1180 out5/dark-white-box80.png $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:box=1:boxcolor=black@1.0:boxborderw=24:x=(w-text_w)/2:y=1180 -f rawvideo -pix_fmt rgb24 out5/dark-white-box100.raw $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:box=1:boxcolor=black@1.0:boxborderw=24:x=(w-text_w)/2:y=1180 out5/dark-white-box100.png $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=0xFFE24A:fontsize=48:box=1:boxcolor=black@0.6:boxborderw=24:x=(w-text_w)/2:y=1180 -f rawvideo -pix_fmt rgb24 out5/dark-yellow-box60.raw $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=0xFFE24A:fontsize=48:box=1:boxcolor=black@0.6:boxborderw=24:x=(w-text_w)/2:y=1180 out5/dark-yellow-box60.png $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=black@0.75:fontsize=48:x=(w-text_w)/2+4:y=1180+4,drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:x=(w-text_w)/2:y=1180 -f rawvideo -pix_fmt rgb24 out5/dark-white-shadow.raw $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=black@0.75:fontsize=48:x=(w-text_w)/2+4:y=1180+4,drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:x=(w-text_w)/2:y=1180 out5/dark-white-shadow.png $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -f rawvideo -pix_fmt rgb24 out5/dark-plain.raw $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 out5/dark-plain.png $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:x=(w-text_w)/2:y=1180 -f rawvideo -pix_fmt rgb24 out5/bright-white-plain.raw $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:x=(w-text_w)/2:y=1180 out5/bright-white-plain.png $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:borderw=6:bordercolor=black:x=(w-text_w)/2:y=1180 -f rawvideo -pix_fmt rgb24 out5/bright-white-outline.raw $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:borderw=6:bordercolor=black:x=(w-text_w)/2:y=1180 out5/bright-white-outline.png $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:box=1:boxcolor=black@0.6:boxborderw=24:x=(w-text_w)/2:y=1180 -f rawvideo -pix_fmt rgb24 out5/bright-white-box60.raw $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:box=1:boxcolor=black@0.6:boxborderw=24:x=(w-text_w)/2:y=1180 out5/bright-white-box60.png $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:box=1:boxcolor=black@0.8:boxborderw=24:x=(w-text_w)/2:y=1180 -f rawvideo -pix_fmt rgb24 out5/bright-white-box80.raw $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:box=1:boxcolor=black@0.8:boxborderw=24:x=(w-text_w)/2:y=1180 out5/bright-white-box80.png $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:box=1:boxcolor=black@1.0:boxborderw=24:x=(w-text_w)/2:y=1180 -f rawvideo -pix_fmt rgb24 out5/bright-white-box100.raw $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:box=1:boxcolor=black@1.0:boxborderw=24:x=(w-text_w)/2:y=1180 out5/bright-white-box100.png $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=0xFFE24A:fontsize=48:box=1:boxcolor=black@0.6:boxborderw=24:x=(w-text_w)/2:y=1180 -f rawvideo -pix_fmt rgb24 out5/bright-yellow-box60.raw $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=0xFFE24A:fontsize=48:box=1:boxcolor=black@0.6:boxborderw=24:x=(w-text_w)/2:y=1180 out5/bright-yellow-box60.png $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=black@0.75:fontsize=48:x=(w-text_w)/2+4:y=1180+4,drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:x=(w-text_w)/2:y=1180 -f rawvideo -pix_fmt rgb24 out5/bright-white-shadow.raw $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=black@0.75:fontsize=48:x=(w-text_w)/2+4:y=1180+4,drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:x=(w-text_w)/2:y=1180 out5/bright-white-shadow.png $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 -f rawvideo -pix_fmt rgb24 out5/bright-plain.raw $ ffmpeg -v error -y -ss 3 -i out5/bright-9x16.mp4 -frames:v 1 out5/bright-plain.png === figure frames: the same caption at three sizes on the real dark clip $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=40:x=(w-text_w)/2:y=1180 out5/figure-size-40.png $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=48:x=(w-text_w)/2:y=1180 out5/figure-size-48.png $ ffmpeg -v error -y -ss 1 -i out5/dark-9x16.mp4 -frames:v 1 -vf drawtext=fontfile='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf':text='TAP TO SEE THE FULL ROUTINE':fontcolor=white:fontsize=56:x=(w-text_w)/2:y=1180 out5/figure-size-56.png === measurement 3: brightness of the caption band over time (ffmpeg signalstats) $ ffmpeg -v error -y -i out5/dark-9x16.mp4 -vf crop=1080:260:0:1180,fps=10,signalstats,metadata=print:file=out5/stats-dark.txt -f null - --- dark: per-frame luma of the 1080x260 band at y=1180 --- lavfi.signalstats.YMIN=6 lavfi.signalstats.YAVG=42.5764 lavfi.signalstats.YMAX=245 lavfi.signalstats.YMIN=3 lavfi.signalstats.YAVG=42.4703 lavfi.signalstats.YMAX=248 ... 40 $ ffmpeg -v error -y -i out5/bright-9x16.mp4 -vf crop=1080:260:0:1180,fps=10,signalstats,metadata=print:file=out5/stats-bright.txt -f null - --- bright: per-frame luma of the 1080x260 band at y=1180 --- lavfi.signalstats.YMIN=64 lavfi.signalstats.YAVG=96.0965 lavfi.signalstats.YMAX=211 lavfi.signalstats.YMIN=62 lavfi.signalstats.YAVG=96.216 lavfi.signalstats.YMAX=211 ... 40 === measurement 4: characters per second of sample captions caption characters duration_seconds chars_per_second TAP TO SEE THE FULL ROUTINE 27 1.2 22.5 TAP TO SEE THE FULL ROUTINE 27 1.6 16.9 TAP TO SEE THE FULL ROUTINE 27 2.0 13.5 THIS TEXT IS FAR TOO SMALL TO READ 35 1.5 23.3 THIS TEXT IS FAR TOO SMALL TO READ 35 2.0 17.5 === measure the rendered pixels $ python3 /home/ubuntu/rt/readable-caption-styles/measure.py out5 /usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf 390 1080 1920 TAP TO SEE THE FULL ROUTINE ==================================================================================================== A. CAP HEIGHT BY FONT SIZE sample caption: 'TAP TO SEE THE FULL ROUTINE' ==================================================================================================== font file: /usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf frame: 1080x1920, phone view: 390 CSS px wide (scale 0.36111) size_px cap_height_px text_width_px pct_frame_width cap_css_390px pct_of_844px chars_fit 32 23 557 51.6% 8.31 px 0.98% 41 of 27 40 30 695 64.4% 10.83 px 1.28% 33 of 27 48 37 835 77.3% 13.36 px 1.58% 27 of 27 56 43 973 90.1% 15.53 px 1.84% 23 of 27 64 49 1080 100.0% 17.69 px 2.1% 21 of 27 72 54 1080 100.0% 19.5 px 2.31% 21 of 27 96 73 1080 100.0% 26.36 px 3.12% 21 of 27 ==================================================================================================== B. WHAT THE CAPTION LETTERS ACTUALLY TOUCH, ON TWO REAL CLIPS ==================================================================================================== A support pixel is solid when its four neighbours have almost the same brightness (that rejects antialiased letter edges). 'Worst' is the lowest contrast found between the caption fill and a support pixel next to it. ---------------------------------------------------------------------------------------------------- dark clip: background in the caption band, caption removed: brightest pixel 0.988, 90th percentile 0.114, median 0.001 a plain white caption has no separation there: 1.01:1 against the brightest pixel in the band (RGB 252,255,245) white-plain fill #FFFFFF contrast against what the letters touch: median 20.47:1, worst 10% 8.94:1, lowest 3.88:1 white-shadow fill #FFFFFF contrast against what the letters touch: median 20.64:1, worst 10% 12.98:1, lowest 3.88:1 white-outline fill #FFFFFF contrast against what the letters touch: median 21.00:1, worst 10% 21.00:1, lowest 21.00:1 white-box60 fill #FFFFFF contrast against what the letters touch: median 20.47:1, worst 10% 16.33:1, lowest 6.46:1 white-box80 fill #FFFFFF contrast against what the letters touch: median 20.70:1, worst 10% 19.07:1, lowest 13.55:1 white-box100 fill #FFFFFF contrast against what the letters touch: median 21.00:1, worst 10% 21.00:1, lowest 21.00:1 yellow-box60 fill #FFE24A contrast against what the letters touch: median 15.31:1, worst 10% 12.11:1, lowest 6.71:1 ---------------------------------------------------------------------------------------------------- bright clip: background in the caption band, caption removed: brightest pixel 0.863, 90th percentile 0.203, median 0.098 a plain white caption has no separation there: 1.15:1 against the brightest pixel in the band (RGB 235,241,230) white-plain fill #FFFFFF contrast against what the letters touch: median 7.61:1, worst 10% 4.26:1, lowest 1.25:1 white-shadow fill #FFFFFF contrast against what the letters touch: median 10.79:1, worst 10% 5.76:1, lowest 1.25:1 white-outline fill #FFFFFF contrast against what the letters touch: median 21.00:1, worst 10% 21.00:1, lowest 1.25:1 white-box60 fill #FFFFFF contrast against what the letters touch: median 16.22:1, worst 10% 12.51:1, lowest 1.29:1 white-box80 fill #FFFFFF contrast against what the letters touch: median 19.06:1, worst 10% 17.62:1, lowest 1.29:1 white-box100 fill #FFFFFF contrast against what the letters touch: median 21.00:1, worst 10% 21.00:1, lowest 1.29:1 yellow-box60 fill #FFE24A contrast against what the letters touch: median 12.47:1, worst 10% 9.79:1, lowest 6.66:1 ==================================================================================================== C. HOW BRIGHT IS THE CAPTION BAND OVER TIME? (ffmpeg signalstats) ==================================================================================================== dark 40 frames at 10 fps. 23 frames (57.5%) contain a pixel as bright as white text (YMAX 255). Median YMAX 250, max 255, median band brightness YAVG 43. bright 40 frames at 10 fps. 0 frames (0.0%) contain a pixel as bright as white text (YMAX 255). Median YMAX 218, max 224, median band brightness YAVG 97. ==================================================================================================== D. SUMMARY ==================================================================================================== cap height rows: 7, contrast rows: 14, band rows: 2 === files produced total 181232 drwxrwxr-x 2 ubuntu ubuntu 4096 Oct 26 08:14 . drwxrwxr-x 8 ubuntu ubuntu 4096 Oct 26 08:14 .. -rw-rw-r-- 1 ubuntu ubuntu 5918468 Oct 26 08:14 bright-9x16.mp4 -rw-rw-r-- 1 ubuntu ubuntu 1817826 Oct 26 08:14 bright-plain.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 bright-plain.raw -rw-rw-r-- 1 ubuntu ubuntu 1732398 Oct 26 08:14 bright-white-box100.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 bright-white-box100.raw -rw-rw-r-- 1 ubuntu ubuntu 1776617 Oct 26 08:14 bright-white-box60.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 bright-white-box60.raw -rw-rw-r-- 1 ubuntu ubuntu 1760784 Oct 26 08:14 bright-white-box80.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 bright-white-box80.raw -rw-rw-r-- 1 ubuntu ubuntu 1793513 Oct 26 08:14 bright-white-outline.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 bright-white-outline.raw -rw-rw-r-- 1 ubuntu ubuntu 1812742 Oct 26 08:14 bright-white-plain.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 bright-white-plain.raw -rw-rw-r-- 1 ubuntu ubuntu 1813318 Oct 26 08:14 bright-white-shadow.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 bright-white-shadow.raw -rw-rw-r-- 1 ubuntu ubuntu 1780529 Oct 26 08:14 bright-yellow-box60.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 bright-yellow-box60.raw -rw-rw-r-- 1 ubuntu ubuntu 267 Oct 26 08:14 cps.tsv -rw-rw-r-- 1 ubuntu ubuntu 1832812 Oct 26 08:14 dark-9x16.mp4 -rw-rw-r-- 1 ubuntu ubuntu 1844540 Oct 26 08:14 dark-plain.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 dark-plain.raw -rw-rw-r-- 1 ubuntu ubuntu 1777859 Oct 26 08:14 dark-white-box100.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 dark-white-box100.raw -rw-rw-r-- 1 ubuntu ubuntu 1816339 Oct 26 08:14 dark-white-box60.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 dark-white-box60.raw -rw-rw-r-- 1 ubuntu ubuntu 1802219 Oct 26 08:14 dark-white-box80.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 dark-white-box80.raw -rw-rw-r-- 1 ubuntu ubuntu 1821832 Oct 26 08:14 dark-white-outline.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 dark-white-outline.raw -rw-rw-r-- 1 ubuntu ubuntu 1842244 Oct 26 08:14 dark-white-plain.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 dark-white-plain.raw -rw-rw-r-- 1 ubuntu ubuntu 1840803 Oct 26 08:14 dark-white-shadow.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 dark-white-shadow.raw -rw-rw-r-- 1 ubuntu ubuntu 1817377 Oct 26 08:14 dark-yellow-box60.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 dark-yellow-box60.raw -rw-rw-r-- 1 ubuntu ubuntu 1843145 Oct 26 08:14 figure-size-40.png -rw-rw-r-- 1 ubuntu ubuntu 1842244 Oct 26 08:14 figure-size-48.png -rw-rw-r-- 1 ubuntu ubuntu 1838247 Oct 26 08:14 figure-size-56.png -rw-rw-r-- 1 ubuntu ubuntu 32980 Oct 26 08:14 pick-0.txt -rw-rw-r-- 1 ubuntu ubuntu 32957 Oct 26 08:14 pick-1.txt -rw-rw-r-- 1 ubuntu ubuntu 32964 Oct 26 08:14 pick-2.txt -rw-rw-r-- 1 ubuntu ubuntu 25369 Oct 26 08:14 pick-3.txt -rw-rw-r-- 1 ubuntu ubuntu 9808 Oct 26 08:14 size-32.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 size-32.raw -rw-rw-r-- 1 ubuntu ubuntu 10787 Oct 26 08:14 size-40.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 size-40.raw -rw-rw-r-- 1 ubuntu ubuntu 12096 Oct 26 08:14 size-48.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 size-48.raw -rw-rw-r-- 1 ubuntu ubuntu 12305 Oct 26 08:14 size-56.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 size-56.raw -rw-rw-r-- 1 ubuntu ubuntu 14281 Oct 26 08:14 size-64.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 size-64.raw -rw-rw-r-- 1 ubuntu ubuntu 14081 Oct 26 08:14 size-72.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 size-72.raw -rw-rw-r-- 1 ubuntu ubuntu 15162 Oct 26 08:14 size-96.png -rw-rw-r-- 1 ubuntu ubuntu 6220800 Oct 26 08:14 size-96.raw -rw-rw-r-- 1 ubuntu ubuntu 33649 Oct 26 08:14 stats-bright.txt === editor note, 2026-10-26 (review after publication) The "lowest" column is not reliable on the bright clip: a solid black box (white-box100) cannot fall below 21:1, yet it reads 1.29:1, so the lowest single value comes from mis-classified edge pixels, not from a letter. The page therefore reports only the worst tenth of letters. Character counts above 56 px were taken from a line clipped at the frame edge (1080 px) and are replaced on the page by estimates scaled from the 56 px width.