A Lua user script for mpv that lets you:
- Save screenshots to per‑video folders
- Browse screenshots in an in‑player tiled gallery overlay
- Select, delete, and export as contact sheets (PNG), CSV, and XLSX
- Render timecode labels on thumbnails
- Keep XLSX files small via physical image resizing (Pillow), or fall back to visual scaling
Works on Linux, macOS, and Windows.
- Screenshots saved to
./images/<video_name>/f########.jpg(or .png) - In-player gallery overlay:
- Grid navigation with paging
- Click to seek to a screenshot's timestamp
- Exports:
- Contact sheets (per page or all pages) →
./exports/<video>_contact_sheet_pXX.png - CSV (filename, timecode, seconds, frame) →
./exports/<video>_gallery.csv - XLSX via Python (
xlsxwriter, optionalPillow) →./exports/<video>.xlsx- Horizontal and vertical centering of images and text
- Row height adjusted to the image height
- Physical image resizing with Pillow (smaller XLSX); fallback to visual scaling if Pillow is not available
- Contact sheets (per page or all pages) →
- Timecode labels rendered into thumbnails (via ffmpeg filters)
- Cross-platform; ffmpeg used where available, mpv fallback where possible
- Safe margins are now relative to the viewport size:
SAFE_MARGIN_*_RELare fractions of width/height;GRID_GAPremains in pixels.
- Fullscreen alignment fix:
- Thumbnails are positioned using absolute OSD coordinates, so they match the clickable zones regardless of video vs. screen aspect ratio.
- Screenshot resolution control:
- Configurable scale and minimum dimensions; preserves aspect ratio and never upscales above the source.
- Clear limit for gallery size:
- Maximum thumbnails per page: 63 (example: 9×7 grid).
All settings are configured at the top of the script.
- mpv (0.35+ recommended; older builds may still work)
- ffmpeg in PATH (for labeled thumbnails and contact sheet composition)
- Python 3 (only for XLSX export)
xlsxwriteris requiredPillow(optional) enables physical resizing of images for smaller XLSX files
Install Python packages:
pip install xlsxwriter pillow- Place
gallery_screenshots.luainto your mpvscriptsfolder. - Place
gallery_xlsx_export.pynext to the Lua file (same folder). - Restart mpv.
Python virtual environment (recommended):
- Linux/macOS:
python3 -m venv ~/venv-mpv source ~/venv-mpv/bin/activate pip install xlsxwriter pillow which python # Then set PYTHON_PATH in the Lua script to the path printed by `which python`
- Windows (PowerShell):
py -m venv C:\venv-mpv C:\venv-mpv\Scripts\Activate.ps1 pip install xlsxwriter pillow # Then set PYTHON_PATH = "C:\\venv-mpv\\Scripts\\python.exe"
Open the Lua file and adjust the user‑configurable variables at the top section. Defaults shown below may differ from your copy.
PYTHON_PATH(string or nil): Absolute path to Python interpreter. Leavenilto auto‑detect. It is recommended to set it up according to the instructions above.XLSX_SCRIPT_NAME(string): Python exporter script name (kept next to the Lua script).
GRID_COLS(int): Number of columns per page.GRID_ROWS(int): Number of rows per page.GRID_GAP(int, px): Gap between tiles and edges.SAFE_MARGIN_TOP_REL(0–1, of viewport height)SAFE_MARGIN_BOTTOM_REL(0–1, of viewport height)SAFE_MARGIN_LEFT_REL(0–1, of viewport width)SAFE_MARGIN_RIGHT_REL(0–1, of viewport width)
Notes:
- Maximum thumbnails per page is 63. Ensure
GRID_COLS × GRID_ROWS ≤ 63(e.g., 9×7). - Margins scale with the window; the gap remains constant in pixels.
SCREENSHOT_SCALE(0.01–1.0): Base downscale factor for saved screenshots (e.g.,0.5→ 50%).SCREENSHOT_MIN_WIDTH(int, px): Minimum width; enforced without upscaling.SCREENSHOT_MIN_HEIGHT(int, px): Minimum height; enforced without upscaling.
Behavior:
- Preserves aspect ratio.
- Applies scale and then ensures the result meets the minimum width/height.
- Never upscales beyond the source dimensions.
ENABLE_TIME_LABELS(bool): Draw HH:MM:SS into thumbnails.LABEL_BOX_ALPHA(0–1): Opacity of the time label background box.LABEL_MARGIN_X,LABEL_MARGIN_Y(int, px): Text padding inside the box.LABEL_REL_SIZE(0–1): Relative font size based on tile size.SELECT_BOX_ALPHA(0–1): Opacity of the red bottom strip indicating selection.
DIR_IMAGES_BASE(string): Per‑video screenshots folder:./images/<video_name>/.DIR_EXPORTS_NAME(string): Sibling exports folder:./exports/.
XLSX_IMG_SCALE(0.15–0.35 recommended): Image scale for XLSX export.- With Pillow: physical resizing (smaller XLSX).
- Without Pillow: Excel visual scaling (larger XLSX, same look).
Default key bindings (can be customized):
s Save screenshot → ./images/<video_name>/f########.jpg
g Toggle gallery overlay on/off
In gallery:
Click Seek to clicked thumbnail's time
m Toggle selection on a tile
[ / ] Previous / Next page
a Select/Unselect all (current page)
d Delete selected (files + cache)
Shift+c Export contact sheet (current page) → ./exports/<video>_contact_sheet_pXX.png
c Export contact sheets for all pages
e Export CSV → ./exports/<video>_gallery.csv
x Export XLSX → ./exports/<video>.xlsx
- Thumbnails are cached as raw BGRA in
./images/<video>/.gallery_bgra/and rebuilt when window size changes.
- Contact sheets (PNG): ffmpeg
tilefilter composes the page (padding/margins from your grid settings). - CSV:
filename,timecode(HH:MM:SS),seconds(float),frame(if derivable from filename). - XLSX (Python):
- Images in column A, timecodes in column B
- Horizontal and vertical centering
- Row height set to the image height
- Physical resizing with Pillow; otherwise visual scaling
For a video at .../movie.ext:
.../images/movie/ # per-video screenshots
.../images/movie/.gallery_bgra # cached BGRA tiles (auto-managed)
.../exports/ # contact sheets, CSV, XLSX
Screenshots are named f########.jpg by default (based on estimated frame number).
- ffmpeg not found:
- Install ffmpeg and ensure it’s in PATH.
- Python not found (XLSX):
- Set
PYTHON_PATHin the Lua script or ensurepython3/pythonis in PATH.
- Set
- XLSX too large:
- Install Pillow to enable physical resizing; lower
XLSX_IMG_SCALE.
- Install Pillow to enable physical resizing; lower
- Gallery looks offset in fullscreen:
- Fixed in this version (absolute OSD coordinates). If you still see issues, ensure you’re running the latest script.
- Logging:
- Run mpv with logging to capture script output:
mpv --log-file=mpv.log --msg-level=script=trace yourvideo.mkv
- Run mpv with logging to capture script output:
MIT License. See LICENSE.
- mpv authors and contributors
- ffmpeg project
- xlsxwriter and Pillow authors
- Community testers and issue reporters