Audio Session

sanghee·2022년 5월 2일
0

🍀인턴 스터디

목록 보기
3/12

Audio Session

Audio Session은 앱, 운영체제, 그리고 오디오 하드웨어 간의 중개자 역할을 하며 오디오 환경을 정의하고 관리한다.

기본적인 설정은 다음과 같으며 목적에 따라 변경이 가능하다.

  • 재생은 가능하지만, 녹음은 불가능하다.
  • 시스템에서 무음으로 설정하면, 앱에서 재생중인 오디오는 역시 무음으로 설정된다.
  • 기기를 잠그면 오디오는 무음이 된다.
  • 앱이 오디오를 재생할 때 다른 배경 오디오를 무음으로 설정한다.



Category

  • Ambient: 주로 게임 및 생산성 앱에서 사용된다. 재생과 Mixing은 허용되지만 녹음은 불가능하다.
  • Solo Ambient(default): 주로 게임 및 생산성 앱에서 사용되면 재생만 가능하다.
  • Playback: 오디오 및 비디오 플레이어에 사용된다. 재생은 허용되나 Mixing은 옵셔널이다.
  • Record: 녹음 목적으로 사용되며 녹음만 허용된다.
  • Play and Record: 주로 VolP과 같은 음성 채팅 목적으로 사용된다. 재생과 녹음은 허용되나 Mixing은 옵셔널이다.
  • Audio Processing: 주로 오프라인 변환에 사용된다. 재생, 녹음, Mixing 모두 불가능하다.
  • Multi-Route: 외부 장치를 이용하는 A/V 앱 목적으로 사용된다. 재생과 녹음은 가능하다 Mixing은 불가능하다.



AudioSession 객체

AudioSession의 객체를 통해 설정한다.

AudioSession의 라이프사이클은 앱의 라이프사이클과 일치하므로, 일반적으로 앱이 실행될 때 한번 구성한다.

application didFinishLauncingWithOptions에서 작성하면 좋다.



🔇때에도 🎶하려면

AudioSession의 기본 카테고리는 Solo Ambient로 설정되어 있다.

만약 음소거 스위치가 활성화 되어 있어도 실행하고 싶다면 Playback으로 설정한다.

let audioSession = AVAudioSession.sharedInstance()
try? audioSession.setCategory(.playback)
try? audioSession.setActive(true, options: .notifyOthersOnDeactivation)



🔒때에도 🎶하려면

재생중에 기기가 잠금화면이 뜰 수 있다.

그때 오디오를 계속 재생하고 싶다면 다음과 같이 설정한다.

1. Info.plist 파일에서 Request background modes 프로퍼티를 찾거나 없으면 생성한다.
2. Item 0App plays audio or streams audio/video using AirPlay로 설정한다.



☎때에도 🎶하려면

오디오가 나오는 중에 통화가 발생한다면, 기본으로 서서히 Fade-out되다 멈춘다.

만약 사용자가 전화를 거절한 경우 다시 오디오를 재생하고 싶다면 다음과 같이 설정한다.

Notification을 등록한 후 해당 Notification을 이용해 처리한다.

NotificationCenter.default.addObserver(self, selector: #selector(handleAudioInterruption(notification:)), name: AVAudioSession.interruptionNotification, object: audioSession)

@objc func handleAudioInterruption(notification: Notification) {
    guard let info = notification.userInfo,
          let interruptionType = info[AVAudioSessionInterruptionTypeKey] as? AVAudioSession.InterruptionType,
          let interruptionOptions = info[AVAudioSessionInterruptionOptionKey] as? AVAudioSession.InterruptionOptions else { return }

    if interruptionType == .began {
        // 인터럽션이 시작된 경우 처리 코드
    }
    if interruptionOptions == .shouldResume {
        // 다시 재생하는 코드
    }
}



🔊🎧️🎤 재생장치가 변경됨

재생 장치가 내장 스피커에서 이어폰으로는 자연스럽게 변경된다.

사용자가 오디오를 듣던 중에 이어폰으로 듣고자 연결하는 것이기에 오디오가 이어지는 것이 자연스럽다.

하지만 이어폰을 듣던 중에 이어폰이 제거되면 어떻게 될까?

사용자가 일부로 이어폰을 제거한 것인지, 혹은 오디오를 듣던 중에 다른 요인으로 인해 제거된 것인지 알 수 없다.

이럴 경우, 이어폰이 제거되었다면 재생을 멈추도록 설정할 수 있다.

  • oldDeviceUnavailable: 이전의 오디오 출력 경로가 불가능하다는 것을 나타내는 값이다.
NotificationCenter.default.addObserver(self, selector: #selector(handleAudioRouteChange(notification:)), name: AVAudioSession.routeChangeNotification, object: audioSession)

@objc func handleAudioRouteChange(notification: Notification) {
    guard let info = notification.userInfo,
          let reason = info[AVAudioSessionRouteChangeReasonKey] as? AVAudioSession.RouteChangeReason,
          let prevRoute = info[AVAudioSessionRouteChangePreviousRouteKey] as? AVAudioSessionRouteDescription else { return }

    if reason == .oldDeviceUnavailable {
        let prevOutput = prevRoute.outputs[0]
        let portType = prevOutput.portType

        if portType == .headphones {
            // 재생을 멈추는 코드
        }
    }
}



정리

오디오를 재생했을 때 다양한 상황들이 발생할 수 있다는 것을 알게 되었다.

잠금화면이 뜨거나, 통화 등의 인터럽트가 발생하거나 이어폰이 제거되는 등 일어날 수 있는 사건들을 생각하고 처리해야 겠다.



참고문서

AVAudioSession 공식문서

AudioSession 관련 블로그

profile
👩‍💻

0개의 댓글