wanna be dev 🧑‍💻

Cool 하고 Sick한 개발자가 되고 싶은 uzun입니다

A.K.A. Kick-snare, hyjhyj0901, h_uz99 solvedac-logo

Android/Challenge

패스트캠퍼스 챌린지 46일차

Kick_snare 2022. 3. 10. 21:26
728x90

46일차

30개 프로젝트로 배우는 Android 앱 개발 with Kotlin 초격차 패키지 Online

강의 목표


  • 프로젝트를 따라해보며 앱개발에 필요한 기술을 학습할 수 있습니다.
  • 프로젝트를 따라해보며 앱개발에 필요한 기술을 학습할 수 있습니다.
  • 앱 개발시 원하는 기능을 구현하기 위해 어떤 기술이 필요한 지 알 수 있습니다.
  • 디자인 아키텍처 패턴, 비동기 처리 등 효율적인 앱 개발 방법을 익힐 수 있습니다.

목차 02 Basic - Ch07. 녹음기


  • 기본 UI 구성
  • 권한 요청하기
  • 녹음 기능 구현하기 - 1
  • 녹음 기능 구현하기 - 2
  • 오디오 시각화
  • 마무리

오디오 시각화

SoundVisualizer 커스텀 뷰를 만들어 자기자신을 계속 호출하여 리스트를 갱신하는 runnable 객체를 마저 완성하도록 하자.

그전에 먼저 함수를 정의할 수 있도록 null 값의 함수를 메소드로 넣어주자

// SoundVisualizerView

var onRequestCurrentAmplitude: (() -> Int)? = null

// MainActivity

private val soundVisualizerView: SoundVisualizerView by lazy {
    findViewById(R.id.soundVisualizerView)
}

soundVisualizerView.onRequestCurrentAmplitude = {
    recorder?.maxAmplitude ?: 0
}

우리는 main 액티비티에서 onRequestCurrentAmplitude 함수를 정의함으로써 녹음 객체인 recorder의 maxAmplitude를 반환하도록 했다.

이제 정의한 함수를 invoke하여 runnable 객체에서 사용할 수 있겠다.

private val visualizerRepeatAction : Runnable = object : Runnable {
    override fun run() {
        val currentAmplitude = onRequestCurrentAmplitude?.invoke() ?: 0
        // MainActivity 에서 정의한 함수로 현재 오디오가 가진 maxAmplitude 값을 가져옴

        drawingAmplitudes = listOf(currentAmplitude) + drawingAmplitudes
        invalidate()

        handler?.postDelayed(this, ACTION_INTERVAL)
        // 자기 자신을 20ms 마다 호출함
    }
}

리스트의 헤드에 currentAmplitude를 넣어 줌으로써 실시간으로 draw 할 수 있다. 20ms 간격으로 자기자신을 재호출하여 실시간으로 갱신한다.

다만 시작과 종료를 위해 객체를 종료할 수 있는 핸들러 메소드를 등록해준다.

fun startVisualizing() {
    handler?.post(visualizerRepeatAction)
}

fun stopVisualizing() {
    handler?.removeCallbacks(visualizerRepeatAction)
}

이제 MainActivity의 적절한 위치에 뷰 핸들러를 넣어주자.

private fun startRecord() {
    recorder = MediaRecorder().apply {
        setAudioSource(MediaRecorder.AudioSource.MIC)
        setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP) // 컨테이너
        setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB) // 코덱 지정
        setOutputFile(recordingFilePath)
        prepare()
    }
    recorder?.start()
    soundVisualizerView.startVisualizing()
    state = State.ON_RECORDING
}

private fun stopRecording() {
    recorder?.run {
        stop()
        release()
    }
    recorder = null
    soundVisualizerView.stopVisualizing()
    state = State.AFTER_RECORDING
}

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

수강인증샷

링크

https://bit.ly/37BpXiC

 

 

728x90