wanna be dev 🧑‍💻

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

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

Android/Challenge

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

Kick_snare 2022. 3. 11. 23:04
728x90

47일차

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

강의 목표


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

목차 02 Basic - Ch07. 녹음기


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

오디오 시각화

저번 시간에 녹음 하는 경우의 오디오 시각화를 완성하였으니 이번에는 마찬가지로 다시 재생할 때에도 오디오가 시각화 될 수 있도록 만들어 주자.

먼저 isReplaying이라는 재생중임을 구별하는 상태 프로퍼티를 만들고 runnable 객체를 시작하는 핸들러에 상태 값을 받아오자

private var isReplaying: Boolean = false

fun startVisualizing(isReplaying: Boolean) {
    this.isReplaying = isReplaying
    handler?.post(visualizerRepeatAction)
}

이제 똑같이 onDraw 하며 forEach문을 돌며 그려줄 것이지만 replaying의 경우과 구분하여 그려줄 것이다.

replaying의 경우 녹음했는 amplitude 리스트를 반대로 끝에서 부터 읽어야 할 것이다.

그러므로 let문을 이용해서 가져올 때 반대로 가져오도록 하자.

private var replayingPosition: Int = 0

// in onDraw fun
drawingAmplitudes
    .let { amplitude ->
        if(isReplaying) amplitude.takeLast(replayingPosition)
        else amplitude
    }
    .forEach { amplitude ->
        val lineLength = amplitude / MAX_AMPLITUDE * drawingHeight * 0.8F

        offsetX -= LINE_SPACE
        if(offsetX < 0) return@forEach

        canvas.drawLine(
            offsetX, centerY - lineLength / 2F,
            offsetX, centerY + lineLength / 2F,
            amplitudePaint
        )
    }

let를 이용하니 정말 cool한 코드가 완성되었다.

내가 직접 짰다면 다른 함수를 만들거나 더 지저분하게 짰을거 같은데 감쪽같이 코드 3줄 추가하니 완성

이제 그럼 MainActivity 에서도 인자값을 주고, playing 하는 부분에 메소드를 추가해주자.

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(false)
    state = State.ON_RECORDING
}

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

private fun startPlaying() {
    player = MediaPlayer().apply {
        setDataSource(recordingFilePath)
        prepare()
        // prepare Async 는 비동기적으로.. 지금은 금방 되니까 걍
    }
    player?.start()
    soundVisualizerView.startVisualizing(true)
    state = State.ON_PLAYING
}

private fun stopPlaying() {
    player?.release()
    player = null
    soundVisualizerView.stopVisualizing()
    state = State.BEFORE_RECORDING
}

와 정말 쉽다~~~!!!


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

수강인증샷

링크

https://bit.ly/37BpXiC

 

728x90