UNPKG

@julianfrank/opensource

Version:

Open Source Projects from Julian Frank

588 lines (461 loc) â€ĸ 15.2 kB
# MicManager Documentation The MicManager is a TypeScript library (v2025.4.21) that provides a comprehensive interface for managing microphone input, audio recording, and waveform visualization in web applications. It offers a customizable UI component with microphone selection, recording controls, and real-time audio visualization. ## Table of Contents - [Features](#features) - [Installation](#installation) - [Basic Usage](#basic-usage) - [TypeScript Support](#typescript-support) - [Architecture](#architecture) - [Interfaces](#interfaces) - [API Reference](#api-reference) - [Examples](#examples) - [Error Handling](#error-handling) - [Browser Support](#browser-support) - [Development](#development) ## Features - 🎤 Microphone device selection and management - đŸŽšī¸ Audio recording controls with start/stop functionality - 📊 Real-time waveform visualization with configurable parameters - đŸŽ¯ Custom stream target support for advanced audio processing - 🎨 Fully customizable UI elements with theming support - 🔄 Automatic microphone list updates with caching - ⚡ Efficient event handling and automatic resource cleanup - 🔒 Built-in error handling and type safety with TypeScript - 📱 Responsive design with mobile device support ## Installation ```bash npm install @julianfrank/micmanager ``` ## Basic Usage First, import the MicManager class: ```typescript import { MicManager } from '@julianfrank/micmanager'; ``` Then create a new instance and initialize the UI: ```typescript // Create a new MicManager instance with default settings const micManager = new MicManager({ rootElement: document.getElementById('mic-container'), startButtonText: 'đŸŽ™ī¸ Start', stopButtonText: 'âšī¸ Stop', onStartRecording: (stream) => { console.log('Recording started', stream); }, onStopRecording: () => { console.log('Recording stopped'); } }); // Initialize the UI with waveform visualization micManager.createMicUI({ waveform: { enabled: true, width: 300, height: 150, backgroundColor: '#000000', waveformColor: '#00ff00', resolution: 32, refreshRate: 30 } }); // Optional: Customize the appearance micManager.setStyle({ backgroundColor: '#f0f0f0', waveformColor: '#ff0000', waveformBackgroundColor: '#333333', buttonBackgroundColor: '#ffffff', buttonShadowColor: 'rgba(0,0,0,0.3)', micListBackgroundColor: '#ffffff', micListBorderColor: '#cccccc' }); ``` ## TypeScript Support MicManager comes with full TypeScript support. The package includes type definitions for all classes, interfaces, and methods. ### Using Types in Your Project ```typescript import { MicManager, MicUIParameters, StreamTarget, WaveformConfig } from '@julianfrank/micmanager'; // Create a strongly-typed configuration const config: MicUIParameters = { rootElement: document.getElementById('mic-container') as HTMLElement, waveform: { enabled: true, width: 300, height: 150 } }; // Create a custom stream target with proper typing class CustomAudioProcessor implements StreamTarget { setStream(stream: MediaStream | null): void { // Implementation } start(): void { // Implementation } stop(): void { // Implementation } } const micManager = new MicManager(config); micManager.setStreamTarget(new CustomAudioProcessor()); ``` ### Available Types The package exports the following types: - `MicManager` - The main class - `Microphone` - Interface for microphone device information - `StreamTarget` - Interface for custom audio stream handlers - `WaveformConfig` - Interface for waveform visualization configuration - `MicUIParameters` - Interface for UI configuration parameters - `MicUIElements` - Interface for created UI elements - `MicManagerError`, `StreamError`, `DeviceError` - Error classes ## Architecture ```mermaid classDiagram class MicManager { -stream: MediaStream | null -rootElement: HTMLElement -elements: MicUIElements | null -streamTarget: StreamTarget | null -useDefaultAudioElement: boolean -eventListeners: Map -micListCache: Microphone[] | null -micListCacheTimestamp: number -audioContext: AudioContext | null -analyser: AnalyserNode | null -waveformConfig: WaveformConfig -animationFrameId: number | null +constructor(params: MicUIParameters) +createMicUI(params: MicUIParameters): MicUIElements +setStreamTarget(target: StreamTarget): void +clearStreamTarget(): void +getMicrophoneList(): Promise<Microphone[]> +toggleMicSettings(enabled: boolean): void +toggleWaveform(enabled: boolean): void +setStyle(styles: object): void +dispose(): void -addEventListenerWithCleanup(element, type, listener): void -removeEventListeners(element): void -updateMicList(micList, microphones): void -handleMicChange(): Promise<void> -startRecording(deviceId): Promise<void> -stopRecording(): void -updateWaveformPosition(): void -setupWaveform(stream): void -drawWaveform(): void -stopWaveform(): void } class StreamTarget { <<interface>> +setStream(stream: MediaStream | null): void +start?(): void +stop?(): void +onStreamStart?(): void +onStreamStop?(): void +onStreamError?(error: Error): void } class MicUIElements { <<interface>> +micWidget: HTMLDivElement +micSettingsContainer: HTMLDivElement +settingsButton: HTMLDivElement +micList: HTMLSelectElement +startButton: HTMLDivElement +stopButton: HTMLDivElement +audioElement: HTMLAudioElement +waveformCanvas?: HTMLCanvasElement +waveformContainer?: HTMLDivElement } class WaveformConfig { <<interface>> +enabled?: boolean +width?: number +height?: number +resolution?: number +refreshRate?: number +backgroundColor?: string +waveformColor?: string } class MicManagerError { +name: string +constructor(message: string) } class StreamError { +name: string +constructor(message: string) } class DeviceError { +name: string +constructor(message: string) } MicManager --> StreamTarget : uses MicManager --> MicUIElements : creates MicManager --> WaveformConfig : configures StreamError --|> MicManagerError : extends DeviceError --|> MicManagerError : extends ``` ## Interfaces ### MicUIParameters ```typescript interface MicUIParameters { rootElement?: HTMLElement; // Container element for the UI streamTarget?: StreamTarget; // Custom audio stream handler onMicListChange?: (mics: Microphone[]) => void; // Microphone list update callback onStartRecording?: (stream: MediaStream) => void; // Recording start callback onStopRecording?: () => void; // Recording stop callback onAudioElementError?: (error: Error) => void; startButtonText?: string; // Custom start button text stopButtonText?: string; // Custom stop button text waveform?: WaveformConfig; // Waveform visualization config showMicSettings?: boolean; // Whether to show mic settings by default } ``` ### StreamTarget ```typescript interface StreamTarget { // Required method setStream(stream: MediaStream | null): void; // Optional methods start?(): void; stop?(): void; // Optional event handlers onStreamStart?(): void; onStreamStop?(): void; onStreamError?(error: Error): void; } ``` ### WaveformConfig ```typescript interface WaveformConfig { enabled?: boolean; // Enable/disable waveform visualization width?: number; // Canvas width in pixels height?: number; // Canvas height in pixels resolution?: number; // FFT size / 2 refreshRate?: number; // Updates per second backgroundColor?: string; // Canvas background color waveformColor?: string; // Waveform line color } ``` ### Microphone ```typescript interface Microphone { deviceId: string; // Unique device identifier label: string; // Human-readable device name } ``` ## API Reference ### Constructor ```typescript constructor(params: MicUIParameters) ``` Creates a new MicManager instance. Only one instance can exist at a time. ### Methods #### createMicUI ```typescript createMicUI(params: MicUIParameters): MicUIElements ``` Creates and returns the UI elements for microphone management. #### setStreamTarget ```typescript setStreamTarget(target: StreamTarget): void ``` Sets a custom stream target for handling the audio stream. #### clearStreamTarget ```typescript clearStreamTarget(): void ``` Removes the custom stream target and reverts to using the default audio element. #### getMicrophoneList ```typescript async getMicrophoneList(): Promise<Microphone[]> ``` Returns a list of available microphone devices. #### dispose ```typescript dispose(): void ``` Cleans up resources and removes UI elements. #### toggleMicSettings ```typescript toggleMicSettings(enabled: boolean): void ``` Enables or disables the microphone settings interface. #### toggleWaveform ```typescript toggleWaveform(enabled: boolean): void ``` Enables or disables the waveform visualization. If disabled while recording, the waveform will stop; if enabled while recording, the waveform will start. #### setStyle ```typescript setStyle(styles: { backgroundColor?: string; waveformColor?: string; waveformBackgroundColor?: string; buttonBackgroundColor?: string; buttonShadowColor?: string; micListBackgroundColor?: string; micListBorderColor?: string; }): void ``` Sets custom styles for various UI components. All parameters are optional: - `backgroundColor`: Background color of the main widget - `waveformColor`: Color of the waveform line - `waveformBackgroundColor`: Background color of the waveform canvas - `buttonBackgroundColor`: Background color of all buttons - `buttonShadowColor`: Shadow color for all buttons - `micListBackgroundColor`: Background color of the microphone selection dropdown - `micListBorderColor`: Border color of the microphone selection dropdown ## Examples ### Basic Recording with Waveform ```typescript const micManager = new MicManager({ rootElement: document.getElementById('mic-container') }); const ui = micManager.createMicUI({ startButtonText: 'đŸŽ™ī¸ Start', stopButtonText: 'âšī¸ Stop', waveform: { enabled: true, width: 300, height: 150, resolution: 32, refreshRate: 30, backgroundColor: '#000000', waveformColor: '#00ff00' }, onStartRecording: (stream) => { console.log('Recording started'); }, onStopRecording: () => { console.log('Recording stopped'); } }); ``` ### Custom UI Configuration ```typescript const micManager = new MicManager({ rootElement: document.getElementById('mic-container') }); const ui = micManager.createMicUI({ startButtonText: 'đŸŽ™ī¸ Start', stopButtonText: 'âšī¸ Stop', showMicSettings: true, waveform: { enabled: true, width: 300, height: 150 } }); // Customize the appearance micManager.setStyle({ backgroundColor: '#f0f0f0', waveformColor: '#ff0000', waveformBackgroundColor: '#333333', buttonBackgroundColor: '#ffffff', buttonShadowColor: 'rgba(0,0,0,0.3)', micListBackgroundColor: '#ffffff', micListBorderColor: '#cccccc' }); // Toggle UI components micManager.toggleMicSettings(true); // Show mic settings micManager.toggleWaveform(false); // Hide waveform // Later, when recording starts micManager.toggleWaveform(true); // Show waveform during recording ``` ### Custom Stream Target ```typescript class AudioProcessor implements StreamTarget { private audioContext: AudioContext; private processor: ScriptProcessorNode; constructor() { this.audioContext = new AudioContext(); } setStream(stream: MediaStream | null): void { if (stream) { const source = this.audioContext.createMediaStreamSource(stream); source.connect(this.processor); } } start(): void { console.log('Processing started'); } stop(): void { console.log('Processing stopped'); } onStreamError(error: Error): void { console.error('Stream error:', error); } } const micManager = new MicManager({ rootElement: document.getElementById('mic-container'), streamTarget: new AudioProcessor() }); micManager.createMicUI({ waveform: { enabled: true } }); ``` ## Error Handling The MicManager provides custom error types for better error handling: ```typescript // Base error type class MicManagerError extends Error { name = "MicManagerError"; } // Stream-related errors class StreamError extends MicManagerError { name = "StreamError"; } // Device-related errors class DeviceError extends MicManagerError { name = "DeviceError"; } // Error handling example try { await micManager.startRecording(); } catch (error) { if (error instanceof StreamError) { console.error('Stream error:', error.message); } else if (error instanceof DeviceError) { console.error('Device error:', error.message); } else { console.error('Unknown error:', error); } } ``` ## Development ### Prerequisites - Node.js (Latest LTS version recommended) - npm or yarn ### Setup 1. Clone the repository 2. Install dependencies: ```bash npm install ``` ### Available Scripts - `npm run dev` - Start development server with hot reload - `npm run build` - Build for production - `npm run preview` - Preview production build ### Dependencies - TypeScript 5.8.3 - Vite 6.3.2 - @vitejs/plugin-basic-ssl 2.0.0 - vite-plugin-css-injected-by-js 3.5.2 ## Best Practices 1. **Singleton Usage**: Only one MicManager instance should exist at a time. 2. **Resource Cleanup**: Always call `dispose()` when the MicManager is no longer needed. 3. **Error Handling**: Implement proper error handling using the provided error types. 4. **Stream Target**: Use custom stream targets for advanced audio processing. 5. **Waveform Configuration**: Adjust waveform settings based on performance requirements. 6. **Mobile Support**: Test on various devices and screen sizes. 7. **Memory Management**: Properly dispose of instances to prevent memory leaks. ## Browser Support MicManager requires browsers that support: - `MediaDevices` API - `getUserMedia` - Web Audio API - Canvas API Supported Browsers: - Chrome (latest) - Firefox (latest) - Safari (latest) - Edge (latest) ## License This project is licensed under the MIT License.