Untitled
unknown
javascript
a year ago
3.1 kB
12
Indexable
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();Editor is loading...
Leave a Comment