오디오 경로 제어
Android에서 오디오 경로 제어는 스피커폰, 수화기, Bluetooth 기기 또는 유선 헤드셋 중 어디로 오디오를 출력할지 결정합니다. PlanetKitAudioSwitch를 사용하면 통화 중 활성 오디오 경로를 제어할 수 있습니다.
| 지원 통화 유형 | 최소 SDK 버전 |
|---|---|
| 1대1 통화, 그룹 통화(컨퍼런스) | PlanetKit 3.7 |
오디오 경로 값
PlanetKit은 PlanetKitAudioRoute로 현재 경로를 나타냅니다.
| 값 | 설명 |
|---|---|
UNDEFINED | 경로가 정의되지 않았거나 아직 결정되지 않았습니다. |
SPEAKER | 휴대전화 스피커폰 |
HANDSET | 휴대전화 수화기 |
BLUETOOTH | Bluetooth 오디오 기기 |
PLUGGED | 유선 헤드셋 |
오디오 경로 제어 여부 설정
기본적으로 PlanetKit이 통화의 오디오 경로를 관리합니다. 관리 여부를 설정하려면 AudioDefaultAttributes.Builder.controlAudioRoute()를 설정한 다음, PlanetKit을 초기화할 때 해당 속성을 전달하세요.
val audioAttributes = AudioDefaultAttributes.Builder()
.controlAudioRoute(true) // Default: true
.build()
val configurationBuilder = PlanetKit.PlanetKitConfiguration.Builder(context)
// Configure the other required PlanetKit settings on configurationBuilder.
configurationBuilder.setAudioDefaultAttributes(audioAttributes)
val configuration = configurationBuilder.build()
// Pass configuration to PlanetKit.initialize(configuration, listener).
controlAudioRoute(false)로 설정하면 PlanetKit이 통화의 오디오 경로를 관리하지 않습니다. 이 경우 setAudioRoute() 및 setSpeakerOn()을 통한 경로 선택 요청은 false를 반환합니다.
통화 중 오디오 경로를 확인하거나 변경하려면 활성 세션에서 PlanetKitAudioSwitch를 가져오세요.
// 1-to-1 call
val audioSwitch = call.getAudioSwitch()
// Group call
val audioSwitch = conference.getAudioSwitch()
PlanetKitAudioSwitch의 수명은 이를 생성한 PlanetKitCall 또는 PlanetKitConference와 같습니다.
현재 경로 및 사용 가능한 경로 확인
selectedAudioRoute로 현재 선택된 경로를 확인하고, availableAudioRoutes로 현재 사용 가능한 경로를 확인하세요.
현재 선택된 경로만 필요하다면 PlanetKitCall.audioRoute 또는 PlanetKitConference.audioRoute를 사용하세요. 두 속성은 PlanetKitAudioSwitch.selectedAudioRoute와 같은 값을 반환합니다. 사용 가능한 경로를 함께 확인하거나 경로 변경을 요청하려면 PlanetKitAudioSwitch를 사용하세요.
// Current active route
val current = audioSwitch.selectedAudioRoute
Log.d(TAG, "Current route: $current")
// Available routes at this moment
val available = audioSwitch.availableAudioRoutes
Log.d(TAG, "Available routes: $available")
특정 경로로 전환
활성 통화의 PlanetKitAudioSwitch에서 setAudioRoute()를 호출하세요. 요청할 경로는 availableAudioRoutes에 포함되어 있어야 합니다. 반환값은 PlanetKit이 요청을 접수하고 전환을 시도했는지를 나타낼 뿐, 경로가 실제로 바뀌었음을 보장하지 않습니다. 호출 후 selectedAudioRoute를 읽거나 경로 변경 리스너로 PlanetKit이 현재 선택한 경로를 확인하세요. 이 값은 PlanetKit이 선택한 경로이며 OS가 적용을 확정한 값은 아닙니다(예: Bluetooth SCO 연결은 수 초가 걸리거나 실패할 수 있습니다). 이후 해당 경로를 사용할 수 없다고 판단되면 PlanetKit이 경로 변경 이벤트를 다시 전달할 수 있습니다.
val audioSwitch = call.getAudioSwitch()
// Request Bluetooth if available
if (audioSwitch.availableAudioRoutes.contains(PlanetKitAudioRoute.BLUETOOTH)) {
audioSwitch.setAudioRoute(PlanetKitAudioRoute.BLUETOOTH)
val selectedByPlanetKit = audioSwitch.selectedAudioRoute == PlanetKitAudioRoute.BLUETOOTH
Log.d(TAG, "Bluetooth selected by PlanetKit: $selectedByPlanetKit")
}
setAudioRoute()의 반환값의 의미는 다음과 같습니다.
true: PlanetKit이 요청을 접수하고 전환을 시도했습니다. OS가 전환을 거부하는 등의 이유로 아직 경로가 바뀌지 않았을 수 있습니다.false: 요청한 경로가availableAudioRoutes에 없거나, 오디오 경로 제어가 비활성화되었거나, 요청한 경로가 이미 현재 경로입니다.
Android 12 이상에서는 앱에 Bluetooth 연결 권한이 없더라도 OS에서 경로를 노출하면 Bluetooth 경로가 availableAudioRoutes에 나타날 수 있습니다. 이 경우 PlanetKit은 해당 경로를 SDK 오디오 경로로 선택하지 않습니다. Bluetooth를 선택 가능한 경로로 제공하기 전에 필요한 Bluetooth 권한을 요청하세요. 권한 없이 Bluetooth 경로를 요청해도 setAudioRoute()는 true를 반환하므로, 반환값 대신 selectedAudioRoute로 PlanetKit이 선택한 경로를 확인하세요.
스피커폰 전환
setSpeakerOn()은 스피커폰과 스피커폰 외에 우선순위가 가장 높은 경로 사이를 전환하는 편의 메서드입니다.
// Enable speakerphone
audioSwitch.setSpeakerOn(true)
// Disable speakerphone — falls back to highest-priority available route
audioSwitch.setSpeakerOn(false)
// Query current state
val isSpeakerOn = audioSwitch.isSpeakerOn
경로 우선순위 구성
PlanetKit이 경로를 자동으로 선택해야 할 때는 우선순위 목록을 사용합니다. setPreferredAudioRoutesAtDisconnect()로 목록을 구성하세요.
이 우선순위 목록은 외부 기기 연결이 해제된 경우, 이미 선택된 외부 경로 없이 오디오가 시작되는 경우, 스피커폰을 끄는 경우, 외부 경로 없이 영상 통화가 활성화되는 경우에 사용됩니다. 새 외부 기기가 연결되었을 때의 동작은 목록 순서에 따라 결정되지 않습니다. 이때 PlanetKit은 목록 순서와 관계없이 새 유선 또는 Bluetooth 경로를 요청합니다.
우선순위 목록을 구성하지 않으면 PlanetKit은 다음 기본값을 사용합니다.
| 통화 유형 | 우선순위 |
|---|---|
| 음성 통화 | BLUETOOTH → PLUGGED → HANDSET → SPEAKER |
| 영상 통화 | BLUETOOTH → PLUGGED → SPEAKER → HANDSET |
목록에는 선택 가능한 PlanetKitAudioRoute 값 네 가지를 각각 한 번씩, 원하는 우선순위 순서로 모두 포함해야 합니다.
음성 통화와 영상 통화의 우선순위 목록은 별도로 구성하세요. 영상 통화 우선순위 목록에는 whenOnVideoCall = true를 사용합니다. 다음 예시에서는 PlanetKit이 경로를 자동으로 선택해야 할 때 유선 헤드셋을 우선하도록 음성 통화 우선순위 목록을 구성합니다.
val audioSwitch = call.getAudioSwitch()
val audioCallPriority = listOf(
PlanetKitAudioRoute.PLUGGED,
PlanetKitAudioRoute.BLUETOOTH,
PlanetKitAudioRoute.HANDSET,
PlanetKitAudioRoute.SPEAKER
)
val success = audioSwitch.setPreferredAudioRoutesAtDisconnect(
whenOnVideoCall = false,
list = audioCallPriority
)
항목 수가 잘못되었거나 중복 항목이 있는 등 목록이 유효하지 않으면 setPreferredAudioRoutesAtDisconnect()는 false를 반환합니다.
자동 경로 변경
오디오 경로 제어가 활성화되면, 오디오가 시작될 때 이미 선택된 유선 또는 Bluetooth 경로를 PlanetKit이 유지합니다. 통화가 활성화될 때 두 경로가 모두 연결되어 있다면, Android 7 이상에서는 OS가 Bluetooth 경로를 선택한 경우에만 Bluetooth를 사용하고, 그렇지 않으면 유선 경로를 사용합니다. Android 6 이하에서는 Bluetooth를 사용합니다. 이 동작에는 필요한 Bluetooth 권한이 있어야 합니다.
영상 통화가 활성화되면 PlanetKit은 유선 또는 Bluetooth 경로를 유지합니다. 둘 다 해당하지 않으면 영상 통화 우선순위 목록에서 처음으로 사용 가능한 경로를 선택합니다. 영상 통화를 비활성화해도 경로가 자동으로 바뀌지는 않습니다.
경로 변경 및 사용 가능 경로 목록 변경 감지
선택된 오디오 경로의 변경과 사용 가능한 경로 목록의 업데이트를 받으려면 PlanetKitCall 또는 PlanetKitConference 인스턴스에 리스너를 등록하세요.
call.setOnAudioRouteChangeListener { newRoute ->
Log.d(TAG, "Audio route changed to: $newRoute")
// Update UI to reflect new route
}
// Also listen for changes to the available route list
call.setOnAudioRouteAvailableListChangeListener { availableRoutes ->
Log.d(TAG, "Available routes updated: $availableRoutes")
// Refresh route selection UI
}
// The same listener APIs are available on PlanetKitConference.
관련 API
오디오 경로 제어와 관련된 API는 다음과 같습니다.