UNPKG

z-web-audio-stream

Version:

iOS Safari-safe Web Audio streaming with separated download/storage optimization, instant playback, and memory management

158 lines 5.77 kB
import { type DownloadStrategy, type DownloadProgress } from './DownloadManager.js'; export interface WebAudioManagerOptions { workletPath?: string; enableCache?: boolean; maxCacheSize?: number; onTimeUpdate?: (currentTime: number, duration: number) => void; onEnded?: () => void; onError?: (error: Error) => void; onProgressiveLoadingStatus?: (status: 'STARTED' | 'PROGRESS' | 'COMPLETED' | 'FAILED', data?: any) => void; enableInstantPlayback?: boolean; instantPlaybackConfig?: InstantPlaybackConfig; obfuscationKey?: string; } export interface InstantPlaybackConfig { downloadStrategy?: Partial<DownloadStrategy>; storageChunkSize?: number; playbackChunkSize?: number; maxInitialWaitTime?: number; strategy?: 'auto' | 'always' | 'never'; enablePerformanceLogging?: boolean; } /** * iOS Safari-safe Web Audio manager with progressive streaming * * Key features: * - iOS-safe AudioContext initialization to fix pitch/speed issues * - Memory-safe progressive loading to prevent page reloads * - IndexedDB-based caching with Safari-specific retry logic * - AudioWorklet-based playback with sample rate monitoring * - Automatic cleanup and storage management */ export declare class WebAudioManager { private audioContext; private audioWorkletNode; private gainNode; private audioBuffers; private currentTrackId; private isInitialized; private preloadQueue; private chunkStore; private onTimeUpdate?; private onEnded?; private onError?; private onProgressiveLoadingStatus?; private lastKnownPosition; private positionRequestResolvers; private iosSafariDetected; private lastKnownSampleRate; private sampleRateMonitorInterval; private silentBuffer; private readonly MAX_TRANSFER_SIZE; private downloadManager; private streamingAssembler; private workletPath; private enableCache; private enableInstantPlayback; private instantPlaybackConfig; private obfuscationKey?; private instantPlaybackSessions; private defaultInstantConfig; constructor(options?: WebAudioManagerOptions); private isIOSSafari; private initializeOnUserGesture; private createIOSSafeAudioContext; private playDummyBuffer; private createSilentBuffer; private startSampleRateMonitoring; private handleSampleRateChange; initialize(): Promise<void>; private setupWorkletMessageHandling; loadAudio(url: string, trackId: string, progressCallback?: (loaded: number, total: number) => void): Promise<AudioBuffer>; play(trackId: string): Promise<void>; loadAndPlay(url: string, trackId: string, name?: string): Promise<void>; playInstantly(url: string, trackId: string, name: string, options?: { forceInstant?: boolean; onChunkLoaded?: (chunkIndex: number, totalChunks: number) => void; onFullyLoaded?: () => void; onDownloadProgress?: (progress: DownloadProgress) => void; }): Promise<void>; /** * Start playback with the first assembled chunk */ private startPlaybackWithChunk; /** * Seamlessly replace the current buffer with a larger one containing more audio data */ private seamlesslyReplaceBuffer; preloadAudio(url: string, trackId: string, name?: string): Promise<void>; pause(): Promise<void>; resume(): Promise<void>; seek(time: number): Promise<void>; setVolume(volume: number): void; getCurrentTime(): number; /** * Get the duration of a loaded audio buffer * @param trackId The track ID to get duration for * @returns Duration in seconds, or null if not loaded */ getBufferDuration(trackId: string): number | null; /** * Check if audio for a specific track is fully loaded * @param trackId The track ID to check * @returns True if audio is loaded and ready for playback */ isAudioLoaded(trackId: string): Promise<boolean>; /** * Get a list of all cached tracks with metadata * @returns Array of cached track information */ getCachedTracks(): Promise<Array<{ trackId: string; name?: string; duration?: number; size: number; lastAccessed: Date; isLoaded: boolean; }>>; private shouldUseInstantPlayback; private loadFirstChunk; private checkRangeSupport; private loadFirstChunkWithRangeRequest; private loadFirstChunkWithProgressiveDownload; private getFileSize; private loadRemainingChunksWithRangeRequests; private continueLoadingInBackground; private updateSessionWithLargerBuffer; private loadRemainingChunks; private loadChunk; private mergeAudioBuffers; private replaceBufferSeamlessly; private getCurrentPosition; getInstantPlaybackMetrics(): { enabled: boolean; config: InstantPlaybackConfig; activeSessions: number; sessionMetrics: Array<{ trackId: string; startTime: number; isActive: boolean; loadedChunks: number; totalChunks: number; }>; }; getPlaybackStrategy(url: string, options?: { estimatedFileSize?: number; connectionSpeed?: 'slow' | 'medium' | 'fast'; deviceType?: 'mobile' | 'desktop'; }): { strategy: 'instant' | 'progressive' | 'standard'; reasoning: string; recommendedConfig?: Partial<InstantPlaybackConfig>; }; enableInstantMode(config?: Partial<InstantPlaybackConfig>): void; disableInstantMode(): void; cleanup(): Promise<void>; } export declare function getWebAudioManager(options?: WebAudioManagerOptions): WebAudioManager; //# sourceMappingURL=WebAudioManager.d.ts.map