Skip to content

Instantly share code, notes, and snippets.

@paulirish
Created May 22, 2025 01:08
Show Gist options
  • Save paulirish/c1401da1a52f38212fbb478cc9884423 to your computer and use it in GitHub Desktop.
Save paulirish/c1401da1a52f38212fbb478cc9884423 to your computer and use it in GitHub Desktop.
screencapture a specific application's frontmost window
#!/usr/bin/env fish
# depends on FZF. also.. fish i guess. but AI could port it to zsh/bash ez.
# just run it and it'll prompt for application.
# (Trap defined lower down…)
# Select application and get bounds of it.
set -l app_list (osascript -e 'tell application "System Events" to get the name of every application process whose background only = false')
# commas to newlines and over to fzf for selection
set -l selected_app_name (echo $app_list | sed 's/,/\n/g' | string trim | fzf --header "Select an active application. We'll capture the most foreground window of it.")
# set -l selected_app_name "Google Chrome for Testing"
if test -z $selected_app_name; exit 0; end
set -l title (osascript -e "tell application \"$selected_app_name\" to get the title of the front window")
set -l bounds (osascript -e "tell application \"$selected_app_name\" to get the bounds of the front window")
set -l boundsplit (string split -- ", " "$bounds")
set -l TL_x $boundsplit[1]; set -l TL_y $boundsplit[2]; set -l BR_x $boundsplit[3]; set -l BR_y $boundsplit[4]
if test (count $boundsplit) -ne 4
echo "Dimensions are broken somehow. Cannot recover"
return 1
end
set -l width (math $BR_x - $TL_x)
set -l height (math $BR_y - $TL_y)
# CROP. filter takes size and position https://ffmpeg.org/ffmpeg-filters.html#crop
set -l cropthing (string join ":" "w=$width" "h=$height" "x=$TL_x" "y=$TL_y")
# Filename
set -l app_fname (string replace -ra '[^A-Za-z0-9._-]' '' (string replace -a ' ' '_' $selected_app_name))
set -l filename "$app_fname"_$(date +"%Y-%m-%d_%A_%I-%M_%p").mkv
set -l full_path "$HOME/Documents/screencaps/$filename"
# need rendered screen resolution height. this seems to work better than the alternatives?
# set -l resolution_height (defaults read /Library/Preferences/com.apple.windowserver.displays.plist DisplayAnyUserSets | grep High | head -n1 | egrep -o '\d+')
AV_LOG_FORCE_COLOR=1 ffmpeg -nostdin -hide_banner \
-thread_queue_size 1024 -framerate 60 -f avfoundation -pix_fmt yuyv422 \
-drop_late_frames true -capture_cursor 1 -capture_mouse_clicks 1 -i "Capture screen 0:none" \
-filter_complex "
[0:v] scale=-1:1440 [scaled],
[scaled] crop=$cropthing:keep_aspect=0:exact=1 [vout]
" \
-map '[vout]' -c:v hevc_videotoolbox -b:v 5000k -tag:v hvc1 -profile:v main -realtime true \
-y "$full_path";
# -f matroska - | mpv -;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment