tapplayer 0.1.0__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 TAP contributors
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,250 @@
1
+ Metadata-Version: 2.4
2
+ Name: tapplayer
3
+ Version: 0.1.0
4
+ Summary: TAP: Terminal Audio Player
5
+ Author: TAP contributors
6
+ License-Expression: MIT
7
+ Keywords: audio,cli,ffmpeg,music,rich,terminal,tui
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: End Users/Desktop
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Operating System :: Microsoft :: Windows
13
+ Classifier: Operating System :: MacOS
14
+ Classifier: Operating System :: POSIX :: Linux
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Topic :: Multimedia :: Sound/Audio :: Players
18
+ Classifier: Topic :: Terminals
19
+ Requires-Python: >=3.14
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: miniaudio>=1.61
23
+ Requires-Dist: numpy>=2.4.3
24
+ Requires-Dist: rich>=14.3.3
25
+ Provides-Extra: dev
26
+ Requires-Dist: build>=1.2.2; extra == "dev"
27
+ Requires-Dist: pyproject-hooks>=1.2.0; extra == "dev"
28
+ Requires-Dist: twine>=6.1.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # TAP: Terminal Audio Player
32
+
33
+ > <font color="red">This is a pure vibe-coding project, thus might be hard to maintain XOX</font>
34
+
35
+ > <font color="red">This project has only been tested on Windows yet.</font>
36
+
37
+ TAP is a Rich-based terminal audio player built for fast keyboard control, synchronized multi-track playback, and terminal-first workflows.
38
+
39
+ It can scan folders and files from the command line, render a tree-style library view, switch between solo and together playback strategies, and optionally use `ffmpeg` as the decode backend.
40
+
41
+ ## Highlights
42
+
43
+ - terminal UI rendered with Rich
44
+ - grouped library tree for mixed `--files` inputs
45
+ - synchronized `together` playback with shared transport
46
+ - solo and together strategy families with runtime switching
47
+ - optional `ffmpeg` backend with automatic fallback to `miniaudio`
48
+ - keyboard-first controls for Windows, Linux, and macOS
49
+ - publishable Python package with a `tapplayer` command
50
+
51
+ ## Installation
52
+
53
+ Install from PyPI:
54
+
55
+ ```bash
56
+ pip install tapplayer
57
+ ```
58
+
59
+ Then run:
60
+
61
+ ```bash
62
+ tapplayer --help
63
+ python -m tapplayer --help
64
+ ```
65
+
66
+ If you prefer isolated CLI installs:
67
+
68
+ ```bash
69
+ pipx install tapplayer
70
+ tapplayer --help
71
+ ```
72
+
73
+ Install from source:
74
+
75
+ ```bash
76
+ git clone <your-repo-url>
77
+ cd tap
78
+ uv sync --extra dev
79
+ uv run tapplayer --help
80
+ ```
81
+
82
+ For local development, the compatibility launcher still works:
83
+
84
+ ```bash
85
+ uv run python main.py --help
86
+ ```
87
+
88
+ TAP pins `uv` to free-threaded CPython `3.14t` via [`.python-version`](.python-version). CI, PyPI builds, and Windows EXE releases are all expected to run on that interpreter variant.
89
+
90
+ ## Windows EXE
91
+
92
+ TAP also ships with a GitHub Actions workflow that builds a standalone Windows executable.
93
+
94
+ - Run the `Build Windows EXE` workflow manually to get a downloadable Actions artifact.
95
+ - Push a version tag like `v0.1.0` to build `tapplayer.exe` and attach a `.zip` archive to the GitHub release.
96
+ - The archive contains `tapplayer.exe`, `README.md`, and `LICENSE`.
97
+ - The workflow builds with uv-managed free-threaded CPython `3.14t`.
98
+
99
+ To build the executable locally on Windows:
100
+
101
+ ```bash
102
+ uv run --with pyinstaller pyinstaller --noconfirm --clean tap.spec
103
+ dist/tapplayer.exe --help
104
+ ```
105
+
106
+ ## Quick Start
107
+
108
+ ```bash
109
+ tapplayer --files "~/Music/Drums" "~/Music/bass.wav" --strategy together --time auto-max
110
+ ```
111
+
112
+ Common examples:
113
+
114
+ ```bash
115
+ tapplayer --files ./stems ./vox.wav
116
+ tapplayer --files ./album --generic-mode solo --strategy playlist-once
117
+ tapplayer --files ./stems --decode-backend auto
118
+ tapplayer --files ./stems --arrow-mode hjkl
119
+ ```
120
+
121
+ ## Features
122
+
123
+ - `--files` accepts a mixed list of audio files and folders
124
+ - folders are scanned recursively and grouped under source nodes
125
+ - direct single-file inputs are collected under one `Single Files` node
126
+ - global play, pause, stop, reverse, seek, and volume controls stay global
127
+ - `--generic-mode` limits the available strategy family to `solo`, `together`, or `both`
128
+ - `--strategy` supports `playlist-once`, `track-loop`, `track-once`, `playlist-loop`, `random`, `together`, and `together-loop`
129
+ - `--time` controls the shared transport length for `together` and `together-loop`
130
+ - `--decode-backend` supports `auto`, `miniaudio`, and `ffmpeg`
131
+ - `--disable-*` flags can hide risky controls and disable the matching key paths
132
+
133
+ ## Platform Notes
134
+
135
+ - keyboard input is supported on Windows, Linux, and macOS
136
+ - the current UI is intentionally keyboard-only for better terminal compatibility
137
+ - Linux and macOS use `termios` / `tty` / `select`
138
+ - Windows uses guarded Win32 keyboard APIs
139
+ - `ffmpeg` decoding is optional and only requires the `ffmpeg` executable on `PATH`
140
+ - if your terminal does not send `F1` reliably, use `U` for help
141
+
142
+ ## Supported Formats
143
+
144
+ `wav`, `mp3`, `flac`, `ogg`, `vorbis`
145
+
146
+ Actual decode support depends on the active backend. `ffmpeg` generally handles more real-world edge cases.
147
+
148
+ ## CLI Overview
149
+
150
+ - `--files PATH [PATH ...]`
151
+ Mix audio files and folders in one command.
152
+ - `--generic-mode solo|together|both`
153
+ Limits the available strategy family.
154
+ - `--strategy MODE`
155
+ Sets the initial strategy inside the selected generic mode.
156
+ - `--time auto-max|auto-min`
157
+ Shared transport policy for `together` and `together-loop`.
158
+ - `--decode-backend auto|miniaudio|ffmpeg`
159
+ Chooses the decode backend. `auto` prefers `ffmpeg` when available.
160
+ - `--arrow-mode hjkl|arrows|both`
161
+ Chooses directional input style.
162
+ - `--forward-seconds` / `--backward-seconds`
163
+ Seek step sizes.
164
+ - `--rate-fast-forward` / `--rate-slow-forward`
165
+ Hold playback rates.
166
+ - `--disable-forward`
167
+ - `--disable-fast-forward`
168
+ - `--disable-backward`
169
+ - `--disable-fast-backward`
170
+ - `--disable-reverse`
171
+ - `--disable-strategy-change`
172
+ - `--disable-list-modify`
173
+
174
+ Run `tapplayer --help` for the full argument list.
175
+
176
+ ## Runtime Controls
177
+
178
+ - `P`: global play or pause
179
+ - `S`: global stop
180
+ - `D`: tap to cycle strategy within the active generic mode, hold to open the mode picker
181
+ - `Enter`: context action for the focused row
182
+ - `Space`: context action, or hold for fast playback
183
+ - `Left/Right` or `H/L`: seek, depending on `--arrow-mode`
184
+ - `B`: toggle reverse playback
185
+ - `Backspace` / `Delete`: open a confirmation dialog and remove the focused track from the current playlist
186
+ - `M`: toggle track mute in `together` modes
187
+ - `G`: toggle group mute in `together` modes
188
+ - `T`: tap to cycle `together` time mode
189
+ - `+` / `-`: adjust volume
190
+ - `U` / `F1`: show help
191
+ - `Esc` / `Ctrl+C` / `Q`: quit
192
+
193
+ If the focused solo track is currently playing, opening the delete confirmation pauses playback until you confirm or cancel. Empty source folders disappear automatically when their last track is removed from the active playlist.
194
+
195
+ ## Development
196
+
197
+ Install the project in editable mode:
198
+
199
+ ```bash
200
+ uv sync --extra dev
201
+ ```
202
+
203
+ Useful commands:
204
+
205
+ ```bash
206
+ uv run python -m py_compile main.py src/tapplayer/__init__.py src/tapplayer/__main__.py src/tapplayer/_version.py src/tappl/app.py
207
+ uv run --extra dev python -m build
208
+ uv run tapplayer --help
209
+ uv run python -m tapplayer --help
210
+ ```
211
+
212
+ Please keep changes cross-platform when possible. Avoid introducing Windows-only dependencies unless they are fully guarded and optional.
213
+ For CI, releases, and local `uv` workflows, prefer the pinned free-threaded CPython `3.14t`.
214
+
215
+ ## Project Layout
216
+
217
+ ```text
218
+ src/tapplayer/ Public Python package entrypoint
219
+ main.py local compatibility launcher
220
+ .github/ issue templates and GitHub Actions
221
+ README.md project overview and usage
222
+ CONTRIBUTING.md contributor workflow
223
+ CODE_OF_CONDUCT.md community expectations
224
+ LICENSE project license
225
+ ```
226
+
227
+ ## Release Workflow
228
+
229
+ TAP ships with GitHub Actions for CI, PyPI publishing, and Windows executable packaging.
230
+
231
+ For a release:
232
+
233
+ 1. Update `src/tapplayer/_version.py`.
234
+ 2. Commit the change.
235
+ 3. Create and push a tag like `v0.1.0`.
236
+ 4. The publish workflow builds the Python distribution and uploads it to PyPI.
237
+ 5. The Windows EXE workflow builds `tapplayer.exe`, uploads a workflow artifact, and attaches a release archive on tag builds.
238
+ 6. All release automation runs on uv-managed free-threaded CPython `3.14t`.
239
+
240
+ The PyPI workflow is configured for Trusted Publishing. Before the first release, configure your PyPI project to trust this GitHub repository and workflow.
241
+
242
+ ## Community
243
+
244
+ - Read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request.
245
+ - Please follow [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) in all project spaces.
246
+ - Use the GitHub issue templates for bugs and feature requests.
247
+
248
+ ## License
249
+
250
+ TAP is released under the [MIT License](LICENSE).
@@ -0,0 +1,220 @@
1
+ # TAP: Terminal Audio Player
2
+
3
+ > <font color="red">This is a pure vibe-coding project, thus might be hard to maintain XOX</font>
4
+
5
+ > <font color="red">This project has only been tested on Windows yet.</font>
6
+
7
+ TAP is a Rich-based terminal audio player built for fast keyboard control, synchronized multi-track playback, and terminal-first workflows.
8
+
9
+ It can scan folders and files from the command line, render a tree-style library view, switch between solo and together playback strategies, and optionally use `ffmpeg` as the decode backend.
10
+
11
+ ## Highlights
12
+
13
+ - terminal UI rendered with Rich
14
+ - grouped library tree for mixed `--files` inputs
15
+ - synchronized `together` playback with shared transport
16
+ - solo and together strategy families with runtime switching
17
+ - optional `ffmpeg` backend with automatic fallback to `miniaudio`
18
+ - keyboard-first controls for Windows, Linux, and macOS
19
+ - publishable Python package with a `tapplayer` command
20
+
21
+ ## Installation
22
+
23
+ Install from PyPI:
24
+
25
+ ```bash
26
+ pip install tapplayer
27
+ ```
28
+
29
+ Then run:
30
+
31
+ ```bash
32
+ tapplayer --help
33
+ python -m tapplayer --help
34
+ ```
35
+
36
+ If you prefer isolated CLI installs:
37
+
38
+ ```bash
39
+ pipx install tapplayer
40
+ tapplayer --help
41
+ ```
42
+
43
+ Install from source:
44
+
45
+ ```bash
46
+ git clone <your-repo-url>
47
+ cd tap
48
+ uv sync --extra dev
49
+ uv run tapplayer --help
50
+ ```
51
+
52
+ For local development, the compatibility launcher still works:
53
+
54
+ ```bash
55
+ uv run python main.py --help
56
+ ```
57
+
58
+ TAP pins `uv` to free-threaded CPython `3.14t` via [`.python-version`](.python-version). CI, PyPI builds, and Windows EXE releases are all expected to run on that interpreter variant.
59
+
60
+ ## Windows EXE
61
+
62
+ TAP also ships with a GitHub Actions workflow that builds a standalone Windows executable.
63
+
64
+ - Run the `Build Windows EXE` workflow manually to get a downloadable Actions artifact.
65
+ - Push a version tag like `v0.1.0` to build `tapplayer.exe` and attach a `.zip` archive to the GitHub release.
66
+ - The archive contains `tapplayer.exe`, `README.md`, and `LICENSE`.
67
+ - The workflow builds with uv-managed free-threaded CPython `3.14t`.
68
+
69
+ To build the executable locally on Windows:
70
+
71
+ ```bash
72
+ uv run --with pyinstaller pyinstaller --noconfirm --clean tap.spec
73
+ dist/tapplayer.exe --help
74
+ ```
75
+
76
+ ## Quick Start
77
+
78
+ ```bash
79
+ tapplayer --files "~/Music/Drums" "~/Music/bass.wav" --strategy together --time auto-max
80
+ ```
81
+
82
+ Common examples:
83
+
84
+ ```bash
85
+ tapplayer --files ./stems ./vox.wav
86
+ tapplayer --files ./album --generic-mode solo --strategy playlist-once
87
+ tapplayer --files ./stems --decode-backend auto
88
+ tapplayer --files ./stems --arrow-mode hjkl
89
+ ```
90
+
91
+ ## Features
92
+
93
+ - `--files` accepts a mixed list of audio files and folders
94
+ - folders are scanned recursively and grouped under source nodes
95
+ - direct single-file inputs are collected under one `Single Files` node
96
+ - global play, pause, stop, reverse, seek, and volume controls stay global
97
+ - `--generic-mode` limits the available strategy family to `solo`, `together`, or `both`
98
+ - `--strategy` supports `playlist-once`, `track-loop`, `track-once`, `playlist-loop`, `random`, `together`, and `together-loop`
99
+ - `--time` controls the shared transport length for `together` and `together-loop`
100
+ - `--decode-backend` supports `auto`, `miniaudio`, and `ffmpeg`
101
+ - `--disable-*` flags can hide risky controls and disable the matching key paths
102
+
103
+ ## Platform Notes
104
+
105
+ - keyboard input is supported on Windows, Linux, and macOS
106
+ - the current UI is intentionally keyboard-only for better terminal compatibility
107
+ - Linux and macOS use `termios` / `tty` / `select`
108
+ - Windows uses guarded Win32 keyboard APIs
109
+ - `ffmpeg` decoding is optional and only requires the `ffmpeg` executable on `PATH`
110
+ - if your terminal does not send `F1` reliably, use `U` for help
111
+
112
+ ## Supported Formats
113
+
114
+ `wav`, `mp3`, `flac`, `ogg`, `vorbis`
115
+
116
+ Actual decode support depends on the active backend. `ffmpeg` generally handles more real-world edge cases.
117
+
118
+ ## CLI Overview
119
+
120
+ - `--files PATH [PATH ...]`
121
+ Mix audio files and folders in one command.
122
+ - `--generic-mode solo|together|both`
123
+ Limits the available strategy family.
124
+ - `--strategy MODE`
125
+ Sets the initial strategy inside the selected generic mode.
126
+ - `--time auto-max|auto-min`
127
+ Shared transport policy for `together` and `together-loop`.
128
+ - `--decode-backend auto|miniaudio|ffmpeg`
129
+ Chooses the decode backend. `auto` prefers `ffmpeg` when available.
130
+ - `--arrow-mode hjkl|arrows|both`
131
+ Chooses directional input style.
132
+ - `--forward-seconds` / `--backward-seconds`
133
+ Seek step sizes.
134
+ - `--rate-fast-forward` / `--rate-slow-forward`
135
+ Hold playback rates.
136
+ - `--disable-forward`
137
+ - `--disable-fast-forward`
138
+ - `--disable-backward`
139
+ - `--disable-fast-backward`
140
+ - `--disable-reverse`
141
+ - `--disable-strategy-change`
142
+ - `--disable-list-modify`
143
+
144
+ Run `tapplayer --help` for the full argument list.
145
+
146
+ ## Runtime Controls
147
+
148
+ - `P`: global play or pause
149
+ - `S`: global stop
150
+ - `D`: tap to cycle strategy within the active generic mode, hold to open the mode picker
151
+ - `Enter`: context action for the focused row
152
+ - `Space`: context action, or hold for fast playback
153
+ - `Left/Right` or `H/L`: seek, depending on `--arrow-mode`
154
+ - `B`: toggle reverse playback
155
+ - `Backspace` / `Delete`: open a confirmation dialog and remove the focused track from the current playlist
156
+ - `M`: toggle track mute in `together` modes
157
+ - `G`: toggle group mute in `together` modes
158
+ - `T`: tap to cycle `together` time mode
159
+ - `+` / `-`: adjust volume
160
+ - `U` / `F1`: show help
161
+ - `Esc` / `Ctrl+C` / `Q`: quit
162
+
163
+ If the focused solo track is currently playing, opening the delete confirmation pauses playback until you confirm or cancel. Empty source folders disappear automatically when their last track is removed from the active playlist.
164
+
165
+ ## Development
166
+
167
+ Install the project in editable mode:
168
+
169
+ ```bash
170
+ uv sync --extra dev
171
+ ```
172
+
173
+ Useful commands:
174
+
175
+ ```bash
176
+ uv run python -m py_compile main.py src/tapplayer/__init__.py src/tapplayer/__main__.py src/tapplayer/_version.py src/tappl/app.py
177
+ uv run --extra dev python -m build
178
+ uv run tapplayer --help
179
+ uv run python -m tapplayer --help
180
+ ```
181
+
182
+ Please keep changes cross-platform when possible. Avoid introducing Windows-only dependencies unless they are fully guarded and optional.
183
+ For CI, releases, and local `uv` workflows, prefer the pinned free-threaded CPython `3.14t`.
184
+
185
+ ## Project Layout
186
+
187
+ ```text
188
+ src/tapplayer/ Public Python package entrypoint
189
+ main.py local compatibility launcher
190
+ .github/ issue templates and GitHub Actions
191
+ README.md project overview and usage
192
+ CONTRIBUTING.md contributor workflow
193
+ CODE_OF_CONDUCT.md community expectations
194
+ LICENSE project license
195
+ ```
196
+
197
+ ## Release Workflow
198
+
199
+ TAP ships with GitHub Actions for CI, PyPI publishing, and Windows executable packaging.
200
+
201
+ For a release:
202
+
203
+ 1. Update `src/tapplayer/_version.py`.
204
+ 2. Commit the change.
205
+ 3. Create and push a tag like `v0.1.0`.
206
+ 4. The publish workflow builds the Python distribution and uploads it to PyPI.
207
+ 5. The Windows EXE workflow builds `tapplayer.exe`, uploads a workflow artifact, and attaches a release archive on tag builds.
208
+ 6. All release automation runs on uv-managed free-threaded CPython `3.14t`.
209
+
210
+ The PyPI workflow is configured for Trusted Publishing. Before the first release, configure your PyPI project to trust this GitHub repository and workflow.
211
+
212
+ ## Community
213
+
214
+ - Read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request.
215
+ - Please follow [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) in all project spaces.
216
+ - Use the GitHub issue templates for bugs and feature requests.
217
+
218
+ ## License
219
+
220
+ TAP is released under the [MIT License](LICENSE).
@@ -0,0 +1,54 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "tapplayer"
7
+ description = "TAP: Terminal Audio Player"
8
+ readme = { file = "README.md", content-type = "text/markdown" }
9
+ requires-python = ">=3.14"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ authors = [{ name = "TAP contributors" }]
13
+ keywords = ["audio", "cli", "ffmpeg", "music", "rich", "terminal", "tui"]
14
+ dynamic = ["version"]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Environment :: Console",
18
+ "Intended Audience :: End Users/Desktop",
19
+ "Intended Audience :: Developers",
20
+ "Operating System :: Microsoft :: Windows",
21
+ "Operating System :: MacOS",
22
+ "Operating System :: POSIX :: Linux",
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Python :: 3.14",
25
+ "Topic :: Multimedia :: Sound/Audio :: Players",
26
+ "Topic :: Terminals",
27
+ ]
28
+ dependencies = [
29
+ "miniaudio>=1.61",
30
+ "numpy>=2.4.3",
31
+ "rich>=14.3.3",
32
+ ]
33
+
34
+ [project.optional-dependencies]
35
+ dev = [
36
+ "build>=1.2.2",
37
+ "pyproject-hooks>=1.2.0",
38
+ "twine>=6.1.0",
39
+ ]
40
+
41
+ [project.scripts]
42
+ tapplayer = "tapplayer:main"
43
+
44
+ [tool.setuptools]
45
+ include-package-data = true
46
+
47
+ [tool.setuptools.package-dir]
48
+ "" = "src"
49
+
50
+ [tool.setuptools.packages.find]
51
+ where = ["src"]
52
+
53
+ [tool.setuptools.dynamic]
54
+ version = { attr = "tapplayer._version.__version__" }
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,4 @@
1
+ from .app import main
2
+ from ._version import __version__
3
+
4
+ __all__ = ["main", "__version__"]
@@ -0,0 +1,5 @@
1
+ from .app import main
2
+
3
+
4
+ if __name__ == "__main__":
5
+ main()
@@ -0,0 +1 @@
1
+ from tapplayer._version import __version__