Android
[Android] AudioTrack 재생
금님은님아부지
2021. 10. 18. 11:40
728x90
Android 앱에서 음원 및 Raw Data 재생 시 AudioTrack 과 MediaPlayer 를 이용해서 재생할 수 있다. AudioTrack 과 MediaPlayer 는 각 용도에 맞게 선택하여 사용한다.
MediaPlayer
- 음악과 같이 백그라운드 재생을 할 경우
- STATIC 한 시간이 아닌 음원을 재생할 경우
AudioTrack
- AudioChannel Config 설정을 원할 경우
- PCM Raw Data Buffer 를 바로 재생할 경우
MediaPlayer
- Raw 파일의 Wav 음원을 재생하는 경우
- AudioAttribute 설정(안드로이드 O이상 지원)이 필요없을 때에는 MediaPlayer 를 바로 Create 하고 음원을 재생한다.
val mediaPlayer = MediaPlayer.create(context, resId)
mediaPlayer.start()
-
- AudioAttribute 설정이 필요한 경우 RAW 폴더의 res 음원 파일을 uri 로 변환하여 재생한다.
val mediaPlayer = MediaPlayer()
val ttsUri = Uri.parse("android.resource://" + context.packageName + "/" + resId)
mediaPlayer.let { player ->
player.setOnPreparedListener {
Timber.tag(logTag).d("playMediaPlayer - prepare complete")
player.start()
}
player.setOnCompletionListener {
Timber.tag(logTag).d("playMediaPlayer - complete, currentType=$currentType")
// 재생 완료 후 동작 처리...
}
player.reset()
player.setDataSource(context, uri)
/**
* 각 음원 Stream 에 맞는 타입을 설정한다.
*/
player.setAudioAttributes(AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ASSISTANT).setContentType(AudioAttributes.CONTENT_TYPE_SPEECH).build())
player.prepareAsync()
}
2. data 영역에 임시로 저장한 wav 파일을 재생하는 경우
val fis = context.openFileInput(FILE_NAME)
val mediaPlayer = MediaPlayer()
mediaPlayer.let { player ->
player.setOnPreparedListener {
Timber.tag(logTag).d("playMediaPlayer - prepare complete")
player.start()
}
player.setOnCompletionListener {
Timber.tag(logTag).d("playMediaPlayer - complete")
// 재생 완료 후 동작 처리...
}
player.reset()
player.setDataSource(fis.fd)
/**
* 각 음원 Stream 에 맞는 타입을 설정한다.
*/
player.setAudioAttributes(AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ASSISTANT).setContentType(AudioAttributes.CONTENT_TYPE_SPEECH).build())
player.prepareAsync()
}
3. 서버에서 전달되는 음원 url 를 재생하는 경우
mediaPlayer.apply {
setOnPreparedListener { player ->
player.start()
}
setOnCompletionListener {
// 재새 완료 후 동작 처리...
}
setDataSource(url)
prepareAsync()
}
AudioTrack
PCM ByteArray Data 로 변환하여 AudioTrack 에 Writing 후 재생한다.
val minBufferSize = AudioTrack.getMinBufferSize(
44100, // 각 음원에 맞는 SampleRate 설정...
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT
)
val audioTrack = AudioTrack(
AudioAttributes.Builder()
/**
* 각 음원 Stream 에 맞는 타입을 설정한다.
*/
.setUsage(AudioAttributes.USAGE_ASSISTANT)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build(),
AudioFormat.Builder()
.setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
.setSampleRate(44100)
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.build(),
minBufferSize,
AudioTrack.MODE_STREAM,
AudioManager.AUDIO_SESSION_ID_GENERATE
)
audioTrack.let { track ->
track.play()
var i1: Int
val beep = ByteArray(minBufferSize)
val inputStream: InputStream = context.openFileInput(FILE_NAME)
if (track.state != AudioTrack.STATE_UNINITIALIZED) {
if (track.playState != AudioTrack.PLAYSTATE_STOPPED) {
try {
while (inputStream.read(beep).also { i1 = it } != -1) {
val written = track.write(beep, 0, i1)
if (written <= AudioTrack.SUCCESS) {
break
}
}
// Track 재생 완료 후 처리....
} catch (e: IOException) {
Timber.tag(logTag).e("InterruptedException ${e.message}")
}
}
}
}
728x90