VideoSpeed 1.0.4__tar.gz → 1.0.5__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,21 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2026 Wilgat Wong <wilgat.wong@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,150 @@
1
+ Metadata-Version: 2.4
2
+ Name: VideoSpeed
3
+ Version: 1.0.5
4
+ Summary: A command-line video editing tool built in Python for cutting, speeding up, and applying a boomerang effect to MP4 videos.
5
+ Author-email: Wilgat Wong <wilgat.wong@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Wilgat/VideoSpeed
8
+ Project-URL: Repository, https://github.com/Wilgat/VideoSpeed
9
+ Project-URL: Issues, https://github.com/Wilgat/VideoSpeed/issues
10
+ Keywords: Video Editing,Multimeida
11
+ Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE.md
14
+ Requires-Dist: ChronicleLogger>=1.2.3
15
+ Requires-Dist: opencv-python
16
+ Dynamic: license-file
17
+
18
+ # VideoSpeed - Cut, speed, and boomerang MP4 clips from the CLI
19
+
20
+ ![Version](https://img.shields.io/badge/Version-1.0.5-blue?style=flat-square)
21
+ ![License](https://img.shields.io/badge/License-MIT-green?style=flat-square)
22
+ [![CIAO](https://img.shields.io/badge/Philosophy-CIAO%20(Caution%20%E2%80%A2%20Intentional%20%E2%80%A2%20Anti--fragile%20%E2%80%A2%20Over--engineered)-purple.svg)](https://github.com/cloudgen/ciao)
23
+ [![Stars](https://img.shields.io/github/stars/Wilgat/VideoSpeed?style=flat-square)](https://github.com/Wilgat/VideoSpeed)
24
+ [![Python](https://img.shields.io/badge/Python-2.7%2B-blue?style=flat-square)]()
25
+ [![PyPI](https://img.shields.io/pypi/v/VideoSpeed?style=flat-square)](https://pypi.org/project/VideoSpeed/)
26
+
27
+ VideoSpeed is an interactive command-line tool for short MP4 edits: pick a folder of videos, cut a time range, change length/speed (percent), and optionally append a boomerang (forward + reverse). Encoding uses **FFmpeg**; duration probing uses **OpenCV**.
28
+
29
+ Package version SSOT: `pyproject.toml` and `src/VideoSpeed/__init__.py` (**1.0.5**). Console entrypoint: `video-speed`.
30
+
31
+ ## Features
32
+
33
+ - Recursive **MP4** discovery under a chosen folder
34
+ - Interactive **cut** (start/end seconds) with invalid-range re-prompt
35
+ - **Length/speed** change (**20–200%**) with A/V tempo kept in sync
36
+ - Optional **boomerang** (forward then reverse)
37
+ - **USB-safe** intermediate files (staged next to the output) and final publish via `shutil.move`
38
+ - **`--help`** / **`--version`**; bare invoke starts the interactive session (Type N)
39
+ - Fail-closed when **FFmpeg** is missing from `PATH`
40
+
41
+ ## Quick Installation
42
+
43
+ ### Prerequisites (system)
44
+
45
+ - **FFmpeg** on `PATH` (`ffmpeg -version`)
46
+ - A supported **Python** environment (see `requires-python` in `pyproject.toml`)
47
+
48
+ ### From PyPI (registry channel)
49
+
50
+ Package name SSOT: **`VideoSpeed`** (`pyproject.toml` `[project].name`). Upload path: `build.sh` (`twine upload`).
51
+
52
+ ```bash
53
+ pip install VideoSpeed
54
+ ```
55
+
56
+ If the index is behind a local release, install from a checkout or wheel instead (below). Live index version is shown by the PyPI badge above.
57
+
58
+ ### From a git checkout (development)
59
+
60
+ ```bash
61
+ git clone git@github.com:Wilgat/VideoSpeed.git
62
+ cd VideoSpeed
63
+ pip install -e .
64
+ ```
65
+
66
+ This installs the console script **`video-speed`** and pulls Python deps (`opencv-python`, `ChronicleLogger`, …).
67
+
68
+ ### From a local wheel / sdist
69
+
70
+ ```bash
71
+ # after: python -m build (or ./build.sh build)
72
+ pip install dist/VideoSpeed-1.0.5-py3-none-any.whl
73
+ # or
74
+ pip install dist/VideoSpeed-1.0.5.tar.gz
75
+ ```
76
+
77
+ ### Verify
78
+
79
+ ```bash
80
+ video-speed --version
81
+ # or
82
+ python -m VideoSpeed --version
83
+ ```
84
+
85
+ ## Usage
86
+
87
+ Interactive editor (default):
88
+
89
+ ```bash
90
+ video-speed
91
+ # or
92
+ python -m VideoSpeed
93
+ ```
94
+
95
+ 1. Folder containing MP4s (Enter = current directory)
96
+ 2. Choose a video by number
97
+ 3. Cut start/end seconds
98
+ 4. New length percent (default 100; allowed 20–200)
99
+ 5. Optional boomerang (y/n)
100
+ 6. Output is written **next to the source** with a descriptive name
101
+
102
+ Other:
103
+
104
+ ```bash
105
+ video-speed --help
106
+ video-speed --version
107
+ ```
108
+
109
+ ## Examples
110
+
111
+ ```bash
112
+ # Install editable, then run interactive session in a folder of clips
113
+ cd /path/to/videos
114
+ video-speed
115
+
116
+ # Check identity without starting prompts
117
+ video-speed --version
118
+ ```
119
+
120
+ Example output name shape:
121
+
122
+ ```text
123
+ clip_cut1.0-5.0s_100pct.mp4
124
+ clip_cut1.0-5.0s_50pct_BOOMERANG.mp4
125
+ ```
126
+
127
+ ## Platform Compatibility
128
+
129
+ | Platform | Status |
130
+ |----------|--------|
131
+ | Linux | Primary (tested in development) |
132
+ | macOS / Windows | Expected to work when Python, FFmpeg, and OpenCV are available |
133
+ | Filesystems | Local disk and removable/USB volumes supported for output (temps staged beside final path) |
134
+
135
+ ## Related Projects
136
+
137
+ - [VideoSpeed on GitHub](https://github.com/Wilgat/VideoSpeed)
138
+ - [VideoSpeed on PyPI](https://pypi.org/project/VideoSpeed/)
139
+
140
+ ## Contributing
141
+
142
+ Fork the repository, use a checkout install (`pip install -e .`), and open a pull request. Prefer small, tested changes. Do not strip defensive temp/publish behavior (cross-filesystem `shutil.move`) without an explicit redesign.
143
+
144
+ ## License
145
+
146
+ MIT License — see [`LICENSE.md`](LICENSE.md).
147
+
148
+ ## Last Update
149
+
150
+ 2026-08-09 — README aligned with product **1.0.5**, write-readme detection-driven banners (Version / License / CIAO / Stars / Python / PyPI), and install truth (PyPI + editable + wheel).
@@ -0,0 +1,133 @@
1
+ # VideoSpeed - Cut, speed, and boomerang MP4 clips from the CLI
2
+
3
+ ![Version](https://img.shields.io/badge/Version-1.0.5-blue?style=flat-square)
4
+ ![License](https://img.shields.io/badge/License-MIT-green?style=flat-square)
5
+ [![CIAO](https://img.shields.io/badge/Philosophy-CIAO%20(Caution%20%E2%80%A2%20Intentional%20%E2%80%A2%20Anti--fragile%20%E2%80%A2%20Over--engineered)-purple.svg)](https://github.com/cloudgen/ciao)
6
+ [![Stars](https://img.shields.io/github/stars/Wilgat/VideoSpeed?style=flat-square)](https://github.com/Wilgat/VideoSpeed)
7
+ [![Python](https://img.shields.io/badge/Python-2.7%2B-blue?style=flat-square)]()
8
+ [![PyPI](https://img.shields.io/pypi/v/VideoSpeed?style=flat-square)](https://pypi.org/project/VideoSpeed/)
9
+
10
+ VideoSpeed is an interactive command-line tool for short MP4 edits: pick a folder of videos, cut a time range, change length/speed (percent), and optionally append a boomerang (forward + reverse). Encoding uses **FFmpeg**; duration probing uses **OpenCV**.
11
+
12
+ Package version SSOT: `pyproject.toml` and `src/VideoSpeed/__init__.py` (**1.0.5**). Console entrypoint: `video-speed`.
13
+
14
+ ## Features
15
+
16
+ - Recursive **MP4** discovery under a chosen folder
17
+ - Interactive **cut** (start/end seconds) with invalid-range re-prompt
18
+ - **Length/speed** change (**20–200%**) with A/V tempo kept in sync
19
+ - Optional **boomerang** (forward then reverse)
20
+ - **USB-safe** intermediate files (staged next to the output) and final publish via `shutil.move`
21
+ - **`--help`** / **`--version`**; bare invoke starts the interactive session (Type N)
22
+ - Fail-closed when **FFmpeg** is missing from `PATH`
23
+
24
+ ## Quick Installation
25
+
26
+ ### Prerequisites (system)
27
+
28
+ - **FFmpeg** on `PATH` (`ffmpeg -version`)
29
+ - A supported **Python** environment (see `requires-python` in `pyproject.toml`)
30
+
31
+ ### From PyPI (registry channel)
32
+
33
+ Package name SSOT: **`VideoSpeed`** (`pyproject.toml` `[project].name`). Upload path: `build.sh` (`twine upload`).
34
+
35
+ ```bash
36
+ pip install VideoSpeed
37
+ ```
38
+
39
+ If the index is behind a local release, install from a checkout or wheel instead (below). Live index version is shown by the PyPI badge above.
40
+
41
+ ### From a git checkout (development)
42
+
43
+ ```bash
44
+ git clone git@github.com:Wilgat/VideoSpeed.git
45
+ cd VideoSpeed
46
+ pip install -e .
47
+ ```
48
+
49
+ This installs the console script **`video-speed`** and pulls Python deps (`opencv-python`, `ChronicleLogger`, …).
50
+
51
+ ### From a local wheel / sdist
52
+
53
+ ```bash
54
+ # after: python -m build (or ./build.sh build)
55
+ pip install dist/VideoSpeed-1.0.5-py3-none-any.whl
56
+ # or
57
+ pip install dist/VideoSpeed-1.0.5.tar.gz
58
+ ```
59
+
60
+ ### Verify
61
+
62
+ ```bash
63
+ video-speed --version
64
+ # or
65
+ python -m VideoSpeed --version
66
+ ```
67
+
68
+ ## Usage
69
+
70
+ Interactive editor (default):
71
+
72
+ ```bash
73
+ video-speed
74
+ # or
75
+ python -m VideoSpeed
76
+ ```
77
+
78
+ 1. Folder containing MP4s (Enter = current directory)
79
+ 2. Choose a video by number
80
+ 3. Cut start/end seconds
81
+ 4. New length percent (default 100; allowed 20–200)
82
+ 5. Optional boomerang (y/n)
83
+ 6. Output is written **next to the source** with a descriptive name
84
+
85
+ Other:
86
+
87
+ ```bash
88
+ video-speed --help
89
+ video-speed --version
90
+ ```
91
+
92
+ ## Examples
93
+
94
+ ```bash
95
+ # Install editable, then run interactive session in a folder of clips
96
+ cd /path/to/videos
97
+ video-speed
98
+
99
+ # Check identity without starting prompts
100
+ video-speed --version
101
+ ```
102
+
103
+ Example output name shape:
104
+
105
+ ```text
106
+ clip_cut1.0-5.0s_100pct.mp4
107
+ clip_cut1.0-5.0s_50pct_BOOMERANG.mp4
108
+ ```
109
+
110
+ ## Platform Compatibility
111
+
112
+ | Platform | Status |
113
+ |----------|--------|
114
+ | Linux | Primary (tested in development) |
115
+ | macOS / Windows | Expected to work when Python, FFmpeg, and OpenCV are available |
116
+ | Filesystems | Local disk and removable/USB volumes supported for output (temps staged beside final path) |
117
+
118
+ ## Related Projects
119
+
120
+ - [VideoSpeed on GitHub](https://github.com/Wilgat/VideoSpeed)
121
+ - [VideoSpeed on PyPI](https://pypi.org/project/VideoSpeed/)
122
+
123
+ ## Contributing
124
+
125
+ Fork the repository, use a checkout install (`pip install -e .`), and open a pull request. Prefer small, tested changes. Do not strip defensive temp/publish behavior (cross-filesystem `shutil.move`) without an explicit redesign.
126
+
127
+ ## License
128
+
129
+ MIT License — see [`LICENSE.md`](LICENSE.md).
130
+
131
+ ## Last Update
132
+
133
+ 2026-08-09 — README aligned with product **1.0.5**, write-readme detection-driven banners (Version / License / CIAO / Stars / Python / PyPI), and install truth (PyPI + editable + wheel).
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "VideoSpeed"
7
- version = "1.0.4"
7
+ version = "1.0.5"
8
8
  description = "A command-line video editing tool built in Python for cutting, speeding up, and applying a boomerang effect to MP4 videos."
9
9
  readme = "README.md"
10
10
  requires-python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
@@ -0,0 +1,3 @@
1
+ # Package identity SSOT for VideoSpeed (do not import heavy CLI deps here)
2
+ __version__ = "1.0.5"
3
+ __all__ = ["__version__"]
@@ -0,0 +1,489 @@
1
+ #!/usr/bin/env python
2
+ # =============================================================================
3
+ # VideoSpeed CLI — specialized from bootstrap interactive editor (cli.bootstrap-old)
4
+ # Domain: cut → speed/length → optional boomerang (MP4)
5
+ # Law keys: requirement-domain-videospeed, requirement-video-ffmpeg-pipeline,
6
+ # requirement-python-cli-interface, requirement-python-error-handling,
7
+ # requirement-runtime-prerequisites
8
+ # CIAO-Lite: Caution • Intentional • Anti-fragile • Over-protect
9
+ # =============================================================================
10
+ from __future__ import print_function, unicode_literals
11
+
12
+ import argparse
13
+ import os
14
+ import shutil
15
+ import subprocess
16
+ import sys
17
+ import tempfile
18
+ from pathlib import Path
19
+
20
+ # -----------------------------------------------------------------------------
21
+ # Version (package SSOT lives in __init__.__version__; fallback for direct run)
22
+ # -----------------------------------------------------------------------------
23
+ try:
24
+ from . import __version__ as _PKG_VERSION
25
+ except Exception:
26
+ _PKG_VERSION = "1.0.5"
27
+
28
+ APP_NAME = "VideoSpeed"
29
+ CONSOLE_NAME = "video-speed"
30
+
31
+ # Length percent bounds (domain / pipeline guidance made fail-closed)
32
+ RATIO_MIN = 20.0
33
+ RATIO_MAX = 200.0
34
+
35
+
36
+ def out_info(msg):
37
+ """User-facing informational line (stdout)."""
38
+ print(msg)
39
+
40
+
41
+ def out_err(msg):
42
+ """User-facing error line (stderr)."""
43
+ print(msg, file=sys.stderr)
44
+
45
+
46
+ # =============================================================================
47
+ # CIAO-Lite Protection Zone — temp staging + publish (USB / multi-mount)
48
+ # System TMPDIR and removable media are often different filesystems.
49
+ # Bare os.rename / os.replace / Path.rename / Path.replace do NOT cross mounts
50
+ # (Linux EXDEV). Publish completed intermediates with shutil.move (rename same
51
+ # FS; copy+delete on EXDEV). Prefer temps next to final output when writable.
52
+ # Do NOT "simplify" back to bare os.replace from default /tmp onto USB paths.
53
+ # Law: requirement-video-ffmpeg-pipeline, requirement-python-coding-style
54
+ # =============================================================================
55
+
56
+
57
+ def staging_dir_for(dest_path):
58
+ """
59
+ General Purpose: Choose a directory for intermediate files on the same
60
+ filesystem as dest when possible (USB-safe). Falls back to system temp.
61
+ """
62
+ dest_path = Path(dest_path)
63
+ parent = dest_path.parent if dest_path.suffix else dest_path
64
+ if not parent.is_dir():
65
+ parent = dest_path.parent
66
+ try:
67
+ if parent.is_dir() and os.access(str(parent), os.W_OK):
68
+ return parent
69
+ except OSError:
70
+ pass
71
+ return Path(tempfile.gettempdir())
72
+
73
+
74
+ def make_temp_path(suffix, near_path):
75
+ """
76
+ General Purpose: Create a unique temp file path near near_path's directory
77
+ (same FS when writable). File is created empty and closed; caller overwrites.
78
+ """
79
+ d = staging_dir_for(near_path)
80
+ fd, name = tempfile.mkstemp(suffix=suffix, prefix="videospeed_", dir=str(d))
81
+ os.close(fd)
82
+ return Path(name)
83
+
84
+
85
+ def promote_file(src, dest):
86
+ """
87
+ General Purpose: Publish src → dest using shutil.move (stdlib cross-FS safe).
88
+
89
+ Same mount: rename. Different mount (USB, etc.): copy then remove source.
90
+ Never use bare os.replace alone when src may live under system TMPDIR.
91
+ """
92
+ src = Path(src)
93
+ dest = Path(dest)
94
+ if not src.is_file():
95
+ raise FileNotFoundError("promote source missing: {}".format(src))
96
+ dest.parent.mkdir(parents=True, exist_ok=True)
97
+ # shutil.move: try rename; on EXDEV copy + unlink source
98
+ shutil.move(str(src), str(dest))
99
+
100
+
101
+ def ensure_ffmpeg():
102
+ """
103
+ General Purpose: Fail closed if the system ffmpeg binary is not on PATH.
104
+ requirement-runtime-prerequisites / requirement-video-ffmpeg-pipeline
105
+ """
106
+ if shutil.which("ffmpeg") is None:
107
+ out_err("ERROR: ffmpeg not found on PATH.")
108
+ out_err(" Install FFmpeg and ensure `ffmpeg` is available.")
109
+ out_err(" → https://ffmpeg.org/download.html")
110
+ return False
111
+ return True
112
+
113
+
114
+ def run_ffmpeg(cmd):
115
+ """
116
+ General Purpose: Run one FFmpeg command; fail closed on non-zero exit.
117
+ Does not modify the user's source media path.
118
+ """
119
+ out_info(" Running → {}".format(" ".join(str(c) for c in cmd)))
120
+ try:
121
+ subprocess.run(cmd, check=True)
122
+ except FileNotFoundError:
123
+ out_err("ERROR: ffmpeg not found while running a encode step.")
124
+ raise
125
+ except subprocess.CalledProcessError as exc:
126
+ out_err("ERROR: ffmpeg failed (exit {}).".format(exc.returncode))
127
+ raise
128
+
129
+
130
+ def get_mp4_files(folder="."):
131
+ """General Purpose: Recursively list MP4 files under folder (case variants)."""
132
+ folder = Path(folder)
133
+ if not folder.is_dir():
134
+ return []
135
+ files = list(folder.rglob("*.mp4")) + list(folder.rglob("*.MP4"))
136
+ files = [f for f in files if f.is_file()]
137
+ # de-dupe same path if filesystem is case-insensitive
138
+ seen = set()
139
+ unique = []
140
+ for f in files:
141
+ key = str(f.resolve()) if f.exists() else str(f)
142
+ if key not in seen:
143
+ seen.add(key)
144
+ unique.append(f)
145
+ unique.sort(key=lambda x: x.name.lower())
146
+ return unique
147
+
148
+
149
+ def get_duration_cv2(video_path):
150
+ """
151
+ General Purpose: Probe duration via OpenCV (lazy import).
152
+ Returns seconds; 0.0 if unreadable.
153
+ """
154
+ try:
155
+ import cv2
156
+ except ImportError:
157
+ out_err("ERROR: OpenCV (cv2) is not installed.")
158
+ out_err(" Install with: pip install opencv-python")
159
+ return 0.0
160
+
161
+ cap = cv2.VideoCapture(str(video_path))
162
+ if not cap.isOpened():
163
+ cap.release()
164
+ return 0.0
165
+ fps = cap.get(cv2.CAP_PROP_FPS)
166
+ frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
167
+ cap.release()
168
+ if fps is None or fps <= 0 or frame_count <= 0:
169
+ return 0.0
170
+ return float(frame_count) / float(fps)
171
+
172
+
173
+ def format_time(seconds):
174
+ """General Purpose: Format seconds as H:MM:SS.mmm or M:SS.mmm."""
175
+ h = int(seconds // 3600)
176
+ m = int((seconds % 3600) // 60)
177
+ s = seconds % 60
178
+ if h == 0:
179
+ return "{:02d}:{:06.3f}".format(m, s)
180
+ return "{:02d}:{:02d}:{:06.3f}".format(h, m, s)
181
+
182
+
183
+ def cut_clip(src, start, end, output_path):
184
+ """
185
+ General Purpose: Extract [start, end] segment to output_path via FFmpeg.
186
+ Source file is read-only input.
187
+ """
188
+ cmd = [
189
+ "ffmpeg", "-y", "-hide_banner", "-loglevel", "error",
190
+ "-i", str(src),
191
+ "-vf", "trim=start={}:end={},setpts=PTS-STARTPTS".format(start, end),
192
+ "-af", "atrim=start={}:end={},asetpts=PTS-STARTPTS".format(start, end),
193
+ "-c:v", "libx264", "-preset", "ultrafast", "-crf", "17",
194
+ "-c:a", "aac", "-avoid_negative_ts", "make_zero",
195
+ str(output_path),
196
+ ]
197
+ run_ffmpeg(cmd)
198
+
199
+
200
+ def _atempo_filters(speed):
201
+ """
202
+ General Purpose: Build atempo chain. FFmpeg single atempo accepts 0.5–100.
203
+ speed = playback rate ( >1 faster, shorter wall time for same content).
204
+ """
205
+ filters = []
206
+ remaining = float(speed)
207
+ # Speed up: atempo max 100; slow down: min 0.5 — chain when needed
208
+ if remaining <= 0:
209
+ raise ValueError("speed must be positive")
210
+ while remaining > 100.0:
211
+ filters.append("atempo=100.0")
212
+ remaining /= 100.0
213
+ while remaining < 0.5:
214
+ filters.append("atempo=0.5")
215
+ remaining /= 0.5
216
+ filters.append("atempo={:.6f}".format(remaining))
217
+ return ",".join(filters)
218
+
219
+
220
+ def speed_change(input_path, ratio_percent, output_path):
221
+ """
222
+ General Purpose: Change clip length to ratio_percent of original cut length.
223
+ 100 = unchanged duration intent; 50 ≈ half length (faster); 200 ≈ double length.
224
+ """
225
+ speed = 100.0 / float(ratio_percent)
226
+ atempo = _atempo_filters(speed)
227
+ cmd = [
228
+ "ffmpeg", "-y", "-hide_banner", "-loglevel", "error",
229
+ "-i", str(input_path),
230
+ "-filter_complex",
231
+ "[0:v]setpts={:.6f}*PTS[v];[0:a]{}[a]".format(1.0 / speed, atempo),
232
+ "-map", "[v]", "-map", "[a]",
233
+ "-c:v", "libx264", "-preset", "medium", "-crf", "18",
234
+ "-c:a", "aac", "-b:a", "192k",
235
+ "-movflags", "+faststart",
236
+ str(output_path),
237
+ ]
238
+ run_ffmpeg(cmd)
239
+
240
+
241
+ def add_boomerang(forward_clip, final_output):
242
+ """
243
+ General Purpose: Concat forward + reverse of forward_clip into final_output.
244
+ Intermediate reverse/list files are staged near final_output (USB-safe).
245
+ Cleans reverse and concat-list temps on all paths.
246
+ """
247
+ reverse_clip = None
248
+ concat_list = None
249
+ try:
250
+ # Stage reverse next to final output so reverse+concat stay on one mount.
251
+ reverse_clip = make_temp_path(".mp4", final_output)
252
+
253
+ run_ffmpeg([
254
+ "ffmpeg", "-y", "-hide_banner", "-loglevel", "error",
255
+ "-i", str(forward_clip),
256
+ "-vf", "reverse", "-af", "areverse",
257
+ str(reverse_clip),
258
+ ])
259
+
260
+ # Concat list file also near dest FS; paths absolute for demuxer.
261
+ concat_list = make_temp_path(".txt", final_output)
262
+ with open(str(concat_list), "w", encoding="utf-8") as f:
263
+ f.write("file '{}'\n".format(Path(forward_clip).resolve().as_posix()))
264
+ f.write("file '{}'\n".format(Path(reverse_clip).resolve().as_posix()))
265
+
266
+ run_ffmpeg([
267
+ "ffmpeg", "-y", "-hide_banner", "-loglevel", "error",
268
+ "-f", "concat", "-safe", "0",
269
+ "-i", str(concat_list),
270
+ "-c", "copy",
271
+ str(final_output),
272
+ ])
273
+ finally:
274
+ for p in (reverse_clip, concat_list):
275
+ if p is not None and Path(p).exists():
276
+ try:
277
+ os.unlink(p)
278
+ except OSError:
279
+ pass
280
+
281
+
282
+ def choose_index(prompt, count):
283
+ """General Purpose: Prompt for 1-based index in [1, count]; re-prompt on error."""
284
+ while True:
285
+ raw = input(prompt).strip()
286
+ try:
287
+ idx = int(raw)
288
+ except ValueError:
289
+ out_info(" → Please type a number")
290
+ continue
291
+ if 1 <= idx <= count:
292
+ return idx - 1
293
+ out_info(" → Enter 1–{}".format(count))
294
+
295
+
296
+ def prompt_float(prompt, default=None):
297
+ """General Purpose: Prompt for float; empty uses default if provided."""
298
+ while True:
299
+ raw = input(prompt).strip()
300
+ if raw == "" and default is not None:
301
+ return float(default)
302
+ try:
303
+ return float(raw.replace("%", ""))
304
+ except ValueError:
305
+ out_info(" → Please enter a number")
306
+
307
+
308
+ def prompt_yes_no(prompt, default_no=True):
309
+ """General Purpose: y/n prompt; empty → default."""
310
+ raw = input(prompt).strip().lower()
311
+ if raw == "":
312
+ return not default_no
313
+ return raw in ("y", "yes")
314
+
315
+
316
+ def build_output_name(video_path, start, end, ratio, boomerang):
317
+ """General Purpose: Domain output naming pattern beside source."""
318
+ name = "{}_cut{:.1f}-{:.1f}s_{:d}pct".format(
319
+ video_path.stem, start, end, int(ratio)
320
+ )
321
+ if boomerang:
322
+ name += "_BOOMERANG"
323
+ name += ".mp4"
324
+ return video_path.parent / name
325
+
326
+
327
+ def process_job(video_path, start, end, ratio, boomerang):
328
+ """
329
+ General Purpose: Run cut → speed → optional boomerang pipeline.
330
+ Never overwrites source; cleans intermediate temps.
331
+ Temps are staged on the destination filesystem when possible so USB /
332
+ removable media does not hit cross-device os.replace failures.
333
+ Returns final Path or None on failure.
334
+ """
335
+ final_out = build_output_name(video_path, start, end, ratio, boomerang)
336
+ out_info("\nProcessing → {}\n".format(final_out))
337
+ out_info(" Staging dir → {}".format(staging_dir_for(final_out)))
338
+
339
+ cut_temp = None
340
+ speed_temp = None
341
+ try:
342
+ # Same-FS temps next to final_out (e.g. on the USB volume).
343
+ cut_temp = make_temp_path(".mp4", final_out)
344
+ speed_temp = make_temp_path(".mp4", final_out)
345
+
346
+ out_info("1. Cutting segment...")
347
+ cut_clip(video_path, start, end, cut_temp)
348
+ out_info("2. Changing length to {}%...".format(int(ratio) if ratio == int(ratio) else ratio))
349
+ speed_change(cut_temp, ratio, speed_temp)
350
+ if boomerang:
351
+ out_info("3. Creating boomerang...")
352
+ add_boomerang(speed_temp, final_out)
353
+ else:
354
+ # Publish with shutil.move (same-FS rename or cross-FS copy+delete).
355
+ promote_file(speed_temp, final_out)
356
+ speed_temp = None # moved away
357
+ out_info("\nSUCCESS → {}\n".format(final_out))
358
+ return final_out
359
+ except (subprocess.CalledProcessError, FileNotFoundError, OSError, ValueError) as exc:
360
+ err = getattr(exc, "errno", None)
361
+ out_err("Job failed: {}".format(exc))
362
+ if err in (getattr(os, "EXDEV", 18), 18):
363
+ out_err(
364
+ " Hint: cross-filesystem rename failed (USB vs system temp). "
365
+ "Temps should stage next to the output; publish uses shutil.move. "
366
+ "Check USB write permission and free space."
367
+ )
368
+ return None
369
+ finally:
370
+ for p in (cut_temp, speed_temp):
371
+ if p is not None and Path(p).exists():
372
+ try:
373
+ os.unlink(p)
374
+ except OSError:
375
+ pass
376
+
377
+
378
+ def interactive_session():
379
+ """
380
+ General Purpose: Type N interactive domain session (empty argv default).
381
+ requirement-domain-videospeed steps D-01..D-08
382
+ """
383
+ out_info("{} v{} — Cut → Speed → Optional Boomerang".format(APP_NAME, _PKG_VERSION))
384
+ out_info("=" * 62)
385
+
386
+ if not ensure_ffmpeg():
387
+ return 1
388
+
389
+ folder = input("Folder (Enter = current): ").strip() or "."
390
+ folder_path = Path(folder)
391
+ if not folder_path.is_dir():
392
+ out_err("ERROR: Not a directory: {}".format(folder))
393
+ return 1
394
+
395
+ files = get_mp4_files(folder_path)
396
+ if not files:
397
+ out_err("No MP4 files found!")
398
+ return 1
399
+
400
+ for i, f in enumerate(files, 1):
401
+ out_info("{:2d}. {}".format(i, f.name))
402
+
403
+ sel = choose_index("\nChoose video (1–{}): ".format(len(files)), len(files))
404
+ video_path = files[sel]
405
+
406
+ duration = get_duration_cv2(video_path)
407
+ if duration <= 0:
408
+ out_err("ERROR: Could not read duration for {}".format(video_path.name))
409
+ return 1
410
+
411
+ out_info("\nSelected: {}".format(video_path.name))
412
+ out_info("Duration: {} ({:.3f}s)\n".format(format_time(duration), duration))
413
+
414
+ while True:
415
+ out_info("Step 1/4 – Cut segment")
416
+ start = prompt_float(" Start seconds (default 0.0): ", default=0.0)
417
+ out_info(" → Using start: {:.3f}s".format(start))
418
+ end = prompt_float(
419
+ " End seconds [{:.3f}]: ".format(duration),
420
+ default=duration,
421
+ )
422
+
423
+ if not (0 <= start < end <= duration):
424
+ out_info("Invalid range! Need 0 ≤ start < end ≤ duration.\n")
425
+ continue
426
+
427
+ out_info("\nStep 2/4 – Resize length ({}–{}%)".format(int(RATIO_MIN), int(RATIO_MAX)))
428
+ ratio = prompt_float(" New length % [100%]: ", default=100.0)
429
+ if not (RATIO_MIN <= ratio <= RATIO_MAX):
430
+ out_info(
431
+ "Invalid percent! Use {}–{} (got {}).\n".format(
432
+ int(RATIO_MIN), int(RATIO_MAX), ratio
433
+ )
434
+ )
435
+ continue
436
+
437
+ out_info("\nStep 3/4 – Add boomerang effect?")
438
+ boomerang = prompt_yes_no(
439
+ " Make it go forward + backward (y/n) [n]: ",
440
+ default_no=True,
441
+ )
442
+
443
+ process_job(video_path, start, end, ratio, boomerang)
444
+
445
+ if not prompt_yes_no("Again? (y/n): ", default_no=True):
446
+ break
447
+
448
+ out_info("Done.")
449
+ return 0
450
+
451
+
452
+ def build_parser():
453
+ """General Purpose: Optional flags; bare invoke remains interactive (Type N)."""
454
+ p = argparse.ArgumentParser(
455
+ prog=CONSOLE_NAME,
456
+ description=(
457
+ "{} — interactive MP4 cut, length/speed change, optional boomerang."
458
+ .format(APP_NAME)
459
+ ),
460
+ )
461
+ p.add_argument(
462
+ "--version",
463
+ action="version",
464
+ version="{} {}".format(APP_NAME, _PKG_VERSION),
465
+ )
466
+ return p
467
+
468
+
469
+ def main(argv=None):
470
+ """
471
+ General Purpose: Package entry for video-speed / python -m VideoSpeed.
472
+ Empty argv → interactive domain session (Type N).
473
+ """
474
+ if argv is None:
475
+ argv = sys.argv[1:]
476
+
477
+ # Allow --help / --version without starting prompts
478
+ if argv:
479
+ parser = build_parser()
480
+ parser.parse_args(argv)
481
+ # No non-interactive job flags yet → if user passed only unknown, argparse exits
482
+ # If parse succeeds with no action flags, fall through to interactive
483
+ # (version/help already exited via argparse)
484
+
485
+ return interactive_session()
486
+
487
+
488
+ if __name__ == "__main__":
489
+ sys.exit(main() or 0)
@@ -0,0 +1,150 @@
1
+ Metadata-Version: 2.4
2
+ Name: VideoSpeed
3
+ Version: 1.0.5
4
+ Summary: A command-line video editing tool built in Python for cutting, speeding up, and applying a boomerang effect to MP4 videos.
5
+ Author-email: Wilgat Wong <wilgat.wong@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Wilgat/VideoSpeed
8
+ Project-URL: Repository, https://github.com/Wilgat/VideoSpeed
9
+ Project-URL: Issues, https://github.com/Wilgat/VideoSpeed/issues
10
+ Keywords: Video Editing,Multimeida
11
+ Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE.md
14
+ Requires-Dist: ChronicleLogger>=1.2.3
15
+ Requires-Dist: opencv-python
16
+ Dynamic: license-file
17
+
18
+ # VideoSpeed - Cut, speed, and boomerang MP4 clips from the CLI
19
+
20
+ ![Version](https://img.shields.io/badge/Version-1.0.5-blue?style=flat-square)
21
+ ![License](https://img.shields.io/badge/License-MIT-green?style=flat-square)
22
+ [![CIAO](https://img.shields.io/badge/Philosophy-CIAO%20(Caution%20%E2%80%A2%20Intentional%20%E2%80%A2%20Anti--fragile%20%E2%80%A2%20Over--engineered)-purple.svg)](https://github.com/cloudgen/ciao)
23
+ [![Stars](https://img.shields.io/github/stars/Wilgat/VideoSpeed?style=flat-square)](https://github.com/Wilgat/VideoSpeed)
24
+ [![Python](https://img.shields.io/badge/Python-2.7%2B-blue?style=flat-square)]()
25
+ [![PyPI](https://img.shields.io/pypi/v/VideoSpeed?style=flat-square)](https://pypi.org/project/VideoSpeed/)
26
+
27
+ VideoSpeed is an interactive command-line tool for short MP4 edits: pick a folder of videos, cut a time range, change length/speed (percent), and optionally append a boomerang (forward + reverse). Encoding uses **FFmpeg**; duration probing uses **OpenCV**.
28
+
29
+ Package version SSOT: `pyproject.toml` and `src/VideoSpeed/__init__.py` (**1.0.5**). Console entrypoint: `video-speed`.
30
+
31
+ ## Features
32
+
33
+ - Recursive **MP4** discovery under a chosen folder
34
+ - Interactive **cut** (start/end seconds) with invalid-range re-prompt
35
+ - **Length/speed** change (**20–200%**) with A/V tempo kept in sync
36
+ - Optional **boomerang** (forward then reverse)
37
+ - **USB-safe** intermediate files (staged next to the output) and final publish via `shutil.move`
38
+ - **`--help`** / **`--version`**; bare invoke starts the interactive session (Type N)
39
+ - Fail-closed when **FFmpeg** is missing from `PATH`
40
+
41
+ ## Quick Installation
42
+
43
+ ### Prerequisites (system)
44
+
45
+ - **FFmpeg** on `PATH` (`ffmpeg -version`)
46
+ - A supported **Python** environment (see `requires-python` in `pyproject.toml`)
47
+
48
+ ### From PyPI (registry channel)
49
+
50
+ Package name SSOT: **`VideoSpeed`** (`pyproject.toml` `[project].name`). Upload path: `build.sh` (`twine upload`).
51
+
52
+ ```bash
53
+ pip install VideoSpeed
54
+ ```
55
+
56
+ If the index is behind a local release, install from a checkout or wheel instead (below). Live index version is shown by the PyPI badge above.
57
+
58
+ ### From a git checkout (development)
59
+
60
+ ```bash
61
+ git clone git@github.com:Wilgat/VideoSpeed.git
62
+ cd VideoSpeed
63
+ pip install -e .
64
+ ```
65
+
66
+ This installs the console script **`video-speed`** and pulls Python deps (`opencv-python`, `ChronicleLogger`, …).
67
+
68
+ ### From a local wheel / sdist
69
+
70
+ ```bash
71
+ # after: python -m build (or ./build.sh build)
72
+ pip install dist/VideoSpeed-1.0.5-py3-none-any.whl
73
+ # or
74
+ pip install dist/VideoSpeed-1.0.5.tar.gz
75
+ ```
76
+
77
+ ### Verify
78
+
79
+ ```bash
80
+ video-speed --version
81
+ # or
82
+ python -m VideoSpeed --version
83
+ ```
84
+
85
+ ## Usage
86
+
87
+ Interactive editor (default):
88
+
89
+ ```bash
90
+ video-speed
91
+ # or
92
+ python -m VideoSpeed
93
+ ```
94
+
95
+ 1. Folder containing MP4s (Enter = current directory)
96
+ 2. Choose a video by number
97
+ 3. Cut start/end seconds
98
+ 4. New length percent (default 100; allowed 20–200)
99
+ 5. Optional boomerang (y/n)
100
+ 6. Output is written **next to the source** with a descriptive name
101
+
102
+ Other:
103
+
104
+ ```bash
105
+ video-speed --help
106
+ video-speed --version
107
+ ```
108
+
109
+ ## Examples
110
+
111
+ ```bash
112
+ # Install editable, then run interactive session in a folder of clips
113
+ cd /path/to/videos
114
+ video-speed
115
+
116
+ # Check identity without starting prompts
117
+ video-speed --version
118
+ ```
119
+
120
+ Example output name shape:
121
+
122
+ ```text
123
+ clip_cut1.0-5.0s_100pct.mp4
124
+ clip_cut1.0-5.0s_50pct_BOOMERANG.mp4
125
+ ```
126
+
127
+ ## Platform Compatibility
128
+
129
+ | Platform | Status |
130
+ |----------|--------|
131
+ | Linux | Primary (tested in development) |
132
+ | macOS / Windows | Expected to work when Python, FFmpeg, and OpenCV are available |
133
+ | Filesystems | Local disk and removable/USB volumes supported for output (temps staged beside final path) |
134
+
135
+ ## Related Projects
136
+
137
+ - [VideoSpeed on GitHub](https://github.com/Wilgat/VideoSpeed)
138
+ - [VideoSpeed on PyPI](https://pypi.org/project/VideoSpeed/)
139
+
140
+ ## Contributing
141
+
142
+ Fork the repository, use a checkout install (`pip install -e .`), and open a pull request. Prefer small, tested changes. Do not strip defensive temp/publish behavior (cross-filesystem `shutil.move`) without an explicit redesign.
143
+
144
+ ## License
145
+
146
+ MIT License — see [`LICENSE.md`](LICENSE.md).
147
+
148
+ ## Last Update
149
+
150
+ 2026-08-09 — README aligned with product **1.0.5**, write-readme detection-driven banners (Version / License / CIAO / Stars / Python / PyPI), and install truth (PyPI + editable + wheel).
@@ -1,8 +1,9 @@
1
+ LICENSE.md
1
2
  README.md
2
3
  pyproject.toml
3
- src/setup.py
4
4
  src/VideoSpeed/__init__.py
5
5
  src/VideoSpeed/__main__.py
6
+ src/VideoSpeed/cli.bootstrap-old.py
6
7
  src/VideoSpeed/cli.py
7
8
  src/VideoSpeed.egg-info/PKG-INFO
8
9
  src/VideoSpeed.egg-info/SOURCES.txt
videospeed-1.0.4/PKG-INFO DELETED
@@ -1,100 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: VideoSpeed
3
- Version: 1.0.4
4
- Summary: A command-line video editing tool built in Python for cutting, speeding up, and applying a boomerang effect to MP4 videos.
5
- Author-email: Wilgat Wong <wilgat.wong@gmail.com>
6
- License: MIT
7
- Project-URL: Homepage, https://github.com/Wilgat/VideoSpeed
8
- Project-URL: Repository, https://github.com/Wilgat/VideoSpeed
9
- Project-URL: Issues, https://github.com/Wilgat/VideoSpeed/issues
10
- Keywords: Video Editing,Multimeida
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
- # VideoSpeed
17
-
18
- A command-line video editing tool built in Python for cutting, speeding up, and applying a boomerang effect to MP4 videos. This project leverages FFmpeg for video processing and OpenCV to handle video file properties.
19
-
20
- ## Features
21
-
22
- - **Cut segments** from MP4 videos.
23
- - Change the **speed** of video clips.
24
- - Apply a **boomerang effect** by reversing video segments.
25
- - Simple command-line interface for user interaction.
26
-
27
- ## Installation
28
-
29
- To install the VideoSpeed package, use the provided distributions:
30
-
31
- 1. Download the wheel or tar.gz file from the `dist` directory:
32
- - `VideoSpeed-1.0.4-py3-none-any.whl`
33
- - `VideoSpeed-1.0.4.tar.gz`
34
-
35
- 2. Install via pip:
36
- ```bash
37
- pip install dist/VideoSpeed-1.0.4-py3-none-any.whl
38
- ```
39
-
40
- Or
41
- ```bash
42
- pip install dist/VideoSpeed-1.0.4.tar.gz
43
- ```
44
-
45
- ## Usage
46
-
47
- You can run the tool directly from the command line:
48
-
49
- ```bash
50
- python -m VideoSpeed
51
- ```
52
-
53
- ### Steps:
54
- 1. Select the folder containing your MP4 files (default is the current directory).
55
- 2. Choose the video file from the listed options.
56
- 3. Specify the start and end time for the cut.
57
- 4. Enter the desired speed percentage for the clip.
58
- 5. Optionally, choose to add a boomerang effect.
59
- 6. The processed video will be saved in the same directory as the source file.
60
-
61
- ## Folder Structure
62
-
63
- ```
64
- VideoSpeed
65
- ├── build/ # Contains build artifacts
66
- ├── dist/ # Distributions for installation
67
- ├── docs/ # Documentation files
68
- │ ├── CHANGELOG.md # Changes in each version
69
- │ ├── folder-structure.md# Describes folder structure
70
- │ └── LoggedExample-spec.md # Specifications for examples
71
- ├── src/ # Source code directory
72
- │ ├── VideoSpeed/ # Main package
73
- │ ├── setup.py # Installation script
74
- └── README.md # Project documentation
75
- ```
76
-
77
- ## Requirements
78
-
79
- - Python 3.6 or higher
80
- - FFmpeg installed on your system
81
- - OpenCV library (`opencv-python`)
82
-
83
- You can install OpenCV using pip:
84
-
85
- ```bash
86
- pip install opencv-python
87
- ```
88
-
89
- ## Contributing
90
-
91
- Contributions are welcome! Please fork the repository and submit a pull request.
92
-
93
- ## License
94
-
95
- This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
96
-
97
- ## Acknowledgements
98
-
99
- - **FFmpeg**: A powerful multimedia framework for handling video files.
100
- - **OpenCV**: A library for computer vision tasks.
@@ -1,85 +0,0 @@
1
- # VideoSpeed
2
-
3
- A command-line video editing tool built in Python for cutting, speeding up, and applying a boomerang effect to MP4 videos. This project leverages FFmpeg for video processing and OpenCV to handle video file properties.
4
-
5
- ## Features
6
-
7
- - **Cut segments** from MP4 videos.
8
- - Change the **speed** of video clips.
9
- - Apply a **boomerang effect** by reversing video segments.
10
- - Simple command-line interface for user interaction.
11
-
12
- ## Installation
13
-
14
- To install the VideoSpeed package, use the provided distributions:
15
-
16
- 1. Download the wheel or tar.gz file from the `dist` directory:
17
- - `VideoSpeed-1.0.4-py3-none-any.whl`
18
- - `VideoSpeed-1.0.4.tar.gz`
19
-
20
- 2. Install via pip:
21
- ```bash
22
- pip install dist/VideoSpeed-1.0.4-py3-none-any.whl
23
- ```
24
-
25
- Or
26
- ```bash
27
- pip install dist/VideoSpeed-1.0.4.tar.gz
28
- ```
29
-
30
- ## Usage
31
-
32
- You can run the tool directly from the command line:
33
-
34
- ```bash
35
- python -m VideoSpeed
36
- ```
37
-
38
- ### Steps:
39
- 1. Select the folder containing your MP4 files (default is the current directory).
40
- 2. Choose the video file from the listed options.
41
- 3. Specify the start and end time for the cut.
42
- 4. Enter the desired speed percentage for the clip.
43
- 5. Optionally, choose to add a boomerang effect.
44
- 6. The processed video will be saved in the same directory as the source file.
45
-
46
- ## Folder Structure
47
-
48
- ```
49
- VideoSpeed
50
- ├── build/ # Contains build artifacts
51
- ├── dist/ # Distributions for installation
52
- ├── docs/ # Documentation files
53
- │ ├── CHANGELOG.md # Changes in each version
54
- │ ├── folder-structure.md# Describes folder structure
55
- │ └── LoggedExample-spec.md # Specifications for examples
56
- ├── src/ # Source code directory
57
- │ ├── VideoSpeed/ # Main package
58
- │ ├── setup.py # Installation script
59
- └── README.md # Project documentation
60
- ```
61
-
62
- ## Requirements
63
-
64
- - Python 3.6 or higher
65
- - FFmpeg installed on your system
66
- - OpenCV library (`opencv-python`)
67
-
68
- You can install OpenCV using pip:
69
-
70
- ```bash
71
- pip install opencv-python
72
- ```
73
-
74
- ## Contributing
75
-
76
- Contributions are welcome! Please fork the repository and submit a pull request.
77
-
78
- ## License
79
-
80
- This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
81
-
82
- ## Acknowledgements
83
-
84
- - **FFmpeg**: A powerful multimedia framework for handling video files.
85
- - **OpenCV**: A library for computer vision tasks.
@@ -1,4 +0,0 @@
1
- from .cli import ChronicleLogger
2
-
3
- __version__ = "1.0.4"
4
- __all__ = ["ChronicleLogger"]
@@ -1,100 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: VideoSpeed
3
- Version: 1.0.4
4
- Summary: A command-line video editing tool built in Python for cutting, speeding up, and applying a boomerang effect to MP4 videos.
5
- Author-email: Wilgat Wong <wilgat.wong@gmail.com>
6
- License: MIT
7
- Project-URL: Homepage, https://github.com/Wilgat/VideoSpeed
8
- Project-URL: Repository, https://github.com/Wilgat/VideoSpeed
9
- Project-URL: Issues, https://github.com/Wilgat/VideoSpeed/issues
10
- Keywords: Video Editing,Multimeida
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
- # VideoSpeed
17
-
18
- A command-line video editing tool built in Python for cutting, speeding up, and applying a boomerang effect to MP4 videos. This project leverages FFmpeg for video processing and OpenCV to handle video file properties.
19
-
20
- ## Features
21
-
22
- - **Cut segments** from MP4 videos.
23
- - Change the **speed** of video clips.
24
- - Apply a **boomerang effect** by reversing video segments.
25
- - Simple command-line interface for user interaction.
26
-
27
- ## Installation
28
-
29
- To install the VideoSpeed package, use the provided distributions:
30
-
31
- 1. Download the wheel or tar.gz file from the `dist` directory:
32
- - `VideoSpeed-1.0.4-py3-none-any.whl`
33
- - `VideoSpeed-1.0.4.tar.gz`
34
-
35
- 2. Install via pip:
36
- ```bash
37
- pip install dist/VideoSpeed-1.0.4-py3-none-any.whl
38
- ```
39
-
40
- Or
41
- ```bash
42
- pip install dist/VideoSpeed-1.0.4.tar.gz
43
- ```
44
-
45
- ## Usage
46
-
47
- You can run the tool directly from the command line:
48
-
49
- ```bash
50
- python -m VideoSpeed
51
- ```
52
-
53
- ### Steps:
54
- 1. Select the folder containing your MP4 files (default is the current directory).
55
- 2. Choose the video file from the listed options.
56
- 3. Specify the start and end time for the cut.
57
- 4. Enter the desired speed percentage for the clip.
58
- 5. Optionally, choose to add a boomerang effect.
59
- 6. The processed video will be saved in the same directory as the source file.
60
-
61
- ## Folder Structure
62
-
63
- ```
64
- VideoSpeed
65
- ├── build/ # Contains build artifacts
66
- ├── dist/ # Distributions for installation
67
- ├── docs/ # Documentation files
68
- │ ├── CHANGELOG.md # Changes in each version
69
- │ ├── folder-structure.md# Describes folder structure
70
- │ └── LoggedExample-spec.md # Specifications for examples
71
- ├── src/ # Source code directory
72
- │ ├── VideoSpeed/ # Main package
73
- │ ├── setup.py # Installation script
74
- └── README.md # Project documentation
75
- ```
76
-
77
- ## Requirements
78
-
79
- - Python 3.6 or higher
80
- - FFmpeg installed on your system
81
- - OpenCV library (`opencv-python`)
82
-
83
- You can install OpenCV using pip:
84
-
85
- ```bash
86
- pip install opencv-python
87
- ```
88
-
89
- ## Contributing
90
-
91
- Contributions are welcome! Please fork the repository and submit a pull request.
92
-
93
- ## License
94
-
95
- This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
96
-
97
- ## Acknowledgements
98
-
99
- - **FFmpeg**: A powerful multimedia framework for handling video files.
100
- - **OpenCV**: A library for computer vision tasks.
@@ -1,7 +0,0 @@
1
- #!/home/adm01/.pyenv/shims/python3
2
- from setuptools import setup
3
- from Cython.Build import cythonize
4
-
5
- setup(
6
- ext_modules=cythonize("src/VideoSpeed.pyx",compiler_directives={"language_level" : "3"})
7
- )
File without changes