Skip to content

Commit bfbe09c

Browse files
authored
feat: handle changing output mode with AudioSession.configureAudio on android (#148)
* feat: allow changing of audio attributes * feat: handle changing output mode with AudioSession.configureAudio on android
1 parent adb20c7 commit bfbe09c

9 files changed

Lines changed: 71 additions & 10 deletions

File tree

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ dependencies {
130130
api 'com.facebook.react:react-native:+'
131131
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
132132
api 'com.github.davidliu:audioswitch:89582c47c9a04c62f90aa5e57251af4800a62c9a'
133-
api 'io.github.webrtc-sdk:android:114.5735.05'
133+
api 'io.github.webrtc-sdk:android:114.5735.11'
134134
implementation project(':livekit_react-native-webrtc')
135135
implementation "androidx.annotation:annotation:1.4.0"
136136
}

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@ import org.webrtc.audio.JavaAudioDeviceModule
1111

1212
object LiveKitReactNative {
1313

14+
private lateinit var adm: JavaAudioDeviceModule
15+
16+
val audioDeviceModule: JavaAudioDeviceModule
17+
get() {
18+
if(!::adm.isInitialized) {
19+
throw IllegalStateException("Audio device module is not initialized! Did you remember to call LiveKitReactNative.setup in your Application.onCreate?")
20+
}
21+
22+
return adm
23+
}
24+
1425
/**
1526
* Initializes components required for LiveKit to work on Android.
1627
*
@@ -26,10 +37,12 @@ object LiveKitReactNative {
2637

2738
val useHardwareAudioProcessing = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
2839

29-
options.audioDeviceModule = JavaAudioDeviceModule.builder(context)
40+
adm = JavaAudioDeviceModule.builder(context)
3041
.setUseHardwareAcousticEchoCanceler(useHardwareAudioProcessing)
3142
.setUseHardwareNoiseSuppressor(useHardwareAudioProcessing)
3243
.setAudioAttributes(audioType.audioAttributes)
3344
.createAudioDeviceModule()
45+
46+
options.audioDeviceModule = adm
3447
}
3548
}

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

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

33
import android.annotation.SuppressLint
44
import android.content.Context
5+
import android.media.AudioAttributes
56
import com.facebook.react.bridge.*
67
import com.livekit.reactnative.audio.AudioDeviceKind
78
import com.livekit.reactnative.audio.AudioManagerUtils
89
import com.livekit.reactnative.audio.AudioSwitchManager
10+
import org.webrtc.audio.WebRtcAudioTrackHelper
911

1012

1113
class LivekitReactNativeModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
@@ -32,6 +34,10 @@ class LivekitReactNativeModule(reactContext: ReactApplicationContext) : ReactCon
3234
if (androidConfig.hasKey("audioTypeOptions")) {
3335
val audioTypeOptions = androidConfig.getMap("audioTypeOptions") ?: return
3436

37+
val adm = LiveKitReactNative.audioDeviceModule
38+
val oldAudioAttributes = WebRtcAudioTrackHelper.getAudioOutputAttributes(adm)
39+
val attributesBuilder = AudioAttributes.Builder(oldAudioAttributes)
40+
3541
if (audioTypeOptions.hasKey("manageAudioFocus")) {
3642
val manageFocus = audioTypeOptions.getBoolean("manageAudioFocus")
3743
audioManager.setManageAudioFocus(manageFocus)
@@ -68,6 +74,7 @@ class LivekitReactNativeModule(reactContext: ReactApplicationContext) : ReactCon
6874
val usageType = AudioManagerUtils.audioAttributesUsageTypeFromString(usageTypeString)
6975
if (usageType != null) {
7076
audioManager.setAudioAttributesUsageType(usageType)
77+
attributesBuilder.setUsage(usageType)
7178
}
7279
}
7380
}
@@ -77,6 +84,7 @@ class LivekitReactNativeModule(reactContext: ReactApplicationContext) : ReactCon
7784
val contentType = AudioManagerUtils.audioAttributesContentTypeFromString(contentTypeString)
7885
if (contentType != null) {
7986
audioManager.setAudioAttributesContentType(contentType)
87+
attributesBuilder.setContentType(contentType)
8088
}
8189
}
8290
}
@@ -85,6 +93,8 @@ class LivekitReactNativeModule(reactContext: ReactApplicationContext) : ReactCon
8593
val force = audioTypeOptions.getBoolean("forceHandleAudioRouting")
8694
audioManager.setForceHandleAudioRouting(force)
8795
}
96+
97+
WebRtcAudioTrackHelper.setAudioOutputAttributes(adm, attributesBuilder.build())
8898
}
8999
}
90100

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.webrtc.audio
2+
3+
import android.media.AudioAttributes
4+
5+
object WebRtcAudioTrackHelper {
6+
7+
fun getAudioOutputAttributes(adm: JavaAudioDeviceModule): AudioAttributes {
8+
return adm.audioOutput.audioAttributes ?: AudioAttributes.Builder()
9+
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
10+
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
11+
.build()
12+
}
13+
14+
fun setAudioOutputAttributes(
15+
adm: JavaAudioDeviceModule,
16+
audioAttributes: AudioAttributes,
17+
) {
18+
adm.audioOutput.audioAttributes = audioAttributes
19+
}
20+
}

example/ios/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ PODS:
1818
- livekit-react-native (2.1.1):
1919
- livekit-react-native-webrtc
2020
- React-Core
21-
- livekit-react-native-webrtc (114.1.2):
21+
- livekit-react-native-webrtc (114.1.3):
2222
- React-Core
2323
- WebRTC-SDK (~> 114.5735.10)
2424
- RCT-Folly (2021.07.22.00):
@@ -514,7 +514,7 @@ SPEC CHECKSUMS:
514514
hermes-engine: 8b9dc37355d2e12879267382f4256afd356349a1
515515
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
516516
livekit-react-native: 34f87e46b8105cd2b490765d9e6d23d16b967d50
517-
livekit-react-native-webrtc: 6f7be1d60fa9e8cc9e54570d2a8aedcb536dddeb
517+
livekit-react-native-webrtc: b43424d9bd1fa0e5d52478d2daf2af2402bdd82f
518518
RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1
519519
RCTRequired: c20235648eeb64a874f55459ceae6b081956318d
520520
RCTTypeSafety: ca004f1fe0b76f7936f7fe7dfd761a4386cf72f5

example/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"start": "react-native start"
1010
},
1111
"dependencies": {
12-
"@livekit/react-native-webrtc": "^114.1.2",
12+
"@livekit/react-native-webrtc": "^114.1.3",
1313
"@react-native-async-storage/async-storage": "^1.17.10",
1414
"@react-navigation/native": "^6.0.8",
1515
"@react-navigation/native-stack": "^6.5.0",

example/src/RoomPage.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import {
2727
useTracks,
2828
TrackReferenceOrPlaceholder,
2929
ReceivedDataMessage,
30+
AndroidAudioTypePresets,
31+
AndroidAudioTypeOptions,
3032
} from '@livekit/react-native';
3133
import { Platform } from 'react-native';
3234
// @ts-ignore
@@ -39,6 +41,7 @@ import Toast from 'react-native-toast-message';
3941

4042
import { Track } from 'livekit-client';
4143

44+
let audioType = false;
4245
export const RoomPage = ({
4346
navigation,
4447
route,
@@ -47,6 +50,21 @@ export const RoomPage = ({
4750

4851
useEffect(() => {
4952
let start = async () => {
53+
let preset: AndroidAudioTypeOptions;
54+
if (audioType) {
55+
console.log('using communication type');
56+
preset = AndroidAudioTypePresets.communication;
57+
} else {
58+
console.log('using media type');
59+
preset = AndroidAudioTypePresets.media;
60+
}
61+
62+
audioType = !audioType;
63+
AudioSession.configureAudio({
64+
android: {
65+
audioTypeOptions: preset,
66+
},
67+
});
5068
await AudioSession.startAudioSession();
5169
};
5270

example/yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,10 +1275,10 @@
12751275
"@jridgewell/resolve-uri" "3.1.0"
12761276
"@jridgewell/sourcemap-codec" "1.4.14"
12771277

1278-
"@livekit/react-native-webrtc@^114.1.2":
1279-
version "114.1.2"
1280-
resolved "https://registry.yarnpkg.com/@livekit/react-native-webrtc/-/react-native-webrtc-114.1.2.tgz#dc4b40bafee4fb03720aee37447ce138507bb6da"
1281-
integrity sha512-TAPf5wKj7yDFUfYkEHXkA4md1tNby7JAqpKPIoMXmYyoHQ+TiJMkLQi5/H2NBVkArHiY8GU9NUpEk5Gdaf7W6Q==
1278+
"@livekit/react-native-webrtc@^114.1.3":
1279+
version "114.1.3"
1280+
resolved "https://registry.yarnpkg.com/@livekit/react-native-webrtc/-/react-native-webrtc-114.1.3.tgz#87e4b0482d361ed9f785fedebccb55efe23188d9"
1281+
integrity sha512-ayg5ZWyHHJCwchLbxeFxD++t2IZMs9xROQGSKT9Fs9O8q1WjMIaC/5LASFSOZUAHRmOfy7CX1k+/IEvB7Bu54g==
12821282
dependencies:
12831283
base64-js "1.5.1"
12841284
debug "4.3.4"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
"typescript": "4.8.4"
8181
},
8282
"peerDependencies": {
83-
"@livekit/react-native-webrtc": "^114.1.2",
83+
"@livekit/react-native-webrtc": "^114.1.3",
8484
"react": "*",
8585
"react-native": "*"
8686
},

0 commit comments

Comments
 (0)