### Start the Example Application Source: https://github.com/makeusabrew/audioteejs/blob/main/examples/assemblyai-universal-streaming/README.md Starts the AudioTee to AssemblyAI streaming example. This command runs the main application script. Use 'npm run dev' for development with auto-restart. ```bash npm start ``` -------------------------------- ### Install Dependencies with npm Source: https://github.com/makeusabrew/audioteejs/blob/main/examples/assemblyai-universal-streaming/README.md Installs the necessary Node.js packages for the project. This is a prerequisite for running the application. Ensure you have Node.js and npm installed. ```bash npm install ``` -------------------------------- ### AudioTee Binary Command Line Interface Examples Source: https://github.com/makeusabrew/audioteejs/blob/main/CLAUDE.md Demonstrates basic and advanced command-line usage of the AudioTee Swift binary, including capturing raw PCM data, specifying sample rates, chunk durations, and filtering processes. ```bash # Basic usage ./audiotee > output.pcm # With options ./audiotee --sample-rate 16000 --chunk-duration 0.1 --mute # Process filtering ./audiotee --include-processes 1234 5678 ./audiotee --exclude-processes 9012 ``` -------------------------------- ### AudioTee.js Usage Example with TypeScript Source: https://context7.com/makeusabrew/audioteejs/llms.txt Demonstrates how to instantiate and use the AudioTee class with TypeScript, including setting configuration options, handling 'data' and 'error' events, and starting the audio capture process. ```typescript import { AudioTee, AudioTeeOptions, AudioChunk } from 'audiotee' const options: AudioTeeOptions = { sampleRate: 16000, chunkDurationMs: 100, mute: false } const audiotee = new AudioTee(options) audiotee.on('data', (chunk: AudioChunk) => { const buffer: Buffer = chunk.data console.log(`Received ${buffer.length} bytes`) }) audiotee.on('error', (error: Error) => { console.error(error.message) }) await audiotee.start() ``` -------------------------------- ### Start and Stop Audio Capture with Async Methods Source: https://context7.com/makeusabrew/audioteejs/llms.txt Demonstrates how to initiate and terminate audio capture using the `start()` and `stop()` asynchronous methods provided by the AudioTee library. These methods return promises, enabling robust async/await error handling for scenarios like already running instances, platform compatibility, or binary issues. It also includes a graceful shutdown pattern using process event listeners. ```typescript import { AudioTee } from 'audiotee' const audiotee = new AudioTee({ sampleRate: 16000, chunkDurationMs: 100 }) // Start audio capture async function startCapture() { try { // Platform check happens automatically // Will reject if: // - Already running // - Not on macOS // - Binary not found // - Spawn error await audiotee.start() console.log('Capture started') } catch (error) { if (error.message.includes('already running')) { console.error('AudioTee is already capturing') } else if (error.message.includes('only supports macOS')) { console.error('This library only works on macOS') } else { console.error('Failed to start:', error) } } } // Stop audio capture async function stopCapture() { try { // Sends SIGTERM to the process // Force kills with SIGKILL after 5 seconds if unresponsive await audiotee.stop() console.log('Capture stopped cleanly') } catch (error) { console.error('Error during stop:', error) } } // Graceful shutdown pattern let isShuttingDown = false async function gracefulShutdown() { if (isShuttingDown) return isShuttingDown = true console.log('Shutting down...') await audiotee.stop() process.exit(0) } process.on('SIGINT', gracefulShutdown) process.on('SIGTERM', gracefulShutdown) // Start capture await startCapture() // Check if active console.log('Is capturing:', audiotee.isActive()) // true // Later, stop capture await stopCapture() console.log('Is capturing:', audiotee.isActive()) // false ``` -------------------------------- ### Initialize and Use AudioTee Stream (TypeScript) Source: https://github.com/makeusabrew/audioteejs/blob/main/CLAUDE.md Demonstrates how to initialize the AudioTee class with specific configurations for sample rate and chunk duration, and how to handle incoming audio data chunks via event listeners. This example utilizes the `audiotee` library for streaming audio processing. ```typescript import { AudioTee } from 'audiotee' const audiotee = new AudioTee({ sampleRate: 16000, chunkDurationMs: 100, mute: true, }) audiotee.on('data', (chunk) => { // Process raw PCM audio console.log(`${chunk.data.length} bytes at ${chunk.sampleRate}Hz`) }) audiotee.on('log', (message) => {}) // Placeholder for log handling audiotee.start() // Audio chunks will flow via 'data' events audiotee.stop() ``` -------------------------------- ### AudioTee Constructor and Basic Usage Source: https://context7.com/makeusabrew/audioteejs/llms.txt Instantiate AudioTee with optional configurations for sample rate, chunk duration, process inclusion/exclusion, and muting. Start and stop capture using await. ```APIDOC ## AudioTee Constructor and Basic Usage ### Description Create an AudioTee instance to capture system audio with configurable options for sample rate, chunk duration, process filtering, and mute behavior. ### Method `new AudioTee([options])` ### Parameters #### Constructor Options - **sampleRate** (number) - Optional - Convert audio to this sample rate. If specified, audio is 16-bit signed integers, mono. Defaults to device's native sample rate (32-bit floats, mono). - **chunkDurationMs** (number) - Optional - Emit audio chunks every X milliseconds. Defaults to 200. - **mute** (boolean) - Optional - Mute system audio while capturing. Defaults to `false`. - **includeProcesses** (number[]) - Optional - Array of process IDs to include in capture. If empty, all processes are included. - **excludeProcesses** (number[]) - Optional - Array of process IDs to exclude from capture. ### Usage Example ```typescript import { AudioTee, AudioChunk } from 'audiotee' // Basic usage with default settings const audiotee = new AudioTee() // With custom options const audioteeConfigured = new AudioTee({ sampleRate: 16000, chunkDurationMs: 100, mute: true, includeProcesses: [1234, 5678], excludeProcesses: [9012] }) // Listen for audio data audioteeConfigured.on('data', (chunk: AudioChunk) => { console.log(`Received ${chunk.data.length} bytes of audio data`) }) // Start capturing await audioteeConfigured.start() // Stop capturing await audioteeConfigured.stop() ``` ``` -------------------------------- ### Set AssemblyAI API Key Environment Variable Source: https://github.com/makeusabrew/audioteejs/blob/main/examples/assemblyai-universal-streaming/README.md Sets the AssemblyAI API key as an environment variable. This key is required to authenticate with the AssemblyAI service. Replace 'your-api-key-here' with your actual key. ```bash export ASSEMBLYAI_API_KEY="your-api-key-here" ``` -------------------------------- ### AudioTee Wrapper Class Implementation Hints: Binary Path Resolution Source: https://github.com/makeusabrew/audioteejs/blob/main/CLAUDE.md Provides a code snippet demonstrating how to resolve the path to the AudioTee binary within the npm package structure. ```typescript const binaryPath = join(__dirname, '..', 'bin', 'audiotee') ``` -------------------------------- ### Basic Audio Capture with AudioTee.js Source: https://github.com/makeusabrew/audioteejs/blob/main/README.md Demonstrates the basic usage of AudioTee.js for capturing system audio. It initializes AudioTee, listens for 'data' events containing audio chunks, starts capture, and stops it later. Requires 'audiotee' package. ```typescript import { AudioTee, AudioChunk } from 'audiotee' const audiotee = new AudioTee({ sampleRate: 16000 }) audiotee.on('data', (chunk: AudioChunk) => { // chunk.data contains a raw PCM chunk of captured system audio }) await audiotee.start() // ... later await audiotee.stop() ``` -------------------------------- ### TypeScript Interface for AudioChunk Structure Source: https://github.com/makeusabrew/audioteejs/blob/main/CLAUDE.md Defines the structure for audio data chunks emitted by the AudioTee wrapper, containing raw PCM audio bytes. ```typescript interface AudioChunk { data: Buffer // Raw PCM audio bytes // open for expansion } ``` -------------------------------- ### Configure AudioTee and AssemblyAI Transcriber in TypeScript Source: https://github.com/makeusabrew/audioteejs/blob/main/examples/assemblyai-universal-streaming/README.md Configures the AudioTee capture settings and the AssemblyAI transcriber. This snippet shows how to set the sample rate, chunk duration, enable formatted turns, and specify the audio encoding. ```typescript const audioTee = new AudioTee({ sampleRate: 16000, // Audio sample rate chunkDuration: 0.05, // 50ms chunks }) const transcriber = client.streaming.transcriber({ sampleRate: 16000, formatTurns: true, // Enable formatted final transcripts encoding: 'pcm_s16le', }) ``` -------------------------------- ### Event Handling: data, start, stop, error, log Source: https://context7.com/makeusabrew/audioteejs/llms.txt AudioTee emits events for audio data, lifecycle changes (start/stop), errors, and internal logs. Event listeners can be added, removed, or set to listen once. ```APIDOC ## Event Handling ### Description AudioTee uses an EventEmitter interface to stream audio data and lifecycle events. The library emits five event types for comprehensive monitoring. ### Events - **data**: Emitted for each captured audio chunk. - `chunk.data`: Buffer containing raw PCM audio data. - If `sampleRate` is specified in options: 16-bit signed integers, mono. - If `sampleRate` is NOT specified: 32-bit floats, mono. - **start**: Emitted when audio capture has successfully started. - **stop**: Emitted when audio capture has stopped. - **error**: Emitted when an error occurs during capture or processing. - Common errors include permission issues, platform errors (non-macOS), and binary spawn failures. - **log**: Emitted for informational and debug messages from the AudioTee binary. - `level`: 'info' | 'debug' - `message.message`: The log message string. - `message.context`: Optional metadata object. ### Usage Example ```typescript import { AudioTee, AudioChunk, LogLevel, MessageData } from 'audiotee' const audiotee = new AudioTee({ sampleRate: 16000, chunkDurationMs: 50 }) // Data event handler audiotee.on('data', (chunk: AudioChunk) => { processAudioChunk(chunk.data) }) // Lifecycle event handlers audiotee.on('start', () => { console.log('Audio capture started') }) audiotee.on('stop', () => { console.log('Audio capture stopped') }) // Error handling audiotee.on('error', (error: Error) => { console.error('AudioTee error:', error.message) }) // Logging event handler audiotee.on('log', (level: LogLevel, message: MessageData) => { if (level === 'debug') { console.debug(`[DEBUG] ${message.message}`, message.context) } else { console.info(`[INFO] ${message.message}`, message.context) } }) // Start capture try { await audiotee.start() } catch (error) { console.error('Failed to start:', error) } // Event listener management function myHandler(chunk: AudioChunk) { console.log('Got chunk') } audiotee.on('data', myHandler) audiotee.off('data', myHandler) // Remove specific listener audiotee.once('start', () => { console.log('First start only') }) audiotee.removeAllListeners('data') // Remove all 'data' listeners ``` ``` -------------------------------- ### TypeScript Interface for AudioTee Events Source: https://github.com/makeusabrew/audioteejs/blob/main/CLAUDE.md Defines the expected event interface for the AudioTee wrapper class, including types for audio data, recording status, errors, logs, and permission requirements. ```typescript interface AudioTeeEvents { data: (chunk: AudioChunk) => void // Raw PCM audio data start: () => void // Recording started stop: () => void // Recording stopped error: (error: Error) => void // Process/system errors log: (message: string, level: LogLevel) => void // Binary logs 'permission-required': () => void // macOS permission prompt } ``` -------------------------------- ### AudioTee Event Handling in TypeScript Source: https://context7.com/makeusabrew/audioteejs/llms.txt Illustrates how to handle various events emitted by AudioTee, including 'data' for audio chunks, lifecycle events ('start', 'stop'), error handling ('error'), and logging ('log'). It also shows how to manage event listeners using 'on', 'off', 'once', and 'removeAllListeners'. ```typescript import { AudioTee, AudioChunk, LogLevel, MessageData } from 'audiotee' const audiotee = new AudioTee({ sampleRate: 16000, chunkDurationMs: 50 }) // Audio data event - emitted for each captured chunk audiotee.on('data', (chunk: AudioChunk) => { // chunk.data: Buffer containing raw PCM audio // When sampleRate is specified: 16-bit signed integers, mono channel // Without sampleRate: 32-bit floats, mono channel processAudioChunk(chunk.data) }) // Lifecycle events audiotee.on('start', () => { console.log('Audio capture has started successfully') }) audiotee.on('stop', () => { console.log('Audio capture has stopped') cleanup() }) // Error handling audiotee.on('error', (error: Error) => { console.error('AudioTee error:', error.message) // Common errors: // - Process errors (binary not found, spawn failures) // - Permission issues (audio recording not granted) // - Platform errors (running on non-macOS system) }) // Logging from the AudioTee binary audiotee.on('log', (level: LogLevel, message: MessageData) => { // level: 'info' | 'debug' // message.message: string // message.context: optional metadata object if (level === 'debug') { console.debug(`[DEBUG] ${message.message}`, message.context) } else { console.info(`[INFO] ${message.message}`, message.context) } }) // Event listener management function myHandler(chunk: AudioChunk) { console.log('Got chunk') } audiotee.on('data', myHandler) // Add listener audiotee.off('data', myHandler) // Remove specific listener audiotee.once('start', () => { // Listen once console.log('First start only') }) audiotee.removeAllListeners('data') // Remove all listeners for event try { await audiotee.start() } catch (error) { console.error('Failed to start:', error) } ``` -------------------------------- ### TypeScript Interface for Log Message Structure Source: https://github.com/makeusabrew/audioteejs/blob/main/CLAUDE.md Defines the JSON payload structure for log messages received from the AudioTee binary via stderr, including timestamp, message type, and the log data. ```typescript interface LogMessage { timestamp: Date message_type: 'metadata' | 'stream_start' | 'stream_stop' | 'info' | 'error' | 'debug' data: { message: string } } ``` -------------------------------- ### AudioTee Constructor and Basic Usage in TypeScript Source: https://context7.com/makeusabrew/audioteejs/llms.txt Demonstrates how to create an AudioTee instance with default or custom options and how to listen for audio data. It covers configuring sample rate, chunk duration, process filtering, and muting. The 'data' event emits raw PCM audio chunks. ```typescript import { AudioTee, AudioChunk } from 'audiotee' // Basic usage with default settings (device default sample rate, 200ms chunks) const audiotee = new AudioTee() // With custom options const audioteeConfigured = new AudioTee({ sampleRate: 16000, // Convert audio to 16kHz (enables 16-bit PCM encoding) chunkDurationMs: 100, // Emit audio chunks every 100ms mute: true, // Mute system audio while capturing includeProcesses: [1234, 5678], // Only capture audio from these process IDs excludeProcesses: [9012] // Exclude audio from these process IDs }) // Listen for audio data audioteeConfigured.on('data', (chunk: AudioChunk) => { // chunk.data is a Buffer containing raw PCM audio console.log(`Received ${chunk.data.length} bytes of audio data`) }) // Start capturing await audioteeConfigured.start() // Stop capturing when done await audioteeConfigured.stop() ``` -------------------------------- ### TypeScript: Real-time System Audio Transcription with AssemblyAI Source: https://context7.com/makeusabrew/audioteejs/llms.txt This TypeScript code snippet demonstrates piping system audio captured by AudioTee to AssemblyAI's streaming transcription service. It handles connection events, transcription results (both partial and final), and errors from both services. It requires the `audiotee` and `assemblyai` npm packages and the `ASSEMBLYAI_API_KEY` environment variable. ```typescript import { AudioChunk, AudioTee, LogLevel, MessageData } from 'audiotee' import { AssemblyAI, TurnEvent } from 'assemblyai' const API_KEY = process.env.ASSEMBLYAI_API_KEY const SAMPLE_RATE = 16000 async function transcribeSystemAudio() { if (!API_KEY) { console.error('Set ASSEMBLYAI_API_KEY environment variable') process.exit(1) } console.log('Starting real-time transcription of system audio') console.log('Press Ctrl+C to stop\n') // Initialize AssemblyAI client const client = new AssemblyAI({ apiKey: API_KEY }) // Create streaming transcriber const transcriber = client.streaming.transcriber({ sampleRate: SAMPLE_RATE, formatTurns: true, // Group words into turns encoding: 'pcm_s16le', // 16-bit PCM little-endian }) // Initialize AudioTee with matching settings const audioTee = new AudioTee({ sampleRate: SAMPLE_RATE, // Match AssemblyAI sample rate chunkDurationMs: 50, // 50ms chunks (AssemblyAI recommendation) }) // AssemblyAI event handlers transcriber.on('open', ({ id }: { id: string }) => { console.log(`Connected to AssemblyAI (session: ${id})`) console.log('Listening...\n') }) transcriber.on('error', (error: Error) => { console.error('AssemblyAI error:', error) }) transcriber.on('close', (code: number, reason: string) => { console.log(`AssemblyAI closed: ${code} - ${reason}`) }) // Handle transcription results transcriber.on('turn', (turn: TurnEvent) => { if (!turn.transcript || turn.transcript.trim() === '') return if (!turn.end_of_turn || !turn.turn_is_formatted) { // Show partial transcript (real-time) process.stdout.write(`\r${turn.transcript}`) } else { // Show final formatted transcript process.stdout.write(`\r${' '.repeat(100)}\r`) // Clear line console.log(`${turn.transcript}`) } }) // AudioTee event handlers audioTee.on('start', () => { console.log('AudioTee: Capture started') }) audioTee.on('stop', () => { console.log('AudioTee: Capture stopped') }) audioTee.on('error', (error: Error) => { console.error('AudioTee error:', error) }) audioTee.on('log', (level: LogLevel, message: MessageData) => { console.log(`AudioTee [${level.toUpperCase()}]: ${message.message}`) }) // Pipe audio data to AssemblyAI audioTee.on('data', (chunk: AudioChunk) => { transcriber.sendAudio(chunk.data) }) // Graceful shutdown let isShuttingDown = false const shutdown = async () => { if (isShuttingDown) return isShuttingDown = true console.log('\nShutting down...') try { await audioTee.stop() await transcriber.close() console.log('Cleanup complete') } catch (error) { console.error('Shutdown error:', error) } process.exit(0) } process.on('SIGINT', shutdown) process.on('SIGTERM', shutdown) try { // Start both services await transcriber.connect() await audioTee.start() } catch (error) { console.error('Startup failed:', error) await shutdown() } } // Run the transcription transcribeSystemAudio().catch(console.error) ``` -------------------------------- ### AudioTee.js Event Handling Source: https://github.com/makeusabrew/audioteejs/blob/main/README.md Illustrates how to handle various events emitted by AudioTee.js, including audio data, capture start/stop, errors, and logging messages. This allows for comprehensive monitoring and control of the audio capture process. ```typescript // Audio data events audiotee.on('data', (chunk: { data: Buffer }) => { // Raw PCM audio data - mono channel, 32-bit float or 16-bit int depending on conversion }) // Lifecycle events audiotee.on('start', () => { // Audio capture has started }) audiotee.on('stop', () => { // Audio capture has stopped }) // Error handling audiotee.on('error', (error: Error) => { // Process errors, permission issues, etc. }) // Logging audiotee.on('log', (level: LogLevel, message: MessageData) => { // System logs from the AudioTee binary // LogLevel: 'info' | 'debug' // MessageData includes message string and optional context object }) ``` -------------------------------- ### Filter Audio Capture by Process ID Source: https://context7.com/makeusabrew/audioteejs/llms.txt Enables fine-grained control over audio capture by specifying which processes to include or exclude. This is achieved using the `includeProcesses` and `excludeProcesses` options when initializing `AudioTee`, allowing capture of specific applications or exclusion of others like system sounds or background services. Helper functions are provided to retrieve process IDs by application name. ```typescript import { AudioTee } from 'audiotee' import { exec } from 'child_process' import { promisify } from 'util' const execAsync = promisify(exec) // Helper to get process ID by application name async function getProcessIdByName(appName: string): Promise { try { const { stdout } = await execAsync(`pgrep -f "${appName}"`) // Note: escaped quotes return stdout.trim().split('\n').map(pid => parseInt(pid, 10)) } catch { return [] } } // Capture only Safari audio async function captureSafariOnly() { const safariPids = await getProcessIdByName('Safari') if (safariPids.length === 0) { console.error('Safari is not running') return } const audiotee = new AudioTee({ sampleRate: 16000, includeProcesses: safariPids, // Only capture these processes }) audiotee.on('data', (chunk) => { console.log(`Safari audio: ${chunk.data.length} bytes`) }) await audiotee.start() console.log(`Capturing only Safari audio (PIDs: ${safariPids.join(', ')})`) } // Capture all audio EXCEPT Spotify async function captureWithoutSpotify() { const spotifyPids = await getProcessIdByName('Spotify') const audiotee = new AudioTee({ sampleRate: 16000, excludeProcesses: spotifyPids, // Exclude these processes }) audiotee.on('data', (chunk) => { console.log(`System audio (no Spotify): ${chunk.data.length} bytes`) }) await audiotee.start() console.log('Capturing system audio, excluding Spotify') } // Capture multiple specific applications async function captureMultipleApps() { const chromePids = await getProcessIdByName('Google Chrome') const firefoxPids = await getProcessIdByName('Firefox') const allPids = [...chromePids, ...firefoxPids] const audiotee = new AudioTee({ sampleRate: 16000, includeProcesses: allPids, }) audiotee.on('data', (chunk) => { console.log(`Browser audio: ${chunk.data.length} bytes`) }) await audiotee.start() console.log(`Capturing Chrome + Firefox (${allPids.length} processes)`) } // Run examples await captureSafariOnly() ``` -------------------------------- ### AudioTee.js TypeScript Type Definitions Source: https://context7.com/makeusabrew/audioteejs/llms.txt Defines TypeScript interfaces and types for AudioTee.js configuration options, audio data chunks, log levels, and event handling. These types ensure type safety when using the AudioTee constructor and event listeners. ```typescript // Configuration options for AudioTee constructor interface AudioTeeOptions { sampleRate?: number // Target sample rate in Hz (e.g., 16000, 48000) // Setting this enables 16-bit PCM encoding // Default: device default (usually 48000) chunkDurationMs?: number // Chunk duration in milliseconds // Range: 0-5000ms // Default: 200ms mute?: boolean // Mute system audio during capture // Default: false includeProcesses?: number[] // Only capture from these process IDs // Cannot be used with excludeProcesses excludeProcesses?: number[] // Exclude these process IDs from capture // Cannot be used with includeProcesses binaryPath?: string // Custom path to audiotee binary // Default: bundled binary path } // Audio chunk emitted by 'data' events interface AudioChunk { data: Buffer // Raw PCM audio data // Format: mono channel // Encoding: 16-bit int (with sampleRate) // or 32-bit float (without) } // Log levels for 'log' events type LogLevel = 'info' | 'debug' // Message data structure for logs interface MessageData { message: string // Log message text context?: Record // Optional metadata object } // Internal log message format from binary interface LogMessage { timestamp: string // ISO timestamp message_type: MessageType // Type of message data: MessageData // Message payload } type MessageType = | 'metadata' // Capture metadata | 'stream_start' // Streaming started | 'stream_stop' // Streaming stopped | 'info' // Informational message | 'error' // Error message | 'debug' // Debug message // Event interface for type-safe event handling interface AudioTeeEvents { data: (chunk: AudioChunk) => void start: () => void stop: () => void error: (error: Error) => void log: (level: LogLevel, message: MessageData) => void } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.