Building a Video Thumbnail Gen... Note

Building a Video Thumbnail Generator Service with Go and FFmpeg Workers

The company's video category grids were hotlinking large, unoptimized JPEG thumbnails from a third-party CDN, leading to slow mobile Largest Contentful Paint (LCP) times. This was caused by serving full-resolution images and scaling them down with CSS, wasting significant bandwidth. To address this, they developed a Go service to own the thumbnail generation process. This service uses FFmpeg to extract visually distinct frames from source videos or poster frames. It then encodes these frames into multiple WebP widths, which are more efficient than JPEGs. The Go service also handles download traffic control, ensuring that FFmpeg processes are managed efficiently. PHP was deemed unsuitable for this task due to shared hosting limitations on execution time and process management. The Go service utilizes FFmpeg flags like -ss before -i for faster seeking and thumbnail=300 for better frame selection. It also employs a bounded worker pool and singleflight to prevent duplicate processing and manage concurrency. The generated thumbnails are written to a temporary file and then atomically renamed, preventing incomplete files from being served. This Go service is triggered by a cron job that enqueues thumbnail generation tasks. The front-end PHP application then queries a simple SQLite database to check the status of these thumbnails. The database schema is basic, storing video IDs, source URLs, status, and retry counts. The PHP cron job drains this queue by making HTTP requests to the Go service. The Go service's write timeout is intentionally set longer than the job's execution budget to avoid truncated responses.