Status: Beta Release Void Player is currently in its beta stage. While the core state-machine architecture, VLC playback engine, and headless Bluetooth integrations are stable, users may encounter edge cases depending on their specific hardware, rogue Bluetooth peripherals, or unsupported USB DACs. Bug reports and contributions are highly encouraged.
Void Player is a lightweight, high-performance headless audio player designed specifically for the Raspberry Pi. Built entirely in Python, it bypasses standard desktop environments to deliver a pure, physical-button-driven music experience with a dynamic OLED interface.
At its core, Void Player utilizes a decoupled, non-blocking state-machine architecture. It handles hardware interrupts, dynamic audio routing, multithreaded display rendering, and headless Bluetooth management without relying on standard time.sleep() UI loops, preventing thread starvation and ensuring a highly responsive tactile experience.
- Decoupled State-Machine Architecture: Uses a centralized event queue and an active button manager (
btn_mgr) to safely bind and unbind GPIO interrupts across different menu states. - Headless Bluetooth Management: Interacts directly with the Linux BlueZ stack via
bluetoothctlsubprocesses. Handles device scanning, MAC address filtering, pairing, trusting, and connecting entirely through the 128x64 OLED UI. - Dynamic Audio Routing: Hot-swaps active audio streams between Bluetooth sinks, external USB DACs, HDMI, and built-in audio jacks. Built on PulseAudio/PipeWire and managed via
pactl. - VLC-Powered Playback Engine: Supports FLAC, WAV, and MP3 formats with dynamic ID3 tag extraction via
tinytag. Includes an isolated background thread for scrolling long track titles and rendering playback states smoothly. - Hardware Debouncing: Custom wrapper for
gpiozeroimplementing a 50ms re-entrancy lock and debounce window to prevent ghost inputs and overlapping handler execution.
- SBC: Raspberry Pi (Zero 2 W, 3, or 4 recommended for optimal VLC and PipeWire performance)
- Display: 128x64 I2C OLED Display (e.g., SSD1306)
- Input: 6x Tactile Push Buttons
- Audio Output: USB DAC (recommended for high-fidelity output) or a paired Bluetooth device.
Void Player relies on the Raspberry Pi's internal pull-up resistors. Each tactile button must be wired directly between its designated GPIO pin and any available Ground (GND) pin on the Pi. No external pull-up or pull-down resistors are required.
- Menu / Back: GPIO 24
- Center / Select: GPIO 18
- Next Track / Down: GPIO 22
- Previous Track / Up: GPIO 27
- Volume Up: GPIO 17
- Volume Down: GPIO 23
The SSD1306 display connects via the standard hardware I2C pins:
- VCC: 3.3V (Pin 1)
- GND: Ground (Pin 6 or Pin 9)
- SDA: GPIO 2 (Pin 3)
- SCL: GPIO 3 (Pin 5)
Void Player requires the standard Linux audio and Bluetooth stacks to function correctly.
System Packages: Ensure your Raspberry Pi has the following backend utilities installed:
sudo apt-get update
sudo apt-get install vlc pulseaudio-utils pulseaudio-module-bluetooth bluez
Python Requirements: Install the necessary Python libraries using pip:
pip install -r requirements.txt
- Clone the repository:
git clone https://github.com/kashbix/void-player.git
cd void-player
- Prepare the Music Directory:
By default, the player scans for media in
/home/$USER/Music. Ensure your FLAC, WAV, or MP3 files are placed in this directory, or updateconfigs.MUSIC_DIRto point to your desired path. - Configure Fonts (Optional):
The UI uses
DejaVuSans-Bold.ttffor crisp rendering. If this font is not available on your system, theconfigs.pyfile will automatically fall back to the default Pillow font. - Run the Application:
python3 main.py
Deployment Note: For a true headless appliance experience, it is highly recommended to configure main.py to run as a systemd background service on boot.
This project is open-source and available under the MIT License. See the LICENSE file for further details.