Skip to content

Commit f34d817

Browse files
authored
feat: expose android audio and focus modes (#84)
1 parent f317e00 commit f34d817

6 files changed

Lines changed: 101 additions & 6 deletions

File tree

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ dependencies {
129129
// noinspection GradleDynamicVersion
130130
api 'com.facebook.react:react-native:+'
131131
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
132-
api 'com.github.davidliu:audioswitch:c498d866c57f1d88056d5e7e7a78d622e3b0c046'
132+
api 'com.github.davidliu:audioswitch:fb33b237aa50b3d1d2dea0e0695ecb7b38a98971'
133133
api 'io.github.webrtc-sdk:android:104.5112.10'
134134
implementation project(':livekit_react-native-webrtc')
135135
implementation "androidx.annotation:annotation:1.4.0"

android/src/main/java/com/livekit/reactnative/LivekitReactNativeModule.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.livekit.reactnative
22

33
import com.facebook.react.bridge.*
44
import com.livekit.reactnative.audio.AudioDeviceKind
5+
import com.livekit.reactnative.audio.AudioManagerUtils
56
import com.livekit.reactnative.audio.AudioSwitchManager
67

78

@@ -23,6 +24,19 @@ class LivekitReactNativeModule(reactContext: ReactApplicationContext) : ReactCon
2324
}
2425
audioManager.preferredDeviceList = preferredDeviceList
2526
}
27+
28+
androidConfig.getString("audioMode")?.let { audioModeString ->
29+
val audioMode = AudioManagerUtils.audioModeFromString(audioModeString)
30+
if (audioMode != null) {
31+
audioManager.setAudioMode(audioMode)
32+
}
33+
}
34+
androidConfig.getString("audioFocusMode")?.let { focusModeString ->
35+
val focusMode = AudioManagerUtils.focusModeFromString(focusModeString)
36+
if (focusMode != null) {
37+
audioManager.setFocusMode(focusMode)
38+
}
39+
}
2640
}
2741

2842
@ReactMethod
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.livekit.reactnative.audio
2+
3+
import android.media.AudioManager
4+
import android.util.Log
5+
6+
7+
object AudioManagerUtils {
8+
private const val TAG = "AudioManagerUtils"
9+
10+
fun audioModeFromString(audioModeString: String?): Int? {
11+
if (audioModeString == null) {
12+
return null
13+
}
14+
15+
var audioMode: Int? = null
16+
when (audioModeString) {
17+
"normal" -> audioMode = AudioManager.MODE_NORMAL
18+
"callScreening" -> audioMode = AudioManager.MODE_CALL_SCREENING
19+
"inCall" -> audioMode = AudioManager.MODE_IN_CALL
20+
"inCommunication" -> audioMode = AudioManager.MODE_IN_COMMUNICATION
21+
"ringtone" -> audioMode = AudioManager.MODE_RINGTONE
22+
else -> Log.w(TAG, "Unknown audio mode: $audioModeString")
23+
}
24+
25+
return audioMode
26+
}
27+
28+
fun focusModeFromString(focusModeString: String?): Int? {
29+
if (focusModeString == null) {
30+
return null
31+
}
32+
33+
var focusMode: Int? = null
34+
when (focusModeString) {
35+
"gain" -> focusMode = AudioManager.AUDIOFOCUS_GAIN
36+
"gainTransient" -> focusMode = AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
37+
"gainTransientExclusive" -> focusMode = AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE
38+
"gainTransientMayDuck" -> focusMode = AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
39+
else -> Log.w(TAG, "Unknown audio focus mode: $focusModeString")
40+
}
41+
42+
return focusMode
43+
}
44+
}

android/src/main/java/com/livekit/reactnative/audio/AudioSwitchManager.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,20 @@ public class AudioSwitchManager {
4343
@Nullable
4444
private AudioSwitch audioSwitch;
4545

46+
/**
47+
* The audio focus mode to use while started.
48+
*
49+
* Defaults to [AudioManager.AUDIOFOCUS_GAIN].
50+
*/
51+
private int focusMode = AudioManager.AUDIOFOCUS_GAIN;
52+
53+
/**
54+
* The audio mode to use while started.
55+
*
56+
* Defaults to [AudioManager.MODE_NORMAL].
57+
*/
58+
private int audioMode = AudioManager.MODE_NORMAL;
59+
4660
public AudioSwitchManager(@NonNull Context context) {
4761
this.context = context;
4862
this.audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
@@ -64,6 +78,8 @@ public void start() {
6478
audioFocusChangeListener,
6579
preferredDeviceList
6680
);
81+
audioSwitch.setFocusMode(focusMode);
82+
audioSwitch.setAudioMode(audioMode);
6783
audioSwitch.start(audioDeviceChangeListener);
6884
audioSwitch.activate();
6985
});
@@ -137,4 +153,12 @@ public void selectAudioOutput(@Nullable AudioDeviceKind kind) {
137153
selectAudioOutput(kind.audioDeviceClass);
138154
}
139155
}
156+
157+
public void setFocusMode(int focusMode) {
158+
this.focusMode = focusMode;
159+
}
160+
161+
public void setAudioMode(int audioMode) {
162+
this.audioMode = audioMode;
163+
}
140164
}

example/src/RoomPage.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ export const RoomPage = ({
6262
// If you wish to configure audio, uncomment the following:
6363
// await AudioSession.configureAudio({
6464
// android: {
65-
// preferredOutputList: ["earpiece"]
65+
// preferredOutputList: ["earpiece"],
66+
// audioMode: 'normal',
67+
// audioFocusMode: 'gain',
6668
// },
6769
// ios: {
6870
// defaultOutput: "earpiece"

src/audio/AudioSession.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,22 @@ const LivekitReactNative = NativeModules.LivekitReactNative
3939
* By default, this is set to `"speaker"`
4040
*/
4141
export type AudioConfiguration = {
42-
android: {
43-
preferredOutputList: ('speaker' | 'earpiece' | 'headset' | 'bluetooth')[];
42+
android?: {
43+
preferredOutputList?: ('speaker' | 'earpiece' | 'headset' | 'bluetooth')[];
44+
audioMode?:
45+
| 'normal'
46+
| 'callScreening'
47+
| 'inCall'
48+
| 'inCommunication'
49+
| 'ringtone';
50+
audioFocusMode?:
51+
| 'gain'
52+
| 'gainTransient'
53+
| 'gainTransientExclusive'
54+
| 'gainTransientMayDuck';
4455
};
45-
ios: {
46-
defaultOutput: 'speaker' | 'earpiece';
56+
ios?: {
57+
defaultOutput?: 'speaker' | 'earpiece';
4758
};
4859
};
4960

0 commit comments

Comments
 (0)