2019-06-06

MediaRecorder.AudioSourceについて詳しく知ろう

はじめまして。都内でソフトウェアエンジニアで働いている meteor と申します。

最近はiOSとAndroidで配信アプリを作るお仕事をしています。

みなさんは MediaRecorder.AudioSource をちゃんと理解していますか?

今回は筆者の経験を元に、それぞれの違いについて解説していきます。あくまでも個人的に推測して書いているので、参考程度にお読みください。

また、他に知見がありましたらコメント等でお寄せください。

MediaRecorder.AudioSource の種類

Androidでマイクから音を拾う時、どの入力ソースから音をとるのか困ったことはありませんか?

基本的には、 DEFAULT で大丈夫です。しかし、入力ソースごとの違いをしっかり把握しておくと良いでしょう。

Source 挙動
DEFAULT 端末のデフォルトが選択される(通常は MIC が選ばれる)
MIC 端末の通話用マイクが選択される
CAMCORDER 端末のセカンドマイクが選択される
VOICE_COMMUNICATION DEFAULT ソースからVoIP用に最適化される(録音時に声以外のノイズが軽減される)
VOICE_RECOGNITION DEFAULT ソースから音声認識用に最適化される(録音時に声以外のノイズが軽減される)
REMOTE_SUBMIX 端末の音声をリモートに流す(システム権限が必要なので使えない)
VOICE_UPLINK 通話時に自分から相手に送信された音(システム権限が必要なので使えない)
VOICE_DOWNLINK 通話時に相手から自分に送信された音(システム権限が必要なので使えない)
VOICE_CALL VOICE_UPLINKVOICE_DOWNLINK を合わせた音(システム権限が必要なので使えない)
UNPROCESSED DEFAULT ソースからエフェクトを通さずにそのまま出力する(普段は使わない)
VOICE_PERFORMANCE DEFAULT ソースから低遅延で音をとる(Android Q実装予定)

cf. https://developer.android.com/reference/android/media/MediaRecorder.AudioSource

通話用マイクとセカンドマイクの違い

unnamed.png

例として、Pixel 3で説明していきます。Pixel 3の場合は、前面にマイクが二種類あります。

上部の図をご覧ください。

まず最初に、5. に通話するときに使うマイクがあります。

次に 2. にセカンドマイクがあります。

これらの違いは指向特性です。セカンドマイクのほうがより広く音が拾えるでしょう。

なので、もし通話アプリを作るときは、通話用マイクを選ぶべきですし、カメラアプリを作るときはセカンドマイクを選択したほうが良いでしょう。

ただし、端末によって指向特性が異なったり、端末によってはセカンドマイクがない場合もあります。

面倒ではありますが、端末ごとに検証していくことが大事ですね。

システム音をとる方法

現在、Androidでシステム音をとる方法はありません。

システム音をとるには Manifest.permission.CAPTURE_AUDIO_OUTPUT と呼ばれるパーミッションが必要なのですが、残念ながらサードパーティには解放されていません。

もともと、Android 5.0時点では Manifest.permission.CAPTURE_AUDIO_OUTPUT はサードパーティに解放されていました。

しかし、当時、通話の盗聴アプリが流行していたこともあり、セキュリティの関係で、上記にあるパーミッションはAndroid 6.0以降から使えなくなってしまいました。

今後もサードパーティ向けに解放することはおそらくないでしょう。

【2019年6月6日追記】

次のAndroidバージョンであるAndroid Qより、Playback Captureが入ることになりました。

これにより、端末内部のシステム音を録音することができます。

必要な権限はRECORD_AUDIOMediaProjectionManager.createScreenCaptureIntent() が必要みたいなので、スクリーンキャプチャであるMediaProjectionと一緒に使うことが前提とされています。

詳しくはドキュメントをご覧ください。

https://developer.android.com/preview/features/playback-capture

おわりに

今回は筆者の経験談を元に書きました。

ドキュメントには書いてないですが、MediaRecorder.AudioSourceにはそれぞれ癖があります。

これらの挙動をしっかりと把握した上で、最適なソースを選んでいくことが大事ですね。