Cross-platform audio device hotplug detection with debouncing
Project description
audio-hotplug
Cross-platform audio device hotplug detection with debouncing for Windows, macOS, and Linux.
Features
- 🔌 Cross-platform: Works on Windows, macOS, and Linux
- ⚡ Debouncing: Coalesces rapid device changes to prevent callback storms
- 🔄 Async-ready: Supports both sync and async callbacks
- 🎯 Focused: Does one thing well - detects audio device topology changes
- 🪶 Lightweight: Minimal dependencies, platform-specific imports only when needed
Installation
# Install with uv
uv pip install audio-hotplug
# Or with pip
pip install audio-hotplug
Platform-specific dependencies are installed automatically based on your OS.
Quick Start
import asyncio
from audio_hotplug import create_monitor
def on_audio_devices_changed():
print("Audio devices changed!")
async def main():
loop = asyncio.get_running_loop()
# Create monitor with 200ms debounce
monitor = create_monitor(loop=loop, debounce_ms=200)
if monitor:
monitor.start(on_audio_devices_changed)
# Your application code here...
await asyncio.sleep(60)
monitor.stop()
asyncio.run(main())
Usage
Basic Usage (Sync Callback)
from audio_hotplug import create_monitor
def handle_change():
# Refresh your audio device list here
print("Device list changed!")
monitor = create_monitor()
if monitor:
monitor.start(handle_change)
Async Callback
import asyncio
from audio_hotplug import create_monitor
async def handle_change():
# Async operations supported
await notify_websocket_clients()
print("Device list changed!")
async def main():
loop = asyncio.get_running_loop()
monitor = create_monitor(loop=loop)
if monitor:
monitor.start(handle_change)
await asyncio.sleep(3600)
monitor.stop()
asyncio.run(main())
Custom Debouncing
# Adjust debounce time (milliseconds)
monitor = create_monitor(debounce_ms=500) # Wait 500ms after last change
Custom Logging
import logging
logger = logging.getLogger("my_app.audio")
monitor = create_monitor(logger=logger)
How It Works
The library monitors OS-level audio device notifications:
- Windows: Uses Core Audio API (
IMMNotificationClient) viapycaw - macOS: Uses CoreAudio property listeners via
pyobjc-framework-CoreAudio - Linux: Uses
udevsubsystem monitoring viapyudev
When devices are added, removed, or change state, the library:
- Detects the OS notification
- Triggers the debouncer
- Coalesces multiple rapid changes
- Invokes your callback once after the debounce period
API Reference
create_monitor()
Creates a platform-specific audio device monitor.
Parameters:
loop(optional):asyncio.AbstractEventLoop- Event loop for callback schedulingdebounce_ms(optional):int- Milliseconds to wait before invoking callback (default: 200)logger(optional):logging.Logger- Custom logger instance
Returns:
AudioDeviceMonitorinstance orNoneif platform unsupported
AudioDeviceMonitor
Abstract base class for platform monitors.
Methods:
start(on_change: Callback)- Start monitoring, callon_changewhen devices changestop()- Stop monitoring (safe to call multiple times)
Callback signature:
# Sync callback
def on_change() -> None: ...
# Or async callback
async def on_change() -> None: ...
Platform Support
| Platform | Dependency | Auto-installed |
|---|---|---|
| Windows | pycaw, comtypes |
✅ |
| macOS | pyobjc-framework-CoreAudio |
✅ |
| Linux | pyudev |
✅ |
Platform-specific dependencies are only installed on the relevant OS using package markers.
Development
This project uses uv for development:
# Clone the repository
git clone https://github.com/LedFx/audio-hotplug.git
cd audio-hotplug
# Install with dev dependencies
uv sync --extra dev
# Run tests
uv run pytest
# Run example
uv run python examples/monitor_print.py
# Build package
uv run python -m build
Testing
# Run all tests
uv run pytest -v
# Run with coverage
uv run pytest --cov=audio_hotplug --cov-report=html
# Run specific test
uv run pytest tests/test_debounce.py
Contributing
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
MIT License - see LICENSE file for details.
Acknowledgments
Extracted from LedFx to provide a reusable, focused library for audio device hotplug detection.
Related Projects
- LedFx - Real-time LED visualization system
- sounddevice - Audio I/O library
- PortAudio - Cross-platform audio I/O library
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 audio_hotplug-0.1.0.tar.gz.
File metadata
- Download URL: audio_hotplug-0.1.0.tar.gz
- Upload date:
- Size: 8.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e720f05289118217dee440fc8ebdf366ffe6009390448b17f6083b318a284e19
|
|
| MD5 |
d6d3076bcf6c600e0ec5cbfb11d54b99
|
|
| BLAKE2b-256 |
638fff69a4e1986e295e9de126f82372a5b168f388cb97fdce54948bd38e2d40
|
File details
Details for the file audio_hotplug-0.1.0-py3-none-any.whl.
File metadata
- Download URL: audio_hotplug-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dfe36dd1bff94b581efd5bee67caa82d87d448bf4f30318e3a7230e424fda78d
|
|
| MD5 |
4d9d3441f9614699d0a394b5cf11e0ba
|
|
| BLAKE2b-256 |
abe3b81c33d402983e52268fb2183190194a5fef4f84eece3d06aa05c4493fc5
|