TAP: Terminal Audio Player
Project description
TAP: Terminal Audio Player
This is a pure vibe-coding project, thus might be hard to maintain XOX
Interactive runtime testing is still strongest on Windows, although release binaries are now built for Windows, Linux, and macOS.
TAP is a Rich-based terminal audio player built for fast keyboard control, synchronized multi-track playback, and terminal-first workflows.
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.
Highlights
- terminal UI rendered with Rich
- grouped library tree for mixed
--filesinputs - synchronized
togetherplayback with shared transport - solo and together strategy families with runtime switching
- optional
ffmpegbackend with automatic fallback tominiaudio - keyboard-first controls for Windows, Linux, and macOS
- publishable Python package with a
tapplayercommand
Installation
Install from PyPI:
pip install tapplayer
Then run:
tapplayer --help
python -m tapplayer --help
If you prefer isolated CLI installs:
pipx install tapplayer
tapplayer --help
Install from source:
git clone <your-repo-url>
cd tap
uv sync --extra dev
uv run tapplayer --help
For local development, the compatibility launcher still works:
uv run python main.py --help
TAP pins uv to free-threaded CPython 3.14t via .python-version. CI, PyPI builds, and release binaries for Windows, Linux, and macOS are all expected to run on that interpreter variant.
Platform Binaries
TAP also ships with a GitHub Actions workflow that builds standalone release binaries for Windows, Linux, and macOS.
- Run the
Build Platform Binariesworkflow manually to get downloadable Actions artifacts. - Push a version tag like
v0.2.0to build release archives for all three platforms and attach them to the GitHub release. - Windows ships as
tapplayer-windows-<arch>-v0.2.0.zipwithtapplayer.exe. - Linux ships as
tapplayer-linux-<arch>-v0.2.0.tar.gzwithtapplayer. - macOS ships as
tapplayer-macos-<arch>-v0.2.0.tar.gzwithtapplayer. - Every archive contains the binary plus
README.mdandLICENSE. - The workflow builds with uv-managed free-threaded CPython
3.14t.
To build the standalone binary locally:
uv run --with pyinstaller pyinstaller --noconfirm --clean tap.spec
dist/tapplayer --help
On Windows, the output file is dist/tapplayer.exe.
Quick Start
tapplayer --files "~/Music/Drums" "~/Music/bass.wav" --strategy together --time auto-max
Common examples:
tapplayer --files ./stems ./vox.wav
tapplayer --files ./album --generic-mode solo --strategy playlist-once
tapplayer --files ./stems --decode-backend auto
tapplayer --files ./stems --arrow-mode hjkl
Features
--filesaccepts a mixed list of audio files and folders- folders are scanned recursively and grouped under source nodes
- direct single-file inputs are collected under one
Single Filesnode - global play, pause, stop, reverse, seek, and volume controls stay global
--generic-modelimits the available strategy family tosolo,together, orboth--strategysupportsplaylist-once,track-loop,track-once,playlist-loop,random,together, andtogether-loop--timecontrols the shared transport length fortogetherandtogether-loop--decode-backendsupportsauto,miniaudio, andffmpeg--disable-*flags can hide risky controls and disable the matching key paths
Platform Notes
- keyboard input is supported on Windows, Linux, and macOS
- the current UI is intentionally keyboard-only for better terminal compatibility
- Linux and macOS use
termios/tty/select - Windows uses guarded Win32 keyboard APIs
ffmpegdecoding is optional and only requires theffmpegexecutable onPATH- if your terminal does not send
F1reliably, useUfor help
Supported Formats
wav, mp3, flac, ogg, vorbis
Actual decode support depends on the active backend. ffmpeg generally handles more real-world edge cases.
CLI Overview
--files PATH [PATH ...]Mix audio files and folders in one command.--generic-mode solo|together|bothLimits the available strategy family.--strategy MODESets the initial strategy inside the selected generic mode.--time auto-max|auto-minShared transport policy fortogetherandtogether-loop.--decode-backend auto|miniaudio|ffmpegChooses the decode backend.autoprefersffmpegwhen available.--arrow-mode hjkl|arrows|bothChooses directional input style.--forward-seconds/--backward-secondsSeek step sizes.--rate-fast-forward/--rate-slow-forwardHold playback rates.--disable-forward--disable-fast-forward--disable-backward--disable-fast-backward--disable-reverse--disable-strategy-change--disable-list-modify
Run tapplayer --help for the full argument list.
Runtime Controls
P: global play or pauseS: global stopD: tap to cycle strategy within the active generic mode, hold to open the mode pickerEnter: context action for the focused rowSpace: context action, or hold for fast playbackLeft/RightorH/L: seek, depending on--arrow-modeB: toggle reverse playbackBackspace/Delete: open a confirmation dialog and remove the focused track from the current playlistM: toggle track mute intogethermodesG: toggle group mute intogethermodesT: tap to cycletogethertime mode+/-: adjust volumeU/F1: show helpEsc/Ctrl+C/Q: quit
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.
Development
Install the project in editable mode:
uv sync --extra dev
Useful commands:
uv run python -m py_compile main.py src/tapplayer/__init__.py src/tapplayer/__main__.py src/tapplayer/_version.py src/tappl/app.py
uv run -p 3.14t --with build --with pyproject-hooks pyproject-build
uv run tapplayer --help
uv run python -m tapplayer --help
Please keep changes cross-platform when possible. Avoid introducing Windows-only dependencies unless they are fully guarded and optional.
For CI, releases, and local uv workflows, prefer the pinned free-threaded CPython 3.14t.
Project Layout
src/tapplayer/ Public Python package entrypoint
src/tappl/ Internal implementation package
main.py local compatibility launcher
.github/ issue templates and GitHub Actions
README.md project overview and usage
CONTRIBUTING.md contributor workflow
CODE_OF_CONDUCT.md community expectations
LICENSE project license
Release Workflow
TAP ships with GitHub Actions for CI, PyPI publishing, and Windows executable packaging.
For a release:
- Update
src/tapplayer/_version.py. - Commit the change.
- Create and push a tag like
v0.2.0. - The publish workflow builds the Python distribution and uploads it to PyPI.
- The platform binary workflow builds
tapplayer.exeon Windows plustapplayerarchives for Linux and macOS, uploads workflow artifacts, and attaches them on tag builds. - All release automation runs on uv-managed free-threaded CPython
3.14t.
The PyPI workflow is configured for Trusted Publishing. Before the first release, configure your PyPI project to trust this GitHub repository and workflow.
Community
- Read CONTRIBUTING.md before opening a pull request.
- Please follow CODE_OF_CONDUCT.md in all project spaces.
- Use the GitHub issue templates for bugs and feature requests.
License
TAP is released under the MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tapplayer-0.2.0.tar.gz.
File metadata
- Download URL: tapplayer-0.2.0.tar.gz
- Upload date:
- Size: 36.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2be9e65c7fdd728f412a20b917229bc86bd90275999316a752bd2a66beed5d81
|
|
| MD5 |
8b7c907fe2c5c2229718fc3c45b8bc66
|
|
| BLAKE2b-256 |
870945c9a9f542c42b1c8dc84cbb6ac9831a980c9280d74349258f0f258fa4a1
|
Provenance
The following attestation bundles were made for tapplayer-0.2.0.tar.gz:
Publisher:
publish.yml on lupnis/tappl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tapplayer-0.2.0.tar.gz -
Subject digest:
2be9e65c7fdd728f412a20b917229bc86bd90275999316a752bd2a66beed5d81 - Sigstore transparency entry: 1170274403
- Sigstore integration time:
-
Permalink:
lupnis/tappl@7a59752cf9f0e310e3066cb1c4452034c802d1ee -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/lupnis
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7a59752cf9f0e310e3066cb1c4452034c802d1ee -
Trigger Event:
push
-
Statement type:
File details
Details for the file tapplayer-0.2.0-py3-none-any.whl.
File metadata
- Download URL: tapplayer-0.2.0-py3-none-any.whl
- Upload date:
- Size: 34.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
38e7fcf17e65b6e62cacfd31721f1ce838b02dcf195444a35d62bfd1213af2ae
|
|
| MD5 |
240fa1345b59d82cdd79cf621526dc08
|
|
| BLAKE2b-256 |
26bef7c57bad518b74f598a34be37a0be03f69c3a855bd46b3678d6b1cd9b62a
|
Provenance
The following attestation bundles were made for tapplayer-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on lupnis/tappl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tapplayer-0.2.0-py3-none-any.whl -
Subject digest:
38e7fcf17e65b6e62cacfd31721f1ce838b02dcf195444a35d62bfd1213af2ae - Sigstore transparency entry: 1170274470
- Sigstore integration time:
-
Permalink:
lupnis/tappl@7a59752cf9f0e310e3066cb1c4452034c802d1ee -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/lupnis
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7a59752cf9f0e310e3066cb1c4452034c802d1ee -
Trigger Event:
push
-
Statement type: