Cross-platform process-level audio capture library
Project description
📡 ProcTap
Cross-Platform Per-Process Audio Capture
ProcTap is a Python library for per-process audio capture with platform-specific backends.
Capture audio from a specific process only — without system sounds or other app audio mixed in. Ideal for VRChat, games, DAWs, browsers, and AI audio analysis pipelines.
Platform Support
| Platform | Status | Backend | Notes |
|---|---|---|---|
| Windows | ✅ Fully Supported | WASAPI (C++ native) | Windows 10/11 (20H1+) |
| Linux | 🧪 Experimental | PulseAudio/PipeWire | Basic support, sink monitor capture |
| macOS | 🧪 Experimental | Core Audio Process Tap | macOS 14.4+ (Sonoma) required |
* Linux and macOS support are experimental with limitations (see requirements). Windows is currently the only fully functional platform.
🚀 Features
-
🎧 Capture audio from a single target process (VRChat, games, browsers, Discord, DAWs, streaming tools, etc.)
-
🌍 Cross-platform architecture → Windows (fully supported) | Linux (experimental) | macOS (experimental, 14.4+)
-
⚡ Platform-optimized backends → Windows: ActivateAudioInterfaceAsync (modern WASAPI) → Linux: PulseAudio/PipeWire (experimental) → macOS: Core Audio Process Tap API (macOS 14.4+)
-
🧵 Low-latency, thread-safe audio engine → 44.1 kHz / stereo / 16-bit PCM format (Windows)
-
🐍 Python-friendly high-level API
- Callback-based streaming
- Async generator streaming (
async for)
-
🔌 Native extensions for high-performance → C++ extension on Windows for optimal throughput
📦 Installation
From PyPI:
pip install proc-tap
Platform-specific dependencies are automatically installed:
- Windows: No additional dependencies
- Linux:
pulsectlis automatically installed, but you also need system packages:# Ubuntu/Debian sudo apt-get install pulseaudio-utils # Fedora/RHEL sudo dnf install pulseaudio-utils
📚 Read the Full Documentation for detailed guides and API reference.
From TestPyPI (for testing pre-releases):
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ proctap
From Source:
git clone https://github.com/m96-chan/ProcTap
cd ProcTap
pip install -e .
🛠 Requirements
Windows (Fully Supported):
- Windows 10 / 11 (20H1 or later)
- Python 3.10+
- WASAPI support
- No admin privileges required
Linux (Experimental):
- Linux with PulseAudio or PipeWire (with pulseaudio-compat)
- Python 3.10+
pulsectllibrary: automatically installed withpip install proc-tappareccommand: install withsudo apt-get install pulseaudio-utils- ⚠️ EXPERIMENTAL: Basic PulseAudio support implemented
- ⚠️ LIMITATION: Currently captures from entire sink monitor (may include other apps)
macOS (Experimental):
- macOS 14.4 (Sonoma) or later
- Python 3.10+
- Swift CLI helper binary (proctap-macos)
- Audio capture permission
- ⚠️ EXPERIMENTAL: Core Audio Process Tap API support implemented
- ⚠️ REQUIREMENT: Requires macOS 14.4+ for Process Tap API
🧰 Basic Usage (Callback API)
from proctap import ProcTap, StreamConfig
def on_chunk(pcm: bytes, frames: int):
print(f"Received {len(pcm)} bytes ({frames} frames)")
pid = 12345 # Target process ID
tap = ProcTap(pid, StreamConfig(), on_data=on_chunk)
tap.start()
input("Recording... Press Enter to stop.\n")
tap.close()
🔁 Async Usage (Async Generator)
import asyncio
from proctap import ProcTap
async def main():
tap = ProcTap(pid=12345)
tap.start()
async for chunk in tap.iter_chunks():
print(f"PCM chunk size: {len(chunk)} bytes")
asyncio.run(main())
📄 API Overview
class ProcTap
Control Methods:
| Method | Description |
|---|---|
start() |
Start WASAPI per-process capture |
stop() |
Stop capture |
close() |
Release native resources |
Data Access:
| Method | Description |
|---|---|
iter_chunks() |
Async generator yielding PCM chunks |
read(timeout=1.0) |
Synchronous: read one chunk (blocking) |
Properties:
| Property | Type | Description |
|---|---|---|
is_running |
bool | Check if capture is active |
pid |
int | Get target process ID |
config |
StreamConfig | Get stream configuration |
Utility Methods:
| Method | Description |
|---|---|
set_callback(callback) |
Change or remove audio callback |
get_format() |
Get audio format info (dict) |
Audio Format
Note: The native extension uses a fixed audio format (hardcoded in C++):
| Parameter | Value | Description |
|---|---|---|
| Sample Rate | 44,100 Hz | CD quality (fixed) |
| Channels | 2 | Stereo (fixed) |
| Bit Depth | 16-bit | PCM format (fixed) |
The StreamConfig class exists for API compatibility but does not change the native backend format.
🎯 Use Cases
- 🎮 Record audio from one game only
- 🕶 Capture VRChat audio cleanly (without system sounds)
- 🎙 Feed high-SNR audio into AI recognition models
- 📹 Alternative to OBS "Application Audio Capture"
- 🎧 Capture DAW/app playback for analysis tools
📚 Example: Save to WAV
from proctap import ProcTap
import wave
pid = 12345
wav = wave.open("output.wav", "wb")
wav.setnchannels(2)
wav.setsampwidth(2) # 16-bit PCM
wav.setframerate(44100) # Native format is 44.1 kHz
def on_data(pcm, frames):
wav.writeframes(pcm)
with ProcTap(pid, on_data=on_data):
input("Recording... Press Enter to stop.\n")
wav.close()
📚 Example: Synchronous Read API
from proctap import ProcTap
tap = ProcTap(pid=12345)
tap.start()
try:
while True:
chunk = tap.read(timeout=1.0) # Blocking read
if chunk:
print(f"Got {len(chunk)} bytes")
# Process audio data...
else:
print("Timeout, no data")
except KeyboardInterrupt:
pass
finally:
tap.close()
🐧 Linux Example
from proctap import ProcessAudioTap, StreamConfig
import wave
pid = 12345 # Your target process ID
# Create WAV file
wav = wave.open("linux_capture.wav", "wb")
wav.setnchannels(2)
wav.setsampwidth(2)
wav.setframerate(44100)
def on_data(pcm, frames):
wav.writeframes(pcm)
# Create stream config (Linux backend respects these settings)
config = StreamConfig(sample_rate=44100, channels=2)
try:
with ProcessAudioTap(pid, config=config, on_data=on_data):
print("⚠️ Make sure the process is actively playing audio!")
input("Recording... Press Enter to stop.\n")
finally:
wav.close()
Linux-specific requirements:
- Install system package:
sudo apt-get install pulseaudio-utils(providespareccommand) - Python dependency
pulsectlis automatically installed withpip install proc-tap - The target process must be actively playing audio
- See examples/linux_basic.py for a complete example
🍎 macOS Example
from proctap import ProcessAudioTap, StreamConfig
import wave
pid = 12345 # Your target process ID
# Create WAV file
wav = wave.open("macos_capture.wav", "wb")
wav.setnchannels(2)
wav.setsampwidth(2)
wav.setframerate(48000) # macOS backend default is 48 kHz
def on_data(pcm, frames):
wav.writeframes(pcm)
# Create stream config (macOS backend respects these settings)
config = StreamConfig(sample_rate=48000, channels=2)
try:
with ProcessAudioTap(pid, config=config, on_data=on_data):
print("⚠️ Make sure the process is actively playing audio!")
print("⚠️ On first run, macOS will prompt for permission.")
input("Recording... Press Enter to stop.\n")
finally:
wav.close()
macOS-specific requirements:
- macOS 14.4 (Sonoma) or later
- Swift CLI helper binary (proctap-macos) - automatically built during installation if Swift toolchain available
- Audio capture permission - macOS will prompt on first run
- The target process must be actively playing audio
- See examples/macos_basic.py for a complete example
Building the Swift helper manually:
cd swift/proctap-macos
swift build -c release
cp .build/release/proctap-macos ../../src/proctap/bin/
🏗 Build From Source
git clone https://github.com/m96-chan/ProcTap
cd ProcTap
pip install -e .
Windows Build Requirements:
- Visual Studio Build Tools
- Windows SDK
- CMake (if you modularize the C++ code)
Linux/macOS:
- No C++ compiler required (pure Python)
- Note: Backends are not yet functional on these platforms
🤝 Contributing
Contributions are welcome! We have structured issue templates to help guide your contributions:
- 🐛 Bug Report - Report bugs or unexpected behavior
- ✨ Feature Request - Suggest new features or enhancements
- ⚡ Performance Issue - Report performance problems or optimizations
- 🔧 Type Hints / Async - Improve type annotations or async functionality
- 📚 Documentation - Improve docs, examples, or guides
Special Interest:
- PRs from WASAPI/C++ experts are especially appreciated
- Linux backend improvements (PulseAudio/PipeWire per-app isolation)
- macOS backend testing (Core Audio Process Tap on macOS 14.4+)
- Cross-platform testing and compatibility
- Performance profiling and optimization
📄 License
MIT License
👤 Author
m96-chan
Windows Audio / VRChat Tools / Python / C++
https://github.com/m96-chan
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 Distributions
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 proc_tap-0.2.0.tar.gz.
File metadata
- Download URL: proc_tap-0.2.0.tar.gz
- Upload date:
- Size: 23.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46be3c7c2ee63b946b6fc7d0fd9c334ea94959e66a9ae17d0c71de50a5e98234
|
|
| MD5 |
dd6ad0dc537eed6cf2201a5bf9ad2b07
|
|
| BLAKE2b-256 |
a7ea05e6620a6182cceeb164232ec98ff9144e4e073b0cd84bb30e65a47ff801
|
File details
Details for the file proc_tap-0.2.0-py3-none-any.whl.
File metadata
- Download URL: proc_tap-0.2.0-py3-none-any.whl
- Upload date:
- Size: 25.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b437b0db92c60ccab291a1f910dbe097ca3cf84fac3748ea5015a41074813b7
|
|
| MD5 |
fdd30ce08f188dfa0f09222b84c3576d
|
|
| BLAKE2b-256 |
54154d226d855bfb28eba9019cc9cc404383ee4dce9344ce5cfb687fda90583f
|
File details
Details for the file proc_tap-0.2.0-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: proc_tap-0.2.0-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 44.2 kB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f3b195d9ae71ec5cf1021ded437767f8a693c0eaab92f9a25b9a4880c9eae5ca
|
|
| MD5 |
25dc2644a9498bd1d04ed8c874ac7cd1
|
|
| BLAKE2b-256 |
15a3331c87539d6ca75eea42bfda4b7ae3b0460175b482fd4b3233bf3102c7b4
|
File details
Details for the file proc_tap-0.2.0-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: proc_tap-0.2.0-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 44.2 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b4e1efc057f9d8c51ca38eedf7e873bdb9b7e4dc513781715a0ed8e81a3a0042
|
|
| MD5 |
e5faed99d8b62a0324d586a02b5bf8bd
|
|
| BLAKE2b-256 |
a9963f71843b3b8f38957d078d124cc86d03547275ab1dbd8390739a418a9bc4
|
File details
Details for the file proc_tap-0.2.0-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: proc_tap-0.2.0-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 44.2 kB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a32ce1d4a89f198d22d9f0385b9c296879a456f0683333f2a2f4295a3bc45294
|
|
| MD5 |
6a4ef1760b78c4f868c9848ad52fa254
|
|
| BLAKE2b-256 |
21edc345abc9ba7bd47bf9744903b982f5388d79c4679867ce4b231efc4d50a6
|
File details
Details for the file proc_tap-0.2.0-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: proc_tap-0.2.0-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 44.2 kB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4385be0cbe55eb78466b61fa5b7549c795ce2ef0130d089a9754da797f565bb7
|
|
| MD5 |
85b98ea643d2b30def6694c4406b91b8
|
|
| BLAKE2b-256 |
dd26ddc3ddc1286f9ab78564f1ff041a7698aed6328b4aa007bc7daebb939009
|