screencap#
Screenshots and screen video off a phone, tablet, emulator or simulator - for README media, store listings and bug reports.
One surface, two backends, chosen by platform:
| Platform | Stills | Video |
|---|---|---|
android |
adb exec-out screencap |
adb shell screenrecord + adb pull |
ios |
xcrun simctl io screenshot |
xcrun simctl io recordVideo |
Two limits belong to the device, not to this module, and are reported rather than hidden:
screenrecordcaps a single clip at 180 seconds and records no audio.screencap_recordsplits longer requests into chunks and concatenates them, so a 300-second request produces 300 seconds rather than a silent 180. Chunking needsffmpeg; without it a longer request is refused rather than truncated.- A physical iOS device cannot be recorded without Xcode driving it. That returns 3 with an explanation instead of appearing to succeed.
This module depends on adb and ios, and loads both itself if the caller did
not ask for them.
Functions#
screencap_available- Purpose: Report whether at least one backend can capture -
adbwith a ready device, or a booted iOS simulator. -
Returns: 0 when capture is possible; 1 otherwise.
-
screencap_shot [--device <id>] [--platform android|ios] [--out <path>] - Purpose: Capture a single PNG. With no arguments, targets the only connected device.
- Args:
--device- adb serial or simulator UDID. Inferred when exactly one device is present.--platform- required only when both an Android device and an iOS simulator are present.--out- destination; defaults todocs/screenshots/<UTC-timestamp>-<device>.png.
- Returns: 0 and the path written, so it can be piped into a docs step; 2 when the target is ambiguous or an option is given without its value; 3 when no device is available; 1 on a capture failure.
-
Example:
screencap_shot --device R5CRC2WANMT --out docs/img/home.png -
screencap_record [--device <id>] [--platform android|ios] [--out <path>] [--seconds <n>] [--size <WxH>] [--bitrate <bps>] [--gif] - Purpose: Capture screen video. Defaults to 30 seconds.
--gifalso writes a.gifbeside the video. - Returns: 0 and the path to the video; 2 on bad arguments (including an option without its value) or an ambiguous target; 3 when no device is available, or when a >180s Android clip is requested without
ffmpeg, or for a physical iOS device. -
Example:
screencap_record --seconds 20 --gif -
screencap_record_stop [device] - Purpose: Stop an in-flight recording started outside
screencap_record's own timed wait. Safe to call when nothing is recording. -
Returns: 0 always.
-
screencap_frame <video> <out.png> [--at <seconds>] - Purpose: Extract a still frame from a recording, for a README image taken from a demo clip. Defaults to 1 second in, because frame zero is often a blank or transitioning screen.
-
Returns: 0 and the path written; 2 on bad arguments, including an option without its value; 3 when
ffmpegis not installed; 1 on an extraction failure. -
screencap_gif <video> <out.gif> [--fps <n>] [--width <px>] - Purpose: Convert a recording to a GIF suitable for a README. Two-pass with a generated palette, because a single-pass GIF from video is visibly dithered. Defaults to 12 fps and 480px wide, which keeps a short clip under a couple of megabytes.
- Returns: 0 and the path written; 2 on bad arguments, including an option without its value; 3 when
ffmpegis not installed; 1 on a conversion failure.
Environment#
| Variable | Use |
|---|---|
SCREENCAP_DIR |
Output directory for generated names. Defaults to docs/screenshots. |
Dependencies#
adb for Android. macOS with Xcode for iOS simulators. ffmpeg for
screencap_frame, screencap_gif, and for Android clips over 180 seconds.
Examples#
shlib_import screencap
# A screenshot for the README.
screencap_shot --out docs/img/home-screen.png
# A 20-second demo clip, plus a GIF for the README and a still for the store.
video="$(screencap_record --seconds 20 --gif)"
screencap_frame "$video" docs/img/hero.png --at 3
PowerShell#
ps/lib/screencap.ps1 mirrors this module with the same function names. On
Windows only the Android backend is available, because simctl is macOS-only.
The Android still capture streams the process's raw stdout to the file, since a
PowerShell pipeline would corrupt the PNG.