VideoJoin 1.0.2__tar.gz → 1.0.3__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,155 @@
1
+ Metadata-Version: 2.4
2
+ Name: VideoJoin
3
+ Version: 1.0.3
4
+ Summary: VideoJoin is a lightweight command-line tool for concatenating two video files (MP4, MOV, MKV, AVI, M4V) while preserving original audio and video quality using FFmpeg.
5
+ Author-email: Wilgat Wong <wilgat.wong@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Wilgat/VideoJoin
8
+ Project-URL: Repository, https://github.com/Wilgat/VideoJoin
9
+ Project-URL: Issues, https://github.com/Wilgat/VideoJoin/issues
10
+ Keywords: Video Editing,Video,Multimedia
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
+ Dynamic: license-file
16
+
17
+ # VideoJoin - Join two local videos with FFmpeg (stream-copy first)
18
+
19
+ ![Version](https://img.shields.io/badge/Version-1.0.3-blue?style=flat-square)
20
+ ![License](https://img.shields.io/badge/License-MIT-green?style=flat-square)
21
+ [![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)
22
+ [![Stars](https://img.shields.io/github/stars/Wilgat/VideoJoin?style=flat-square)](https://github.com/Wilgat/VideoJoin)
23
+ [![Python](https://img.shields.io/badge/Python-2.7%2B%20(3.x%20recommended)-blue?style=flat-square)]()
24
+
25
+ VideoJoin is a lightweight **interactive** command-line tool that concatenates **two** video files from the current directory using **FFmpeg**. It prefers **stream copy** (no re-encode when possible) and **fail-closed re-encode fallback** when copy fails. Intermediate files are staged next to the output path when possible and published with **`shutil.move`** for multi-mount safety (for example USB).
26
+
27
+ ## Features
28
+
29
+ - Interactive pick of first and second video (same file cannot be chosen twice)
30
+ - Discovers `.mp4`, `.mov`, `.mkv`, `.avi`, `.m4v` in the **current working directory** (sorted case-insensitively)
31
+ - Stream-copy join first (`ffmpeg` concat demuxer); re-encode fallback (`libx264` CRF 18, AAC 192k)
32
+ - Fail-closed: no success message if both paths fail
33
+ - Unique temp list + media intermediates; cleanup on success and failure
34
+ - Publish intermediates with `shutil.move` (same FS rename; cross-mount copy+delete)
35
+ - FFmpeg on `PATH` checked before joining
36
+ - Console script `video-join` and module entry `python -m VideoJoin`
37
+
38
+ ## Quick Installation
39
+
40
+ **System requirement:** [FFmpeg](https://ffmpeg.org/download.html) must be installed and available as `ffmpeg` on your `PATH`. The package does **not** install FFmpeg via pip.
41
+
42
+ ### Local install (primary)
43
+
44
+ From a checkout:
45
+
46
+ ```bash
47
+ git clone https://github.com/Wilgat/VideoJoin.git
48
+ cd VideoJoin
49
+ python3 -m venv venv
50
+ source venv/bin/activate # Windows: venv\Scripts\activate
51
+ pip install -e .
52
+ ```
53
+
54
+ This installs the console entry **`video-join`** and the package **`VideoJoin`**.
55
+
56
+ Optional dependency declared in packaging: `ChronicleLogger` (not required for the current interactive console paths).
57
+
58
+ ### PyPI
59
+
60
+ A future `pip install VideoJoin` channel may appear when the project is published to PyPI. **Today, install from source** as above. Do not assume a live PyPI release without checking [the project page](https://github.com/Wilgat/VideoJoin).
61
+
62
+ ## Usage
63
+
64
+ After install:
65
+
66
+ ```bash
67
+ # ensure videos are in the current directory
68
+ cd /path/to/folder/with/clips
69
+ video-join
70
+ ```
71
+
72
+ Or:
73
+
74
+ ```bash
75
+ python -m VideoJoin
76
+ ```
77
+
78
+ Session steps:
79
+
80
+ 1. Lists eligible videos in the current directory
81
+ 2. Choose first video (number)
82
+ 3. Choose second video from the remaining list
83
+ 4. Confirm or edit output name (default: `{stem1} + {stem2}.mp4`)
84
+ 5. FFmpeg stream-copy → on failure, re-encode → publish result
85
+
86
+ Exit codes: non-zero if fewer than two videos, FFmpeg missing, or join fails.
87
+
88
+ ## Examples
89
+
90
+ ```text
91
+ $ video-join
92
+ Video Joiner – WITH ORIGINAL AUDIO (using ffmpeg)
93
+
94
+ VideoJoin 1.0.3
95
+
96
+ Found video files:
97
+ 1. clip1.mp4
98
+ 2. clip2.mkv
99
+
100
+ Choose FIRST video → 1
101
+
102
+ Found video files:
103
+ 1. clip2.mkv
104
+
105
+ Choose SECOND video → 1
106
+
107
+ Output filename [clip1 + clip2.mp4]: joined.mp4
108
+
109
+ Joining with perfect audio sync:
110
+ clip1.mp4
111
+ + clip2.mkv
112
+ → joined.mp4
113
+ Staging dir → .
114
+
115
+ Running ffmpeg (stream copy – no quality loss)…
116
+ SUCCESS! Perfectly joined with original sound → joined.mp4
117
+ ```
118
+
119
+ Import for scripts (thin entry):
120
+
121
+ ```python
122
+ from VideoJoin import main
123
+ # interactive session; expects cwd videos + TTY stdin
124
+ ```
125
+
126
+ ## Platform Compatibility
127
+
128
+ | Platform | Status |
129
+ |----------|--------|
130
+ | Linux | Primary; tested development path |
131
+ | macOS | Supported when Python + FFmpeg on PATH |
132
+ | Windows | Supported when Python + FFmpeg on PATH (venv activate differs) |
133
+ | Architectures | Any with CPython + FFmpeg binary |
134
+
135
+ Interactive prompts need a terminal (or fed stdin). Non-interactive automation flags are not implemented yet.
136
+
137
+ ## Related Projects
138
+
139
+ - [VideoJoin on GitHub](https://github.com/Wilgat/VideoJoin) — this repository
140
+ - Sibling media tooling (same author ecosystem) may include other FFmpeg CLIs; this product is **two-file join only**, not cut/speed/boomerang editing
141
+
142
+ ## Contributing
143
+
144
+ 1. Keep product law under `docs/requirements/` in sync when behavior changes.
145
+ 2. Prefer small, CIAO-safe changes; do not remove Protection Zones in `cli.py` (staging / `shutil.move` publish) without explicit design.
146
+ 3. Version dual SSOT: bump **`pyproject.toml`** and **`src/VideoJoin/__init__.__version__`** together.
147
+ 4. Open issues and pull requests on GitHub.
148
+
149
+ ## License
150
+
151
+ MIT — see [`LICENSE.md`](./LICENSE.md). Also declared in `pyproject.toml`.
152
+
153
+ ## Last Update
154
+
155
+ 2026-08-09 — README aligned with **1.0.3** (fail-closed join, unique temps, `shutil.move` promote, honest install/runtime docs).
@@ -0,0 +1,139 @@
1
+ # VideoJoin - Join two local videos with FFmpeg (stream-copy first)
2
+
3
+ ![Version](https://img.shields.io/badge/Version-1.0.3-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/VideoJoin?style=flat-square)](https://github.com/Wilgat/VideoJoin)
7
+ [![Python](https://img.shields.io/badge/Python-2.7%2B%20(3.x%20recommended)-blue?style=flat-square)]()
8
+
9
+ VideoJoin is a lightweight **interactive** command-line tool that concatenates **two** video files from the current directory using **FFmpeg**. It prefers **stream copy** (no re-encode when possible) and **fail-closed re-encode fallback** when copy fails. Intermediate files are staged next to the output path when possible and published with **`shutil.move`** for multi-mount safety (for example USB).
10
+
11
+ ## Features
12
+
13
+ - Interactive pick of first and second video (same file cannot be chosen twice)
14
+ - Discovers `.mp4`, `.mov`, `.mkv`, `.avi`, `.m4v` in the **current working directory** (sorted case-insensitively)
15
+ - Stream-copy join first (`ffmpeg` concat demuxer); re-encode fallback (`libx264` CRF 18, AAC 192k)
16
+ - Fail-closed: no success message if both paths fail
17
+ - Unique temp list + media intermediates; cleanup on success and failure
18
+ - Publish intermediates with `shutil.move` (same FS rename; cross-mount copy+delete)
19
+ - FFmpeg on `PATH` checked before joining
20
+ - Console script `video-join` and module entry `python -m VideoJoin`
21
+
22
+ ## Quick Installation
23
+
24
+ **System requirement:** [FFmpeg](https://ffmpeg.org/download.html) must be installed and available as `ffmpeg` on your `PATH`. The package does **not** install FFmpeg via pip.
25
+
26
+ ### Local install (primary)
27
+
28
+ From a checkout:
29
+
30
+ ```bash
31
+ git clone https://github.com/Wilgat/VideoJoin.git
32
+ cd VideoJoin
33
+ python3 -m venv venv
34
+ source venv/bin/activate # Windows: venv\Scripts\activate
35
+ pip install -e .
36
+ ```
37
+
38
+ This installs the console entry **`video-join`** and the package **`VideoJoin`**.
39
+
40
+ Optional dependency declared in packaging: `ChronicleLogger` (not required for the current interactive console paths).
41
+
42
+ ### PyPI
43
+
44
+ A future `pip install VideoJoin` channel may appear when the project is published to PyPI. **Today, install from source** as above. Do not assume a live PyPI release without checking [the project page](https://github.com/Wilgat/VideoJoin).
45
+
46
+ ## Usage
47
+
48
+ After install:
49
+
50
+ ```bash
51
+ # ensure videos are in the current directory
52
+ cd /path/to/folder/with/clips
53
+ video-join
54
+ ```
55
+
56
+ Or:
57
+
58
+ ```bash
59
+ python -m VideoJoin
60
+ ```
61
+
62
+ Session steps:
63
+
64
+ 1. Lists eligible videos in the current directory
65
+ 2. Choose first video (number)
66
+ 3. Choose second video from the remaining list
67
+ 4. Confirm or edit output name (default: `{stem1} + {stem2}.mp4`)
68
+ 5. FFmpeg stream-copy → on failure, re-encode → publish result
69
+
70
+ Exit codes: non-zero if fewer than two videos, FFmpeg missing, or join fails.
71
+
72
+ ## Examples
73
+
74
+ ```text
75
+ $ video-join
76
+ Video Joiner – WITH ORIGINAL AUDIO (using ffmpeg)
77
+
78
+ VideoJoin 1.0.3
79
+
80
+ Found video files:
81
+ 1. clip1.mp4
82
+ 2. clip2.mkv
83
+
84
+ Choose FIRST video → 1
85
+
86
+ Found video files:
87
+ 1. clip2.mkv
88
+
89
+ Choose SECOND video → 1
90
+
91
+ Output filename [clip1 + clip2.mp4]: joined.mp4
92
+
93
+ Joining with perfect audio sync:
94
+ clip1.mp4
95
+ + clip2.mkv
96
+ → joined.mp4
97
+ Staging dir → .
98
+
99
+ Running ffmpeg (stream copy – no quality loss)…
100
+ SUCCESS! Perfectly joined with original sound → joined.mp4
101
+ ```
102
+
103
+ Import for scripts (thin entry):
104
+
105
+ ```python
106
+ from VideoJoin import main
107
+ # interactive session; expects cwd videos + TTY stdin
108
+ ```
109
+
110
+ ## Platform Compatibility
111
+
112
+ | Platform | Status |
113
+ |----------|--------|
114
+ | Linux | Primary; tested development path |
115
+ | macOS | Supported when Python + FFmpeg on PATH |
116
+ | Windows | Supported when Python + FFmpeg on PATH (venv activate differs) |
117
+ | Architectures | Any with CPython + FFmpeg binary |
118
+
119
+ Interactive prompts need a terminal (or fed stdin). Non-interactive automation flags are not implemented yet.
120
+
121
+ ## Related Projects
122
+
123
+ - [VideoJoin on GitHub](https://github.com/Wilgat/VideoJoin) — this repository
124
+ - Sibling media tooling (same author ecosystem) may include other FFmpeg CLIs; this product is **two-file join only**, not cut/speed/boomerang editing
125
+
126
+ ## Contributing
127
+
128
+ 1. Keep product law under `docs/requirements/` in sync when behavior changes.
129
+ 2. Prefer small, CIAO-safe changes; do not remove Protection Zones in `cli.py` (staging / `shutil.move` publish) without explicit design.
130
+ 3. Version dual SSOT: bump **`pyproject.toml`** and **`src/VideoJoin/__init__.__version__`** together.
131
+ 4. Open issues and pull requests on GitHub.
132
+
133
+ ## License
134
+
135
+ MIT — see [`LICENSE.md`](./LICENSE.md). Also declared in `pyproject.toml`.
136
+
137
+ ## Last Update
138
+
139
+ 2026-08-09 — README aligned with **1.0.3** (fail-closed join, unique temps, `shutil.move` promote, honest install/runtime docs).
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "VideoJoin"
7
- version = "1.0.2"
7
+ version = "1.0.3"
8
8
  description = "VideoJoin is a lightweight command-line tool for concatenating two video files (MP4, MOV, MKV, AVI, M4V) while preserving original audio and video quality using FFmpeg."
9
9
  readme = "README.md"
10
10
  requires-python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
@@ -0,0 +1,8 @@
1
+ # Package public surface — requirement-python-packaging / requirement-python-coding-style
2
+ # Do not re-export undefined symbols from .cli.
3
+
4
+ __version__ = "1.0.3"
5
+
6
+ from .cli import main
7
+
8
+ __all__ = ["__version__", "main"]
@@ -1,4 +1,4 @@
1
1
  from .cli import main
2
2
 
3
3
  if __name__ == "__main__":
4
- main()
4
+ main()