반응형

앱개발을 하다보면 사운드관련 처리를 하게되고, 사운드 처리를 하다보면 단말 내 타 앱과 간섭이 발생하게 된다.


뭔가 그럴듯하게 적으려하다보니 어렵게 설명이 되었는데..... 쉽게 설명하면 간단하다.

내가 만든앱에서 가령 '이 편지는 영국에서 시작되어....'라는 음성이 발성되어야한다고하면 

해당 음성이 발성중일때 다른 앱에서 동일 크기에 음성이 발성된다면 개발자는 사용자에게 행운의 편지를 정상적으로 배달하는데 어려움이 발생할것이다.....


이번 포스트는 개발자가 사용자에게 행운의 편지를 성공적으로 배송하기위한 방법!

AudioFocus처리 방법에 대해 정리해보고자 한다.


벌써부터 두근거렸다면 박수감사합니다.




먼저, AudioManager 옵션에 대해 알아보자.


스트림 타입
설명
STREAM_ALARM알람을 의한 오디오 스트림The audio stream for alarms
STREAM_DTMFDTMF 톤을 위한 오디오 스트림
STREAM_MUSIC"미디어"(음악, 팟캐스트, 비디오) 재생을 오디오 스트림
STREAM_NOTIFICATION알림을 위한 오디오 스트림
STREAM_RING폰 링을 위한 오디오 스트림
STREAM_SYSTEM시스템 사운드를 위한 오디오 스트림




위에서 알아본 옵션중 이번 포스트에서는 미디어 관련 옵션을 이용해 처리하였다.



그럼 이제 옵션도 확인했으니, AudioFocus 처리에 대해 진행해보자.

AudioFocus처리를 위해서는 우선적으로 AudioManager 내 'OnAudioFocusChangeListener'를 이용한 Listener 구현이 필요하다.

OnAudioFocusChangeListener는 이름 그대로 오디오 포커스 변환 이벤트가 감지되었을때 해당 리스너를 통해 처리가능하다.

해당 리스너를 통해 넘어오는 케이스에대한 상세정보는 다음과 같다.


획득
상실
AUDIOFOCUS_GAINAUDIOFOCUS_LOSS
AUDIOFOCUS_GAIN_TRANSIENTAUDIOFOCUS_LOSS_TRANSIENT
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCKAUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK



포커스 변경 종류
적절한 행동
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK볼륨을 줄이거나 재생을 일시정지한다. AUDIOFOCUS_LOSS_TRANSIENT의 상태를 저장한다. 애셋을 해제하면 안된다.
AUDIOFOCUS_LOSS_TRANSIENT재생을 일시정지하고 상실이 일시적이란 것의 상태를 유지한다. AUDIOFOCUS_GAIN  이벤트가 나타나면 적절히 재생을 재개할 수 있다. 에셋을 해제하면 안된다.
AUDIOFOCUS_LOSS재생을 정지한다. 에셋을 해제한다.
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK해당 플래그로 포커스 확보 시 포커스가 확보된 앱을 제외한 현재 미디어 재생중인 앱의 볼륨이 줄어든다. - 기존 재생중인 미디어의 볼륨만 줄이고 싶을 때 사용
AUDIOFOCUS_GAIN_TRANSIENT짧은 시간 포커스 확보 필요시 사용
AUDIOFOCUS_GAIN상실 이벤트 후 획득 이벤트. 애플리케이션에 의해 설정된 다른 상태가 없다면 재생을 재개한다. 예를 들어 상실 이베트 이전에 사용자가 명시적으로 일시 정지한 경우.



음.... 이름만 보면 명확하게 와닿지 않는다.

그래서 잠시 Google Developers 를 참조하면 다음과 같이 설명하고 있다.


영속적인 오디오 포커스를 처리하고싶다면 'AUDIOFOCUS_GAIN'을 쓰세요. 

단지 45초 미만의 오디오 포커스만을 원한다면 'AUDIOFOCUS_GAIN_TRASIENT'를 써보세요.

15초 이내로 오디오 포커스를 갖고오면서 배경음악을 잠시 줄이고 싶다면 'AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK'을 써보세요. 대신 15초 이상 오디오 포커스를 잡아선 안됩니다.


필자는 센치한 밤이라 그런지 느낌이 오는듯한다. 마찬가지로 지금 이 포스트를 보고있는 여러분도 같은 느낌을 받길바라며 AudioFocus처리를 위한 리스너를 구현해보자.


/**
* AudioFocus 구현
*/
private AudioManager.OnAudioFocusChangeListener audioFocusChangeLisetner =
new AudioManager.OnAudioFocusChangeListener() {

@Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
// 재생중인 meida 볼륨 처리
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC),
AudioManager.FLAG_PLAY_SOUND);
break;
case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
// 재생중인 meida 볼륨 처리
break;
case AudioManager.AUDIOFOCUS_LOSS:
// 재생중인 meida 일시정지 처리
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
// 재생중인 meida 일시정지 처리
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// 재생중인 meida mute 처리 또는 최소화
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, AudioManager.FLAG_PLAY_SOUND);
break;
}
}
};


위에서 구현한 audioFocusChangeListener를 이용하여 Focus를 요청해보자.

Focus를 요청은 의외로 간단하다.

AudioManager 내 'requestAudioFocus'를 호출하여 요청한다.


AudioManager audioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
audioManager.requestAudioFocus(audioFocusChangeListner, // audioFocus 변화를 처리할 리스너
AudioManager.STREAM_MUSIC, // 포커스 요청 Audio 타입
AudioManager.AUDIOFOCUS_GAIN); // AudioFocus 요청 옵션



요청한 Focus가 정상적으로 처리되었다면, 앞서 구현한 audioFocusChangeListener를 통해 해당 이벤트가 정상전달되며, 개발자는 상황에 맞는 처리를 진행하면 된다.


AudioFocus 해제의 경우 'abandonAudioFocus' 호출을 통해 쉽게 해제할 수 있다.

AudioManager audioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
audioManager.abandonAudioFocus(audioFocusChangeListner);



이상 기본적인 AudioFocus 처리에 대한 포스팅을 마무리한다.


반응형

+ Recent posts