はじめに
会津大学学部3年のHAMADAです。この記事は「Aizu Advent Calendar 2023」18日目の記事です。今回は、鬼の2時間ハッカソンで試したことについて書いていきたいと思います。
経緯
つい最近、私が所属しているA-PxLで ”2時間ハッカソン” と題して、普段の定例会の2時間を使って、テーマが”クリスマス”のプロダクトを一本作り切るという鬼企画が開催されました。
A-PxLはXRのサークルなので、私もAndroidのARアプリを作成しようとしたのですが、ARCore周りの設定で1時間15分も溶かしてしまいました。流石にちょっと厳しそうだったので、方向転換をし、音声録音アプリケーションを作成することにしました。
一応テーマがクリスマスなので、プレゼントを届けに来たサンタさんに”メリークリスマス”と一言伝えられたら素敵やな、とか後付け的に思いついたので、テーマには沿ってると思います…
使用したもの・技術
実装
まず、録音をするためにAndroidManifest.xmlに以下を追記する。
<uses-permission android:name="android.permission.RECORD_AUDIO" />
MediaRecorderとMediaPlayerを使用して、
以下のように実装しました。
import android.media.MediaRecorder import android.media.MediaPlayer class AudioRecorder(private val filePath: String) { private var mediaRecorder: MediaRecorder? = null private var mediaPlayer: MediaPlayer? = null private var isRecording = false fun startRecording() { if (isRecording) return mediaRecorder = MediaRecorder().apply { setAudioSource(MediaRecorder.AudioSource.MIC) setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP) setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB) setOutputFile(filePath) prepare() start() } isRecording = true } fun stopRecording() { if (!isRecording) return mediaRecorder?.apply { stop() release() } mediaRecorder = null isRecording = false } fun playRecording() { mediaPlayer = MediaPlayer().apply { setDataSource(filePath) prepare() start() } } }
MediaRecorder
setAudioSource(MediaRecorder.AudioSource.MIC)
は音をマイクから取ってくるように設定しています。他にも電話から音をとったり、リンクから音を取ったりと色々設定できます。
setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
はアウトプットのフォーマットを設定しています。
setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
はエンコードの形式を設定しています。
setOutputFile(filePath)
は設定したファイルパスにファイルをアウトプットします。
prepare()
で初期化を完了します。
start()
でレコーダーを開始。
stop()
でレコーダーを停止。
release()
でリソースを解放。
MediaPlayer
setDataSource(filePath)
は再生するソースをセットします。
prepare()
で初期化を完了します。
start()
で再生を開始。
上記のような処理を呼び出す際に、使っているハードでパーミッションがあるかどうかを確認するために、以下のような実装をしました。
private fun handleRecording() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.RECORD_AUDIO), 200) } else { audioRecorder?.startRecording() } } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == 200 && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { audioRecorder?.startRecording() } }
アプリがRECORD_AUDIOのパーミッションを持っているかどうか確認して、持っていれば、そのままレコーディングを開始し、持っていなければ以下のようなリクエストを表示します。
リクエストに対してのユーザの応答を確認し、許可が得られていれば録音を開始します。
Andoidの実機が手元になく、デモが撮れませんでした。ごめんなさい...
おまけ
UIとしては、本当にシンプルで雑なUIなのですが、ChatGPT君にいい感じの画像を作ってもらい背景にしたところそれっぽい見た目になりました。
Before
After
感想と展望
45分で雑な実装にはなってしまいましたが、パーミッション周りは触ったことがなかったので、良い学びになりました。二時間でのハッカソンはかなり鬼畜の所業と言わざるを得ませんが、実装したい機能、やったことない機能を勉強するにはちょうど良いので、ぜひ次もやってみたいと思います。ここまで読んでいただきありがとうございます。良いクリスマス、良い年末をお迎えください。
所属サークル
私のTwitter
私のgithub