LastFrame is a simple command-line tool for extracting the last frame from MP4 video files using OpenCV (cv2)
Project description
LastFrame
Overview
LastFrame is a simple command-line tool for extracting the last frame from MP4 video files using OpenCV (cv2), providing multiple fallback methods for reliable frame seeking even with varying codecs or formats. It scans the current directory for MP4 files (case-insensitive), lists them with file sizes, allows interactive selection, and saves the frame as an image (PNG by default, supporting JPG, JPEG, BMP, TIFF). As a Cython (CyMaster type) project, it optimizes video capture and frame reading operations through compiled extensions for faster performance in media analysis tasks . The tool includes user-friendly prompts, error handling for invalid videos, and pauses for result review, making it suitable for quick thumbnail generation or endpoint inspection without full video processing .
Features
- Automatic discovery of MP4 files in the current directory using glob patterns (handles case variations like .mp4, .MP4).
- Interactive numbered list display with file sizes in MB for easy selection.
- Robust last-frame extraction: Primary method uses frame count seeking; fallbacks include time-ratio (99%) and millisecond positioning for accuracy across videos.
- Flexible output naming: Defaults to "output.png" or "{video_stem}_last.png"; auto-appends image extension if missing.
- Success/failure feedback with method details (e.g., "using frame count").
- Cython compilation support for performance gains in OpenCV interactions, generating architecture-specific binaries like InstallPip.cpython-312-x86_64-linux-gnu.so equivalents for LastFrame .
- No temporary files; direct save via cv2.imwrite with resource cleanup (cap.release()).
Prerequisites
- Python 3.6+ (recommend 3.12; use pyenv for management:
curl https://pyenv.run | bash, add to~/.bashrc, thenpyenv install 3.12.0andpyenv shell 3.12.0for isolation) . - OpenCV: Installed via pip (see Installation).
- C compiler (gcc on Linux/macOS, MSVC on Windows) for Cython builds.
- Git for repository management (recommended:
git initto start tracking changes, excluding artifacts) .
For development, create a virtual environment: python3 -m venv venv; source venv/bin/activate (Windows: venv\Scripts\activate) to avoid global conflicts .
Installation
From Source (Recommended for Development)
-
Clone or download the repository:
git clone <repo-url> cd LastFrame -
Initialize Git if needed (for version control):
git init.
-
Configure
.gitignoreto exclude build artifacts, caches, and environment files:# .gitignore content .env __pycache__/ *.pyc *.pyo *.so build/This keeps the repo clean, ignoring compiled modules like LastFrame.cpython-312-x86_64-linux-gnu.so .
-
Create
requirements.txtfor dependencies (example):opencv-python ChronicleLogger cython # For buildsInstall them:
pip3 install -r requirements.txtEnsures reproducible setup across environments .
-
Build and install in editable mode (compiles Cython extensions):
# Install Cython if not in requirements pip install cython # Run build script (POSIX-compliant) chmod +x build.sh ./build.sh # e.g., cythonize src/LastFrame/cli.pyx and python -m build # Editable install pip install -e .This generates outputs in
build/lib/(e.g., LastFrame.cpython-310-arm-linux-gnueabihf.so for ARM) and makes the package importable .
Via pip (Packaged Release)
For the published version on PyPI:
pip3 install LastFrame
This installs OpenCV and other dependencies automatically, setting up the entry point for python -m LastFrame .
Commit initial setup:
git add .
git commit -m "Initial commit"
.
Usage
Command-Line Execution
Place MP4 files in the current directory and run:
python -m src.LastFrame
Or after installation:
python -m LastFrame
(Configure console_scripts in pyproject.toml for a lastframe command if desired.)
Example interactive session:
Found MP4 videos:
1. sample.mp4 (23.5 MB)
2. demo.MP4 (8.2 MB)
Enter video number (1-2): 1
Selected: sample.mp4
Enter output image filename [default: output.png]: end_frame.jpg
Extracting last frame from 'sample.mp4'...
Success: Last frame saved as 'end_frame.jpg'
Done! Image saved as: end_frame.jpg
Press Enter to exit...
The tool pauses at the end for viewing results .
For scripting, import and call: from LastFrame.cli import main; main() .
Building for Distribution
- Use
python -m build(viapyproject.toml) to create wheels/sdists. - Outputs go to
build/(gitignore them); supports architectures like x86_64-linux-gnu or arm-linux-gnueabihf .
Project Structure
The structure follows Cython best practices for maintainability, with src/ isolating code, docs/ for specifications, and build/ for artifacts (excluded via .gitignore). Create folders with mkdir -p docs src/LastFrame tests if extending .
LastFrame/
├── build.sh # Build script for Cython (e.g., cythonize and setup.py build_ext --inplace)
├── docs/ # Documentation and specs
│ ├── CHANGELOG.md
│ ├── folder-structure.md
│ └── LastFrame-spec.md
├── pyproject.toml # Build config with Cython directives (language_level=3)
├── README.md # This file
└── src/
└── LastFrame/
├── cli.py # CLI logic: glob discovery, selection, extraction
├── __init__.py # Package init (exposes ChronicleLogger; rename suggested)
└── __main__.py # Entry point
Add tests/ for validation (e.g., touch tests/test_cli.py) and docs/update-log.md for extended notes .
Development
- Extensions: Add batch support or more formats by modifying glob in
cli.py(preserve existing code with# NEW:comments). - Testing: Install pytest via requirements.txt; run
pytest tests/to validate cv2 mocks. - Versioning: Update
__version__in__init__.pyand CHANGELOG.md; use semantic releases. - Logging: Integrate ChronicleLogger for traceable outputs (currently imported but unused).
- Touch additional files like
backend/app/main.pyortests/test_main.pyfor modular growth, following patterns liketouch requirements.txt.
Troubleshooting
- OpenCV Import Error: Run
pip3 install opencv-python; verify withpython3 -c "import cv2". - Video Open Failure: Ensure MP4 integrity; test with
cv2.VideoCapture('file.mp4').isOpened(). - Cython Build Issues: Check Python version (
which python3); setlanguage_level=3in pyproject.toml; use pyenv for consistency . - Permissions:
chmod +x build.shon Unix; virtualenv avoids conflicts. - No video found? Verify
os.getcwd()and file extensions.
For issues, reference docs/LastFrame-spec.md or open a Git issue after git init .
License
MIT License (add LICENSE file with standard MIT text for open-source distribution) .
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lastframe-1.0.1.tar.gz.
File metadata
- Download URL: lastframe-1.0.1.tar.gz
- Upload date:
- Size: 6.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
459be68fd9ac16b2659a5147b6102da8ee29f04412b541b805fb6cf2e052210b
|
|
| MD5 |
1c46feb34a0c9ac30fbbdf6ede4441b8
|
|
| BLAKE2b-256 |
d43efc3c858d7432c7e5f67153cbc2de0b490e1a7d44ea529e44409b863cbc4a
|
File details
Details for the file lastframe-1.0.1-py3-none-any.whl.
File metadata
- Download URL: lastframe-1.0.1-py3-none-any.whl
- Upload date:
- Size: 6.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ec84c817fd05600e394b3af597cf20301be90d6ec893956043cf9ea62e4edb6
|
|
| MD5 |
5906d299a30e37abfeaf26c4dbe2f3af
|
|
| BLAKE2b-256 |
4abe834300a893b05ad7d06c5b178c86efc983765a3fdfbf407385ffde606e86
|