-
Notifications
You must be signed in to change notification settings - Fork 64
Expand file tree
/
Copy pathAudioSession.ts
More file actions
306 lines (285 loc) · 7.99 KB
/
AudioSession.ts
File metadata and controls
306 lines (285 loc) · 7.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
import { Platform } from 'react-native';
import LiveKitModule from '../LKNativeModule';
/**
* Configuration for the underlying AudioSession.
*
* ----
* Android specific options:
*
* * preferredOutputList - The preferred order in which to automatically select an audio output.
* This is ignored when an output is manually selected with {@link AudioSession.selectAudioOutput}.
*
* By default, the order is set to:
* 1. `"bluetooth"
* 2. `"headset"``
* 3. `"speaker"`
* 4. `"earpiece"`
*
* * audioTypeOptions - An {@link AndroidAudioTypeOptions} object which provides the
* audio options to use on Android.
*
* See {@link AndroidAudioTypePresets} for pre-configured values.
*
* ----
* iOS
*
* * defaultOutput - The default preferred output to use when a wired headset or bluetooth output is unavailable.
*
* By default, this is set to `"speaker"`
*/
export type AudioConfiguration = {
android?: {
preferredOutputList?: ('speaker' | 'earpiece' | 'headset' | 'bluetooth')[];
audioTypeOptions: AndroidAudioTypeOptions;
};
ios?: {
defaultOutput?: 'speaker' | 'earpiece';
};
};
export type AndroidAudioTypeOptions = {
/**
* Whether LiveKit should handle managing the audio focus or not.
*
* Defaults to true.
*/
manageAudioFocus?: boolean;
/**
* Corresponds to {@link https://developer.android.com/reference/android/media/AudioManager#setMode(int)}
*
* Defaults to 'inCommunication'.
*/
audioMode?:
| 'normal'
| 'callScreening'
| 'inCall'
| 'inCommunication'
| 'ringtone';
/**
* Corresponds to the duration hint when requesting audio focus.
*
* Defaults to 'gain'.
*
* See also {@link https://developer.android.com/reference/android/media/AudioManager#AUDIOFOCUS_GAIN}
*/
audioFocusMode?:
| 'gain'
| 'gainTransient'
| 'gainTransientExclusive'
| 'gainTransientMayDuck';
/**
* Corresponds to Android's AudioAttributes usage type.
*
* Defaults to 'voiceCommunication'.
*
* See also {@link https://developer.android.com/reference/android/media/AudioAttributes}
*/
audioAttributesUsageType?:
| 'alarm'
| 'assistanceAccessibility'
| 'assistanceNavigationGuidance'
| 'assistanceSonification'
| 'assistant'
| 'game'
| 'media'
| 'notification'
| 'notificationEvent'
| 'notificationRingtone'
| 'unknown'
| 'voiceCommunication'
| 'voiceCommunicationSignalling';
/**
* Corresponds to Android's AndroidAttributes content type.
*
* Defaults to 'speech'.
*
* See also {@link https://developer.android.com/reference/android/media/AudioAttributes}
*/
audioAttributesContentType?:
| 'movie'
| 'music'
| 'sonification'
| 'speech'
| 'unknown';
/**
* Corresponds to the stream type when requesting audio focus. Used on pre-O devices.
*
* Defaults to 'voiceCall'
*
* See also {@link https://developer.android.com/reference/android/media/AudioManager#STREAM_VOICE_CALL}
*/
audioStreamType?:
| 'accessibility'
| 'alarm'
| 'dtmf'
| 'music'
| 'notification'
| 'ring'
| 'system'
| 'voiceCall';
/**
* On certain Android devices, audio routing does not function properly and
* bluetooth microphones will not work unless audio mode is set to
* `inCommunication` or `inCall`. Audio routing is turned off those cases.
*
* If this set to true, will attempt to do audio routing regardless of audio mode.
*
* Defaults to false.
*/
forceHandleAudioRouting?: boolean;
};
export const AndroidAudioTypePresets: {
/**
* A pre-configured AndroidAudioConfiguration for voice communication.
*/
communication: AndroidAudioTypeOptions;
/**
* A pre-configured AndroidAudioConfiguration for media playback.
*/
media: AndroidAudioTypeOptions;
} = {
communication: {
manageAudioFocus: true,
audioMode: 'inCommunication',
audioFocusMode: 'gain',
audioStreamType: 'voiceCall',
audioAttributesUsageType: 'voiceCommunication',
audioAttributesContentType: 'speech',
},
media: {
manageAudioFocus: true,
audioMode: 'normal',
audioFocusMode: 'gain',
audioStreamType: 'music',
audioAttributesUsageType: 'media',
audioAttributesContentType: 'unknown',
},
} as const;
export type AppleAudioMode =
| 'default'
| 'gameChat'
| 'measurement'
| 'moviePlayback'
| 'spokenAudio'
| 'videoChat'
| 'videoRecording'
| 'voiceChat'
| 'voicePrompt';
export type AppleAudioCategory =
| 'soloAmbient'
| 'playback'
| 'record'
| 'playAndRecord'
| 'multiRoute';
export type AppleAudioCategoryOption =
| 'mixWithOthers'
| 'duckOthers'
| 'interruptSpokenAudioAndMixWithOthers'
| 'allowBluetooth'
| 'allowBluetoothA2DP'
| 'allowAirPlay'
| 'defaultToSpeaker';
export type AppleAudioConfiguration = {
audioCategory?: AppleAudioCategory;
audioCategoryOptions?: AppleAudioCategoryOption[];
audioMode?: AppleAudioMode;
};
export default class AudioSession {
/**
* Applies the provided audio configuration to the underlying AudioSession.
*
* Must be called prior to connecting to a Room for the configuration to apply correctly.
*
* See also useIOSAudioManagement for automatic configuration of iOS audio options.
*/
static configureAudio = async (config: AudioConfiguration) => {
await LiveKitModule.configureAudio(config);
};
/**
* Starts an AudioSession.
*/
static startAudioSession = async () => {
await LiveKitModule.startAudioSession();
};
/**
* Stops the existing AudioSession.
*/
static stopAudioSession = async () => {
await LiveKitModule.stopAudioSession();
};
/**
* Set default audio track volume when new tracks are subscribed.
* Does **not** affect any existing tracks.
*
* @param volume A number between 0.0 and 1.0, where 0.0 represents 0% volume and
* 1.0 represents full volume.
*/
static setDefaultRemoteAudioTrackVolume = async (volume: number) => {
await LiveKitModule.setDefaultAudioTrackVolume(volume);
};
/**
* Gets the available audio outputs for use with {@link selectAudioOutput}.
*
* {@link startAudioSession} must be called prior to using this method.
*
* For Android, will return if available:
* * "speaker"
* * "earpiece"
* * "headset"
* * "bluetooth"
*
* ----
*
* For iOS, due to OS limitations, the only available types are:
* * "default" - Use default iOS audio routing
* * "force_speaker" - Force audio output through speaker
*
* See also {@link showAudioRoutePicker} to display a route picker that
* can choose between other audio devices (i.e. headset/bluetooth/airplay),
* or use a library like `react-native-avroutepicker` for a native platform
* control.
*
* @returns the available audio output types
*/
static getAudioOutputs = async (): Promise<string[]> => {
if (Platform.OS === 'ios') {
return ['default', 'force_speaker'];
} else if (Platform.OS === 'android') {
return (await LiveKitModule.getAudioOutputs()) as string[];
} else {
return [];
}
};
/**
* Select the provided audio output if available.
*
* {@link startAudioSession} must be called prior to using this method.
*
* @param deviceId A deviceId retrieved from {@link getAudioOutputs}
*/
static selectAudioOutput = async (deviceId: string) => {
await LiveKitModule.selectAudioOutput(deviceId);
};
/**
* iOS only, requires iOS 11+.
*
* Displays an AVRoutePickerView for the user to choose their audio output.
*/
static showAudioRoutePicker = async () => {
if (Platform.OS === 'ios') {
await LiveKitModule.showAudioRoutePicker();
}
};
/**
* Directly change the AVAudioSession category/mode.
*
* @param config The configuration to use. Null values will be omitted and the
* existing values will be unchanged.
*/
static setAppleAudioConfiguration = async (
config: AppleAudioConfiguration
) => {
if (Platform.OS === 'ios') {
await LiveKitModule.setAppleAudioConfiguration(config);
}
};
}