Untitled
import { NativeEventEmitter, NativeModules, Platform } from 'react-native'; import notifee from '@notifee/react-native'; export type IOSInterruptionType = | 'phone_call' | 'facetime' | 'siri' | 'system_alert' | 'unknown'; export type IOSInterruptionEvent = { type: 'began' | 'ended'; reason: IOSInterruptionType; options?: { shouldResume?: boolean; }; }; class IOSAudioSessionManager { private listeners: Set<(event: IOSInterruptionEvent) => void> = new Set(); private audioSessionEmitter?: NativeEventEmitter; constructor() { if (Platform.OS === 'ios') { const { RNAudioRecorderPlayer } = NativeModules; this.audioSessionEmitter = new NativeEventEmitter(RNAudioRecorderPlayer); this.setupInterruptionListener(); } } private setupInterruptionListener(): void { if (!this.audioSessionEmitter) return; this.audioSessionEmitter.addListener( 'audioSessionInterruption', this.handleAudioInterruption ); } private handleAudioInterruption = (event: any) => { const interruptionType = this.getInterruptionType(event); this.notifyListeners({ type: event.type === 'began' ? 'began' : 'ended', reason: interruptionType, options: { shouldResume: event.type === 'ended' && event.options?.shouldResume } }); this.updateNotification(event.type, interruptionType); }; private getInterruptionType(event: any): IOSInterruptionType { switch (event.reason) { case 'AVAudioSessionInterruptionTypePhoneCall': return 'phone_call'; case 'AVAudioSessionInterruptionTypeFaceTime': return 'facetime'; case 'AVAudioSessionInterruptionTypeSiri': return 'siri'; case 'AVAudioSessionInterruptionTypeSystemAlert': return 'system_alert'; default: return 'unknown'; } } private async updateNotification( state: 'began' | 'ended', type: IOSInterruptionType ) { const messages = { phone_call: 'Phone Call', facetime: 'FaceTime Call', siri: 'Siri', system_alert: 'System Alert', unknown: 'System Interruption' }; await notifee.displayNotification({ id: 'recording-notification', title: state === 'began' ? 'Recording Paused' : 'Recording Resumed', body: state === 'began' ? `Recording paused due to ${messages[type]}` : 'Recording has resumed', ios: { categoryId: 'recording', interruptionLevel: 'active' } }); } public addListener(listener: (event: IOSInterruptionEvent) => void): () => void { this.listeners.add(listener); return () => this.listeners.delete(listener); } private notifyListeners(event: IOSInterruptionEvent): void { this.listeners.forEach(listener => listener(event)); } public cleanup(): void { if (this.audioSessionEmitter) { this.audioSessionEmitter.removeAllListeners('audioSessionInterruption'); } this.listeners.clear(); } } export const iOSAudioManager = new IOSAudioSessionManager();
Leave a Comment