npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@steelbrain/media-ingest-audio

v1.2.0

Published

Takes an incoming MediaStream and converts it into a ReadableStream for downstream consumers

Downloads

103

Readme

@steelbrain/media-ingest-audio

Convert MediaStream audio to ReadableStream with configurable sample rate for downstream processing.

Installation

npm install @steelbrain/media-ingest-audio

Modern Bundler Support: This package is fully compatible with modern bundlers (Webpack 5, Next.js, Vite, etc.). The AudioWorklet file is automatically detected and bundled - no manual setup or public folder configuration required.

Usage

import { ingestAudioStream, RECOMMENDED_AUDIO_CONSTRAINTS } from '@steelbrain/media-ingest-audio';

// Get microphone access
const mediaStream = await navigator.mediaDevices.getUserMedia({
  audio: RECOMMENDED_AUDIO_CONSTRAINTS
});

// Basic usage - convert to 16kHz audio stream (default)
const audioStream = await ingestAudioStream(mediaStream);

// With volume gain - boost quiet microphones
const boostedAudioStream = await ingestAudioStream(mediaStream, { gain: 2.0 });

// With volume reduction - lower loud inputs
const quietAudioStream = await ingestAudioStream(mediaStream, { gain: 0.5 });

// Use custom sample rate (e.g., 48kHz for high quality)
const highQualityStream = await ingestAudioStream(mediaStream, { sampleRate: 48000 });

// Process specific channel from stereo audio
const leftChannelStream = await ingestAudioStream(mediaStream, { channelId: 0 });  // Left channel
const rightChannelStream = await ingestAudioStream(mediaStream, { channelId: 1 }); // Right channel

// Combine options: boost right channel with custom sample rate
const boostedRightChannel = await ingestAudioStream(mediaStream, {
  gain: 2.0,
  channelId: 1,
  sampleRate: 44100
});

// Read audio data
const reader = audioStream.getReader();
const { value } = await reader.read(); // Float32Array of audio samples at configured sample rate

// Clean up when done
await reader.cancel();

API

ingestAudioStream(mediaStream: MediaStream, options?: AudioIngestOptions): Promise<ReadableStream<Float32Array>>

Converts a MediaStream into a ReadableStream of audio data with configurable sample rate and optional volume gain.

  • mediaStream: MediaStream containing audio tracks
  • options: Optional configuration (see AudioIngestOptions)
  • Returns: ReadableStream that yields Float32Array chunks of audio samples at the configured sample rate

AudioIngestOptions

Configuration options for audio ingestion:

interface AudioIngestOptions {
  /** Volume gain multiplier. 1.0 = no change, 2.0 = double volume, 0.5 = half volume. Default: 1.0 */
  gain?: number;
  /** Audio channel index to use (0-based). Default: 0 (first channel) */
  channelId?: number;
  /** Sample rate for the AudioContext. Default: 16000 */
  sampleRate?: number;
}

RECOMMENDED_AUDIO_CONSTRAINTS

Optimal audio constraints for raw voice capture:

{
  sampleRate: 16000,
  channelCount: 1
}

How it Works

  1. Creates an AudioContext with configurable sample rate (default: 16kHz)
  2. Uses AudioWorklet for efficient audio processing with optional volume gain
  3. Automatically handles sample rate conversion from input to target rate
  4. Applies volume gain multiplier to audio samples when specified
  5. Selects specific audio channel from multi-channel streams when channelId is specified
  6. Defaults to first channel (index 0) for consistent mono output

Use Cases

🎤 Microphone Normalization

// Boost quiet microphones (common for built-in laptop mics)
const audioStream = await ingestAudioStream(mediaStream, { gain: 1.5 });

🔉 Volume Reduction

// Reduce loud inputs to prevent clipping in downstream processing
const audioStream = await ingestAudioStream(mediaStream, { gain: 0.7 });

🎚️ Dynamic Range Adjustment

// Amplify weak signals for better speech detection accuracy
const audioStream = await ingestAudioStream(mediaStream, { gain: 2.5 });

🎧 Device-Specific Optimization

// Different gain settings based on microphone characteristics
const micLabel = mediaStream.getAudioTracks()[0].label.toLowerCase();
const gain = micLabel.includes('built-in') ? 1.8 : // Built-in mics are usually quiet
             micLabel.includes('headset') ? 1.2 :   // Headsets need moderate boost
             1.0; // External mics are usually well-calibrated

const audioStream = await ingestAudioStream(mediaStream, { gain });

🎛️ Stereo Channel Selection

// Process specific channels from stereo microphones
const leftChannel = await ingestAudioStream(mediaStream, { channelId: 0 });
const rightChannel = await ingestAudioStream(mediaStream, { channelId: 1 });

// Useful for stereo interview recordings where each person has their own channel
const interviewer = await ingestAudioStream(mediaStream, { channelId: 0, gain: 1.2 });
const interviewee = await ingestAudioStream(mediaStream, { channelId: 1, gain: 1.5 });

🎪 Multi-Channel Audio Interfaces

// Professional audio interfaces may have many channels
const channel3 = await ingestAudioStream(mediaStream, { channelId: 2 }); // Third input
const channel4 = await ingestAudioStream(mediaStream, { channelId: 3 }); // Fourth input

// Process each band member's microphone separately
const vocals = await ingestAudioStream(mediaStream, { channelId: 0, gain: 1.3 });
const guitar = await ingestAudioStream(mediaStream, { channelId: 1, gain: 0.9 });
const bass = await ingestAudioStream(mediaStream, { channelId: 2, gain: 1.1 });
const drums = await ingestAudioStream(mediaStream, { channelId: 3, gain: 0.8 });

🎵 Sample Rate Configuration

// Default 16kHz for voice applications (VAD, speech recognition)
const voiceStream = await ingestAudioStream(mediaStream);

// 44.1kHz for music quality
const musicStream = await ingestAudioStream(mediaStream, { sampleRate: 44100 });

// 48kHz for professional audio
const studioStream = await ingestAudioStream(mediaStream, { sampleRate: 48000 });

// 8kHz for telephony applications
const phoneStream = await ingestAudioStream(mediaStream, { sampleRate: 8000 });

// High sample rate with specific channel and gain
const highQualityVocals = await ingestAudioStream(mediaStream, {
  sampleRate: 96000,
  channelId: 0,
  gain: 1.2
});

Performance

  • Zero-copy optimization: When gain: 1.0 (default), no multiplication is performed
  • Efficient processing: Gain is applied directly in the AudioWorklet thread
  • Low latency: Processing happens in real-time without buffering delays
  • Memory efficient: Only creates new arrays when gain is applied

License

MIT