Tauri 2 plugin for capturing audio from devices and applications using the Windows Audio Session API (WASAPI). Audio data is streamed to the frontend in real-time via Tauri's Channel IPC.
Author: Max Vohra max-oss@seattlenetworks.com
- Device capture — record from microphones and other capture devices
- Loopback capture — record system output audio (what you hear)
- Application capture — record audio from a specific process (Windows 10 20348+)
- Device enumeration — list all audio devices and their state
- Process listing — list running processes for application-specific capture
- Real-time streaming — PCM audio data streamed via Tauri Channel IPC
- VU Meter visualization — includes logic for calculating and displaying real-time levels
| Platform | Supported |
|---|---|
| Windows | ✅ |
| macOS | ❌ |
| Linux | ❌ |
| Android | ❌ |
| iOS | ❌ |
For a detailed breakdown of the file structure, see FILES.md.
Add the plugin to your Tauri app's Cargo.toml:
[dependencies]
tauri-plugin-wasapi = { path = "../tauri-plugin-wasapi" }Register the plugin in your app:
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_wasapi::init())
.run(tauri::generate_context!())
.expect("error while running application");
}Add the plugin permissions to your tauri.conf.json:
{
"plugins": {
"wasapi": {
"permissions": ["wasapi:default"]
}
}
}npm install tauri-plugin-wasapi-api
# or link locally during developmentimport { listDevices } from 'tauri-plugin-wasapi-api';
const devices = await listDevices();
for (const device of devices) {
console.log(`${device.name} (${device.direction}) — ${device.state}`);
}import { listProcesses } from 'tauri-plugin-wasapi-api';
const processes = await listProcesses();
for (const proc of processes) {
console.log(`PID ${proc.pid}: ${proc.name}`);
}import { startCapture, stopCapture } from 'tauri-plugin-wasapi-api';
await startCapture(
{ sessionId: 'mic-recording' },
(event) => {
switch (event.event) {
case 'format':
console.log('Format:', event.data);
break;
case 'data':
// event.data.data is a raw PCM byte array (f32le interleaved)
console.log(`Received ${event.data.frames} frames`);
break;
case 'error':
console.error('Capture error:', event.data.message);
break;
case 'stopped':
console.log('Capture stopped');
break;
}
},
);
// Later, stop the capture:
await stopCapture('mic-recording');await startCapture(
{ sessionId: 'loopback', loopback: true },
(event) => { /* handle events */ },
);import { listProcesses, startCapture } from 'tauri-plugin-wasapi-api';
const procs = await listProcesses();
const firefox = procs.find((p) => p.name.includes('firefox'));
if (firefox) {
await startCapture(
{ sessionId: 'app-capture', processId: firefox.pid },
(event) => { /* handle events */ },
);
}All capture sessions produce 32-bit float, interleaved PCM data. The sample rate (default 48 kHz) and channel count (default 2) can be configured per session. WASAPI's auto-convert feature handles resampling from the hardware format transparently.
# Install dependencies
bun install
# Build the Rust plugin
cargo build
# Build the TypeScript bindings
bun run build
# Run the example application
cd examples/tauri-app
bun install
bun run tauri devThis project uses standard documentation tools for both the Rust and TypeScript components:
To generate and view the complete API documentation for both Rust and TypeScript:
# Generate all documentation
npm run docs
# Rustdoc only
npm run docs:rust
# TypeDoc only
npm run docs:ts- Rustdoc is generated in
target/doc/tauri_plugin_wasapi/index.html. - TypeDoc is generated in
doc/api/index.html.
Additional architecture and troubleshooting guides are available in the doc/ directory.
MIT