FirstFrame 1.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,158 @@
1
+ Metadata-Version: 2.4
2
+ Name: FirstFrame
3
+ Version: 1.0.1
4
+ Summary: FirstFrame is a simple command-line tool for extracting the last frame from MP4 video files using OpenCV (cv2)
5
+ Author-email: Wilgat Wong <wilgat.wong@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Wilgat/FirstFrame
8
+ Project-URL: Repository, https://github.com/Wilgat/FirstFrame
9
+ Project-URL: Issues, https://github.com/Wilgat/FirstFrame/issues
10
+ Keywords: logging,sudo,chronicle,example
11
+ Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: ChronicleLogger>=1.2.3
14
+ Requires-Dist: opencv-python
15
+
16
+ # FirstFrame
17
+
18
+ ## Overview
19
+
20
+ **FirstFrame** is a lightweight command-line tool that extracts the **first frame** from MP4 video files using OpenCV (`cv2`).
21
+
22
+ It automatically scans the current directory for `.mp4` files (case-insensitive), displays an interactive numbered list with file sizes, lets the user select a video, and saves the first frame as an image file (PNG by default; supports JPG, JPEG, BMP, TIFF).
23
+
24
+ The tool features clear prompts, basic error handling, and a pause at the end — perfect for quick thumbnail generation, cover image creation, or inspecting video starts without loading the entire file.
25
+
26
+ ## Features
27
+
28
+ - Finds all `.mp4` / `.MP4` / `.Mp4` files in the current folder using `glob`
29
+ - Shows numbered list with file sizes (in MB) for easy selection
30
+ - Extracts the very first frame reliably with a single `cap.read()` call
31
+ - Smart default output filename: `output.png` (if free) or `{video_name}_first.png`
32
+ - Automatically adds `.png` extension if user input lacks an image suffix
33
+ - Clean resource handling (`cap.release()`) — no temporary files
34
+ - User-friendly success/error messages and final confirmation
35
+
36
+ ## Prerequisites
37
+
38
+ - Python 3.8+ (recommended: 3.10–3.12)
39
+ - `opencv-python` (installed via pip)
40
+ - Optional: virtual environment (`venv` or `uv`)
41
+
42
+ No C compiler or Cython is required for normal usage — the project is currently pure Python.
43
+
44
+ ## Installation
45
+
46
+ ### Development / Source Install (Editable)
47
+
48
+ ```bash
49
+ # 1. Clone or download the repo
50
+ git clone <your-repo-url>
51
+ cd FirstFrame
52
+
53
+ # 2. (Recommended) Create & activate virtual environment
54
+ python3 -m venv venv
55
+ source venv/bin/activate # Windows: venv\Scripts\activate
56
+
57
+ # 3. Install dependencies
58
+ pip install opencv-python
59
+ # If you later add ChronicleLogger or others → add them here
60
+
61
+ # 4. Install project in editable mode
62
+ pip install -e .
63
+ ```
64
+
65
+ Now you can run it with:
66
+
67
+ ```bash
68
+ python -m FirstFrame
69
+ ```
70
+
71
+ ### Future PyPI Release (when ready)
72
+
73
+ ```bash
74
+ pip install firstframe
75
+ ```
76
+
77
+ (You would then publish it via `python -m build` + twine, and configure `console_scripts` in `pyproject.toml` for a `firstframe` command.)
78
+
79
+ ## Usage
80
+
81
+ Place your MP4 videos in the current directory and run:
82
+
83
+ ```bash
84
+ python -m FirstFrame
85
+ ```
86
+
87
+ Example session:
88
+
89
+ ```
90
+ Found MP4 videos:
91
+
92
+ 1. intro.mp4 (12.4 MB)
93
+ 2. demo.MP4 (45.8 MB)
94
+
95
+ Enter video number (1-2): 1
96
+
97
+ Selected: intro.mp4
98
+ Enter output image filename [default: output.png]:
99
+
100
+ Extracting first frame from 'intro.mp4'...
101
+ Success: First frame saved as 'output.png'
102
+
103
+ Done! Image saved as: output.png
104
+
105
+ Press Enter to exit...
106
+ ```
107
+
108
+ Or specify a custom name:
109
+
110
+ ```
111
+ Enter output image filename [default: intro_first.png]: cover.jpg
112
+ ```
113
+
114
+ The tool saves the image and waits for you to press Enter before closing.
115
+
116
+ For scripting / automation:
117
+
118
+ ```python
119
+ from FirstFrame.__main__ import main
120
+ main()
121
+ ```
122
+
123
+ ## Project Structure
124
+
125
+ Follows modern Python packaging conventions with `src/` layout:
126
+
127
+ ```
128
+ FirstFrame/
129
+ ├── README.md
130
+ ├── pyproject.toml # (add when packaging properly)
131
+ ├── src/
132
+ │ └── FirstFrame/
133
+ │ ├── __init__.py
134
+ │ └── __main__.py # Main logic + entry point
135
+ └── (optional future folders)
136
+ ├── tests/
137
+ └── docs/
138
+ ```
139
+
140
+ ## Development Notes
141
+
142
+ - The core logic lives in `src/FirstFrame/__main__.py`
143
+ - To add features (batch mode, other formats, progress bar…): edit the `main()` and `get_first_frame()` functions
144
+ - Logging: `ChronicleLogger` is imported but unused — either integrate it or remove the import
145
+ - Tests: Consider adding `tests/` folder + `pytest` later
146
+ - Packaging: When ready, add `pyproject.toml` with `build-system = {requires = ["hatchling"], build-backend = "hatchling.build"}` (or setuptools)
147
+
148
+ ## Troubleshooting
149
+
150
+ - **Cannot open video** → Check file path, integrity, and codec support in your OpenCV build
151
+ - **No MP4 files found** → Make sure videos are in the current working directory (`pwd`)
152
+ - **OpenCV not found** → `pip install opencv-python`
153
+ - **Permission denied on save** → Check write permissions in current folder
154
+
155
+ ## License
156
+
157
+ MIT License
158
+ (Add a `LICENSE` file with the standard MIT text when you publish or share the repo.)
@@ -0,0 +1,143 @@
1
+ # FirstFrame
2
+
3
+ ## Overview
4
+
5
+ **FirstFrame** is a lightweight command-line tool that extracts the **first frame** from MP4 video files using OpenCV (`cv2`).
6
+
7
+ It automatically scans the current directory for `.mp4` files (case-insensitive), displays an interactive numbered list with file sizes, lets the user select a video, and saves the first frame as an image file (PNG by default; supports JPG, JPEG, BMP, TIFF).
8
+
9
+ The tool features clear prompts, basic error handling, and a pause at the end — perfect for quick thumbnail generation, cover image creation, or inspecting video starts without loading the entire file.
10
+
11
+ ## Features
12
+
13
+ - Finds all `.mp4` / `.MP4` / `.Mp4` files in the current folder using `glob`
14
+ - Shows numbered list with file sizes (in MB) for easy selection
15
+ - Extracts the very first frame reliably with a single `cap.read()` call
16
+ - Smart default output filename: `output.png` (if free) or `{video_name}_first.png`
17
+ - Automatically adds `.png` extension if user input lacks an image suffix
18
+ - Clean resource handling (`cap.release()`) — no temporary files
19
+ - User-friendly success/error messages and final confirmation
20
+
21
+ ## Prerequisites
22
+
23
+ - Python 3.8+ (recommended: 3.10–3.12)
24
+ - `opencv-python` (installed via pip)
25
+ - Optional: virtual environment (`venv` or `uv`)
26
+
27
+ No C compiler or Cython is required for normal usage — the project is currently pure Python.
28
+
29
+ ## Installation
30
+
31
+ ### Development / Source Install (Editable)
32
+
33
+ ```bash
34
+ # 1. Clone or download the repo
35
+ git clone <your-repo-url>
36
+ cd FirstFrame
37
+
38
+ # 2. (Recommended) Create & activate virtual environment
39
+ python3 -m venv venv
40
+ source venv/bin/activate # Windows: venv\Scripts\activate
41
+
42
+ # 3. Install dependencies
43
+ pip install opencv-python
44
+ # If you later add ChronicleLogger or others → add them here
45
+
46
+ # 4. Install project in editable mode
47
+ pip install -e .
48
+ ```
49
+
50
+ Now you can run it with:
51
+
52
+ ```bash
53
+ python -m FirstFrame
54
+ ```
55
+
56
+ ### Future PyPI Release (when ready)
57
+
58
+ ```bash
59
+ pip install firstframe
60
+ ```
61
+
62
+ (You would then publish it via `python -m build` + twine, and configure `console_scripts` in `pyproject.toml` for a `firstframe` command.)
63
+
64
+ ## Usage
65
+
66
+ Place your MP4 videos in the current directory and run:
67
+
68
+ ```bash
69
+ python -m FirstFrame
70
+ ```
71
+
72
+ Example session:
73
+
74
+ ```
75
+ Found MP4 videos:
76
+
77
+ 1. intro.mp4 (12.4 MB)
78
+ 2. demo.MP4 (45.8 MB)
79
+
80
+ Enter video number (1-2): 1
81
+
82
+ Selected: intro.mp4
83
+ Enter output image filename [default: output.png]:
84
+
85
+ Extracting first frame from 'intro.mp4'...
86
+ Success: First frame saved as 'output.png'
87
+
88
+ Done! Image saved as: output.png
89
+
90
+ Press Enter to exit...
91
+ ```
92
+
93
+ Or specify a custom name:
94
+
95
+ ```
96
+ Enter output image filename [default: intro_first.png]: cover.jpg
97
+ ```
98
+
99
+ The tool saves the image and waits for you to press Enter before closing.
100
+
101
+ For scripting / automation:
102
+
103
+ ```python
104
+ from FirstFrame.__main__ import main
105
+ main()
106
+ ```
107
+
108
+ ## Project Structure
109
+
110
+ Follows modern Python packaging conventions with `src/` layout:
111
+
112
+ ```
113
+ FirstFrame/
114
+ ├── README.md
115
+ ├── pyproject.toml # (add when packaging properly)
116
+ ├── src/
117
+ │ └── FirstFrame/
118
+ │ ├── __init__.py
119
+ │ └── __main__.py # Main logic + entry point
120
+ └── (optional future folders)
121
+ ├── tests/
122
+ └── docs/
123
+ ```
124
+
125
+ ## Development Notes
126
+
127
+ - The core logic lives in `src/FirstFrame/__main__.py`
128
+ - To add features (batch mode, other formats, progress bar…): edit the `main()` and `get_first_frame()` functions
129
+ - Logging: `ChronicleLogger` is imported but unused — either integrate it or remove the import
130
+ - Tests: Consider adding `tests/` folder + `pytest` later
131
+ - Packaging: When ready, add `pyproject.toml` with `build-system = {requires = ["hatchling"], build-backend = "hatchling.build"}` (or setuptools)
132
+
133
+ ## Troubleshooting
134
+
135
+ - **Cannot open video** → Check file path, integrity, and codec support in your OpenCV build
136
+ - **No MP4 files found** → Make sure videos are in the current working directory (`pwd`)
137
+ - **OpenCV not found** → `pip install opencv-python`
138
+ - **Permission denied on save** → Check write permissions in current folder
139
+
140
+ ## License
141
+
142
+ MIT License
143
+ (Add a `LICENSE` file with the standard MIT text when you publish or share the repo.)
@@ -0,0 +1,30 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "FirstFrame"
7
+ version = "1.0.1"
8
+ description = "FirstFrame is a simple command-line tool for extracting the last frame from MP4 video files using OpenCV (cv2)"
9
+ readme = "README.md"
10
+ requires-python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ {name = "Wilgat Wong", email = "wilgat.wong@gmail.com"}
14
+ ]
15
+ keywords = ["logging", "sudo", "chronicle", "example"]
16
+
17
+ dependencies = [
18
+ "ChronicleLogger>=1.2.3",
19
+ "opencv-python"
20
+ ]
21
+
22
+ # Official project links (this is what shows on PyPI!)
23
+ [project.urls]
24
+ Homepage = "https://github.com/Wilgat/FirstFrame"
25
+ Repository = "https://github.com/Wilgat/FirstFrame"
26
+ Issues = "https://github.com/Wilgat/FirstFrame/issues"
27
+
28
+ # This makes `first-frame` command available after pip install
29
+ [project.scripts]
30
+ first-frame = "FirstFrame.cli:main"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,158 @@
1
+ Metadata-Version: 2.4
2
+ Name: FirstFrame
3
+ Version: 1.0.1
4
+ Summary: FirstFrame is a simple command-line tool for extracting the last frame from MP4 video files using OpenCV (cv2)
5
+ Author-email: Wilgat Wong <wilgat.wong@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Wilgat/FirstFrame
8
+ Project-URL: Repository, https://github.com/Wilgat/FirstFrame
9
+ Project-URL: Issues, https://github.com/Wilgat/FirstFrame/issues
10
+ Keywords: logging,sudo,chronicle,example
11
+ Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: ChronicleLogger>=1.2.3
14
+ Requires-Dist: opencv-python
15
+
16
+ # FirstFrame
17
+
18
+ ## Overview
19
+
20
+ **FirstFrame** is a lightweight command-line tool that extracts the **first frame** from MP4 video files using OpenCV (`cv2`).
21
+
22
+ It automatically scans the current directory for `.mp4` files (case-insensitive), displays an interactive numbered list with file sizes, lets the user select a video, and saves the first frame as an image file (PNG by default; supports JPG, JPEG, BMP, TIFF).
23
+
24
+ The tool features clear prompts, basic error handling, and a pause at the end — perfect for quick thumbnail generation, cover image creation, or inspecting video starts without loading the entire file.
25
+
26
+ ## Features
27
+
28
+ - Finds all `.mp4` / `.MP4` / `.Mp4` files in the current folder using `glob`
29
+ - Shows numbered list with file sizes (in MB) for easy selection
30
+ - Extracts the very first frame reliably with a single `cap.read()` call
31
+ - Smart default output filename: `output.png` (if free) or `{video_name}_first.png`
32
+ - Automatically adds `.png` extension if user input lacks an image suffix
33
+ - Clean resource handling (`cap.release()`) — no temporary files
34
+ - User-friendly success/error messages and final confirmation
35
+
36
+ ## Prerequisites
37
+
38
+ - Python 3.8+ (recommended: 3.10–3.12)
39
+ - `opencv-python` (installed via pip)
40
+ - Optional: virtual environment (`venv` or `uv`)
41
+
42
+ No C compiler or Cython is required for normal usage — the project is currently pure Python.
43
+
44
+ ## Installation
45
+
46
+ ### Development / Source Install (Editable)
47
+
48
+ ```bash
49
+ # 1. Clone or download the repo
50
+ git clone <your-repo-url>
51
+ cd FirstFrame
52
+
53
+ # 2. (Recommended) Create & activate virtual environment
54
+ python3 -m venv venv
55
+ source venv/bin/activate # Windows: venv\Scripts\activate
56
+
57
+ # 3. Install dependencies
58
+ pip install opencv-python
59
+ # If you later add ChronicleLogger or others → add them here
60
+
61
+ # 4. Install project in editable mode
62
+ pip install -e .
63
+ ```
64
+
65
+ Now you can run it with:
66
+
67
+ ```bash
68
+ python -m FirstFrame
69
+ ```
70
+
71
+ ### Future PyPI Release (when ready)
72
+
73
+ ```bash
74
+ pip install firstframe
75
+ ```
76
+
77
+ (You would then publish it via `python -m build` + twine, and configure `console_scripts` in `pyproject.toml` for a `firstframe` command.)
78
+
79
+ ## Usage
80
+
81
+ Place your MP4 videos in the current directory and run:
82
+
83
+ ```bash
84
+ python -m FirstFrame
85
+ ```
86
+
87
+ Example session:
88
+
89
+ ```
90
+ Found MP4 videos:
91
+
92
+ 1. intro.mp4 (12.4 MB)
93
+ 2. demo.MP4 (45.8 MB)
94
+
95
+ Enter video number (1-2): 1
96
+
97
+ Selected: intro.mp4
98
+ Enter output image filename [default: output.png]:
99
+
100
+ Extracting first frame from 'intro.mp4'...
101
+ Success: First frame saved as 'output.png'
102
+
103
+ Done! Image saved as: output.png
104
+
105
+ Press Enter to exit...
106
+ ```
107
+
108
+ Or specify a custom name:
109
+
110
+ ```
111
+ Enter output image filename [default: intro_first.png]: cover.jpg
112
+ ```
113
+
114
+ The tool saves the image and waits for you to press Enter before closing.
115
+
116
+ For scripting / automation:
117
+
118
+ ```python
119
+ from FirstFrame.__main__ import main
120
+ main()
121
+ ```
122
+
123
+ ## Project Structure
124
+
125
+ Follows modern Python packaging conventions with `src/` layout:
126
+
127
+ ```
128
+ FirstFrame/
129
+ ├── README.md
130
+ ├── pyproject.toml # (add when packaging properly)
131
+ ├── src/
132
+ │ └── FirstFrame/
133
+ │ ├── __init__.py
134
+ │ └── __main__.py # Main logic + entry point
135
+ └── (optional future folders)
136
+ ├── tests/
137
+ └── docs/
138
+ ```
139
+
140
+ ## Development Notes
141
+
142
+ - The core logic lives in `src/FirstFrame/__main__.py`
143
+ - To add features (batch mode, other formats, progress bar…): edit the `main()` and `get_first_frame()` functions
144
+ - Logging: `ChronicleLogger` is imported but unused — either integrate it or remove the import
145
+ - Tests: Consider adding `tests/` folder + `pytest` later
146
+ - Packaging: When ready, add `pyproject.toml` with `build-system = {requires = ["hatchling"], build-backend = "hatchling.build"}` (or setuptools)
147
+
148
+ ## Troubleshooting
149
+
150
+ - **Cannot open video** → Check file path, integrity, and codec support in your OpenCV build
151
+ - **No MP4 files found** → Make sure videos are in the current working directory (`pwd`)
152
+ - **OpenCV not found** → `pip install opencv-python`
153
+ - **Permission denied on save** → Check write permissions in current folder
154
+
155
+ ## License
156
+
157
+ MIT License
158
+ (Add a `LICENSE` file with the standard MIT text when you publish or share the repo.)
@@ -0,0 +1,11 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/FirstFrame.egg-info/PKG-INFO
4
+ src/FirstFrame.egg-info/SOURCES.txt
5
+ src/FirstFrame.egg-info/dependency_links.txt
6
+ src/FirstFrame.egg-info/entry_points.txt
7
+ src/FirstFrame.egg-info/requires.txt
8
+ src/FirstFrame.egg-info/top_level.txt
9
+ src/LastFrame/__init__.py
10
+ src/LastFrame/__main__.py
11
+ src/LastFrame/cli.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ first-frame = FirstFrame.cli:main
@@ -0,0 +1,2 @@
1
+ ChronicleLogger>=1.2.3
2
+ opencv-python
@@ -0,0 +1 @@
1
+ LastFrame
@@ -0,0 +1,4 @@
1
+ from .cli import ChronicleLogger
2
+
3
+ __version__ = "1.0.1"
4
+ __all__ = ["ChronicleLogger"]
@@ -0,0 +1,4 @@
1
+ from .cli import main
2
+
3
+ if __name__ == "__main__":
4
+ main()
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env python
2
+ from __future__ import print_function, unicode_literals
3
+
4
+ from ChronicleLogger import ChronicleLogger
5
+ import sys
6
+ import cv2
7
+ import os
8
+ import glob
9
+
10
+ def get_last_frame(video_path, output_path):
11
+ """Extract the last frame from video and save it."""
12
+ cap = cv2.VideoCapture(video_path)
13
+ if not cap.isOpened():
14
+ print("Error: Cannot open video file.")
15
+ return False
16
+
17
+ # Method 1: Try by frame count (most accurate)
18
+ total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
19
+ if total_frames > 1:
20
+ cap.set(cv2.CAP_PROP_POS_FRAMES, total_frames - 1)
21
+ ret, frame = cap.read()
22
+ if ret:
23
+ cv2.imwrite(output_path, frame)
24
+ cap.release()
25
+ print(f"Success: Last frame saved as '{output_path}'")
26
+ return True
27
+
28
+ # Method 2: Fallback - seek to 99% of video
29
+ cap.set(cv2.CAP_PROP_POS_AVI_RATIO, 0.99)
30
+ ret, frame = cap.read()
31
+ if ret:
32
+ cv2.imwrite(output_path, frame)
33
+ cap.release()
34
+ print(f"Success: Last frame saved as '{output_path}' (using time-based seek)")
35
+ return True
36
+
37
+ # Method 3: Use millisecond seek
38
+ fps = cap.get(cv2.CAP_PROP_FPS)
39
+ if fps > 0:
40
+ duration_ms = (total_frames / fps) * 1000
41
+ cap.set(cv2.CAP_PROP_POS_MSEC, duration_ms - 100) # 0.1s before end
42
+ ret, frame = cap.read()
43
+ if ret:
44
+ cv2.imwrite(output_path, frame)
45
+ cap.release()
46
+ print(f"Success: Last frame saved as '{output_path}' (millisecond seek)")
47
+ return True
48
+
49
+ cap.release()
50
+ print("Failed: Could not extract the last frame.")
51
+ return False
52
+
53
+
54
+ def main():
55
+ # Find all .mp4 files in current directory (case-insensitive)
56
+ mp4_files = glob.glob("*.mp4") + glob.glob("*.MP4") + glob.glob("*.Mp4")
57
+ mp4_files = sorted(set(mp4_files)) # Remove duplicates, sort nicely
58
+
59
+ if not mp4_files:
60
+ print("No .mp4 videos found in the current folder!")
61
+ print(f"Current directory: {os.getcwd()}")
62
+ input("\nPress Enter to exit...")
63
+ return
64
+
65
+ # Display numbered list
66
+ print("\nFound MP4 videos:\n")
67
+ for i, filename in enumerate(mp4_files, 1):
68
+ size_mb = os.path.getsize(filename) / (1024 * 1024)
69
+ print(f" {i:2d}. {filename} ({size_mb:.1f} MB)")
70
+
71
+ # Get user choice
72
+ while True:
73
+ try:
74
+ choice = input(f"\nEnter video number (1-{len(mp4_files)}): ").strip()
75
+ if not choice:
76
+ print("Please enter a number.")
77
+ continue
78
+ idx = int(choice) - 1
79
+ if 0 <= idx < len(mp4_files):
80
+ selected_video = mp4_files[idx]
81
+ break
82
+ else:
83
+ print(f"Please enter a number between 1 and {len(mp4_files)}.")
84
+ except ValueError:
85
+ print("Invalid input. Please type a number.")
86
+
87
+ # Suggest default output: either output.png or video_name_last.png
88
+ base_name = os.path.splitext(selected_video)[0]
89
+ default_output = "output.png" if os.path.exists("output.png") == False else f"{base_name}_last.png"
90
+
91
+ print(f"\nSelected: {selected_video}")
92
+
93
+ # Ask for output filename
94
+ user_output = input(f"Enter output image filename [default: {default_output}]: ").strip()
95
+ if not user_output:
96
+ output_path = default_output
97
+ else:
98
+ # Ensure it has an image extension
99
+ if not user_output.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.tiff')):
100
+ output_path = user_output + ".png"
101
+ else:
102
+ output_path = user_output
103
+
104
+ print(f"\nExtracting last frame from '{selected_video}'...")
105
+ get_last_frame(selected_video, output_path)
106
+
107
+ print(f"\nDone! Image saved as: {output_path}")
108
+ input("\nPress Enter to exit...")
109
+
110
+
111
+ if __name__ == "__main__":
112
+ main()
113
+