@parastud/react-native-vban
v0.2.0
Published
VBAN (VB-Audio Network) audio-over-IP for React Native / Expo — native UDP send & receive, Android system-audio capture via MediaProjection, and a pure-TypeScript VBAN codec. Interoperates with Voicemeeter and other VBAN endpoints.
Downloads
495
Maintainers
Readme
@parastud/react-native-vban
VBAN (VB-Audio Network) audio-over-IP for React Native / Expo. Stream audio to and from a PC running Voicemeeter (or any VBAN endpoint) over your local network — no server, just UDP.
- Native receive — a UDP socket +
AudioTrackplayback run entirely on a native thread (with a large socket buffer), so you don't drop packets waiting on the JS bridge. - Native send —
AudioRecordcapture → VBAN packetization → UDP, also fully native and paced by the audio clock, so packets are evenly spaced. - Device (system) audio capture — capture the phone's own playback via
Android
MediaProjection+AudioPlaybackCapture(Android 10+). - Pure-TypeScript VBAN codec — encode/decode packet headers and convert PCM, usable on its own.
Platform: Android only for now. 16-bit PCM audio streams.
Install
npm install @parastud/react-native-vbanThis is an Expo module — it autolinks. You need a development build (not Expo Go). After installing, rebuild the native app:
npx expo run:androidThe module adds the FOREGROUND_SERVICE_MEDIA_PROJECTION permission and a
mediaProjection foreground service. Make sure your app also declares
RECORD_AUDIO and INTERNET.
Usage
Receive a stream (play it on the phone)
import { NativeVbanReceiver } from '@parastud/react-native-vban';
const rx = new NativeVbanReceiver();
await rx.start({ port: 6980 }, (stats) => {
console.log(stats.streamName, stats.level, 'dropped', stats.dropped);
});
// ... later
await rx.stop();Point Voicemeeter's outgoing VBAN stream at the phone's IP on that port.
Send audio to the PC
import { NativeVbanSender, isDeviceCaptureSupported } from '@parastud/react-native-vban';
const tx = new NativeVbanSender();
await tx.start(
{
host: '192.168.0.119', // the PC's IP
port: 6980,
streamName: 'Stream1',
sampleRate: 48000,
channels: 2,
source: 'mic', // or 'device' for system audio (shows a capture consent dialog)
},
(level) => console.log('level', level),
);
// ... later
await tx.stop();source: 'device' requires Android's MediaProjection consent (the OS
"start recording/casting" dialog). Only audio is captured — nothing of the
screen is read or sent — but the consent prompt is mandatory and cannot be
suppressed.
Pure VBAN codec
import { encodePacket, decodeHeader, float32ToPcm, VbanDataType } from '@parastud/react-native-vban';License
MIT
