Created
January 15, 2026 13:38
-
-
Save LCamel/6eb765a9ef3526d42e6d59b3f1bd8aac to your computer and use it in GitHub Desktop.
yt_thumb.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Usage: ./yt_thumb.sh VIDEO_ID [WIDTH] [OUTPUT_FILE] | |
| # Example: ./yt_thumb.sh hcx0SSvk7zg 480 thumbnail.jpg | |
| VIDEO_ID="$1" | |
| WIDTH="${2:-}" | |
| OUTPUT="${3:-yt_thumb_${VIDEO_ID}.jpg}" | |
| if [ -z "$VIDEO_ID" ]; then | |
| echo "Usage: $0 VIDEO_ID [WIDTH] [OUTPUT_FILE]" | |
| echo "Example: $0 hcx0SSvk7zg 480 thumbnail.jpg" | |
| exit 1 | |
| fi | |
| TEMP_DIR=$(mktemp -d) | |
| THUMB="$TEMP_DIR/thumb.jpg" | |
| PLAY_BTN="$TEMP_DIR/play.png" | |
| # Download YouTube thumbnail | |
| echo "Downloading thumbnail..." | |
| curl -s -o "$THUMB" "https://img.youtube.com/vi/${VIDEO_ID}/maxresdefault.jpg" | |
| if [ ! -s "$THUMB" ]; then | |
| echo "Failed to download thumbnail. Trying hqdefault..." | |
| curl -s -o "$THUMB" "https://img.youtube.com/vi/${VIDEO_ID}/hqdefault.jpg" | |
| fi | |
| if [ ! -s "$THUMB" ]; then | |
| echo "Error: Could not download thumbnail for video ID: $VIDEO_ID" | |
| rm -rf "$TEMP_DIR" | |
| exit 1 | |
| fi | |
| # Resize thumbnail if WIDTH is specified | |
| if [ -n "$WIDTH" ]; then | |
| echo "Resizing thumbnail to width ${WIDTH}..." | |
| RESIZED="$TEMP_DIR/resized.jpg" | |
| ffmpeg -y -loglevel error \ | |
| -i "$THUMB" \ | |
| -vf "scale=${WIDTH}:-1" \ | |
| "$RESIZED" | |
| mv "$RESIZED" "$THUMB" | |
| fi | |
| # Create anti-aliased play button (4x size then downscale) | |
| echo "Creating play button..." | |
| ffmpeg -y -loglevel error \ | |
| -f lavfi -i "color=black@0.0:s=400x400,format=rgba" \ | |
| -vf "geq=\ | |
| r='if(lt(pow(X-200,2)+pow(Y-200,2),32400)*gte(X,140)*lte(X,280)*gte(Y,120+(X-140)*0.57)*lte(Y,280-(X-140)*0.57),255,0)':\ | |
| g='if(lt(pow(X-200,2)+pow(Y-200,2),32400)*gte(X,140)*lte(X,280)*gte(Y,120+(X-140)*0.57)*lte(Y,280-(X-140)*0.57),255,0)':\ | |
| b='if(lt(pow(X-200,2)+pow(Y-200,2),32400)*gte(X,140)*lte(X,280)*gte(Y,120+(X-140)*0.57)*lte(Y,280-(X-140)*0.57),255,0)':\ | |
| a='if(lt(pow(X-200,2)+pow(Y-200,2),32400),180,0)',\ | |
| scale=100:100:flags=lanczos" \ | |
| -frames:v 1 -update 1 "$PLAY_BTN" | |
| # Overlay play button on thumbnail | |
| echo "Creating final image..." | |
| ffmpeg -y -loglevel error \ | |
| -i "$THUMB" -i "$PLAY_BTN" \ | |
| -filter_complex "[0:v][1:v]overlay=(W-w)/2:(H-h)/2" \ | |
| "$OUTPUT" | |
| # Cleanup | |
| rm -rf "$TEMP_DIR" | |
| echo "Done: $OUTPUT" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment