注意: sndcpyはAndroid 10以降で使えます。

たまにゲームの音楽などを録音したくなるときがあります。画面録画で簡単にできますが、Androidの標準機能だとモノラルになったり、サードパーティのアプリを使ってステレオで録音できたとしても、音が圧縮されているので音質が悪かったりします。

こういうのは音に敏感な自分にとって許せないので、簡単にかつ高音質に録音できる方法はないのか探っていました。

一番手っ取り早いの方法としてアナログケーブルで繋いで録音するというものがありますが、現代のPC、とりわけノートパソコンではLINE IN端子がないためこの方法が使えるのは限定的です。自分は入力端子付きのPCがあるためできなくはないのですが、メインPCではないので操作が面倒です。

もう一つの方法として、sndcpyというツールを使ってネットワーク・USB経由でデジタル録音する方法がありますので、紹介します。

sndcpyとは

sndcpyは、rom1v(Romain Vimont)さんによって作られたフォワーディングツールです。 以下の図のような構成で音をPCで聴けるようにしています。

sndcpyのサーバーがAndroid上で動作し、ADBのトンネルを経由してPC側で再生します。

ダウンロードと準備

sndcpyを使うにはVLCが必要です。 https://www.videolan.org/vlc/index.ja.html からダウンロードしてインストールします。

sndcpyの最新バージョンは https://github.com/rom1v/sndcpy/releases からダウンロードできます。 sndcpy-v◯.zip はsndcpy単体で、sndcpy-with-adb-windows-v◯.zipはADBが付属しています。 まだADBをインストールしてない場合は後者をダウンロードしたほうがいいかと思います。

解凍するとsndcpy (Linux用シェルスクリプト)、sndcpy.apk (Androidにインストールする用のパッケージ)、sndcpy.bat (Windows用バッチスクリプト)が入っています。

使ってみる

あらかじめadb connectなどのコマンドを使ってAndroid端末と接続します。
※Android 11からはワイヤレスデバッグが使えます

コマンドプロンプトなどを開いて .\sndcpy.bat と入力すれば、端末にsndcpy.apkがインストールされてサービス起動します。 数秒後に再生が始まります。音楽を流してみたり、ゲームを起動するとPCで音が流れるはずです。

通知欄にはsndcpyが常駐しています。「STOP」をタップすると止まります。 WindowsではCtrl+Cで止められないので端末側から止める必要があります。

聴くだけであれば、今のようにADBで繋いでバッチスクリプトを起動するだけでOKです。

録音する

実は、sndcpyの仕組みとしては端末側でサーバーを立ち上げてUNIXソケットをPC側のTCPポートにフォワーディングして、VLCを起動し再生する、という操作をスクリプト化しているだけなので、これを応用すれば録音が可能です。

sndcpyが端末にインストールされている前提で作業を進めていきます。 バッチスクリプトを読んでいくと、まず最初にフォワーディングの設定をしています。

%ADB% %serial% forward tcp:%SNDCPY_PORT% localabstract:sndcpy || goto :error

%SNDCPY_PORT% は行頭で宣言されており、デフォルトで28200になっています。PCからは、localhost:28200でアクセスできるということになります。

普段使うときはこのコマンドラインを使います。ポートは28200に固定しています。

adb forward tcp:28200 localabstract:sndcpy

さらに読むと、端末側にインストールしたsndcpyのサービスをadb経由で起動させていることがわかります。 これは接続を切断するごとに実行する必要があります。切断するといちいちサービスが停止してしまうようです。

%ADB% %serial% shell am start com.rom1v.sndcpy/.MainActivity || goto :error

普段使うときはこうします。

adb shell am start com.rom1v.sndcpy/.MainActivity

それからVLCを起動…となっているのですが今回は使いません。FFmpegを使います。 Windows版は ここ からダウンロードできます。7zip形式なのでLhaplusなどの解凍ソフトが必要です。 その他OSは https://www.ffmpeg.org/download.html の「Get packages & executable files」を参照してください。 ダウンロードしたら解凍してパスを通しておきます。

sndcpyのサーバーは生のPCMデータを送信しています。ソースコードを読んだところ48000Hz 16ビット符号付きのフォーマットで送信しているようなので、それに合わせます。FFmpegは生のデータからサンプリング周波数などを割り出せないので自分で指定する必要があります。

FFmpeg付属のプレイヤーで再生してみます。adb shell am start com.rom1v.sndcpy/.MainActivity でサービスを立ち上げておきます。

ffplay -ar 48000 -ac 2 -f s16le tcp://localhost:28200 を実行すると、数秒待つと再生されるはずです。再生されないときは adb forward tcp:28200 localabstract:sndcpy でフォワーディングを設定し直します。

再生できることが確認できたら録音してみます。サービス立ち上げ直しを忘れずに!

ffmpeg -ar 48000 -ac 2 -f s16le -i tcp://localhost:28200 -acodec flac test.flac

可逆圧縮コーデックのFLACを使って録音しています。可逆なので劣化しません。

qキーを押すかCtrl+Cで録音が止まります。ここではtest.flacという名前で保存しています。Windows Media Playerなどで聴けます。

毎回サービス立ち上げ直しなんて忘れてしまいそうなので、最後にスクリプト化します。 フォワーディングもするようにしておきました。

if not "%1"=="" (
    set recfile=%1
) else (
    set recfile=rec.flac
)
adb forward tcp:28200 localabstract:sndcpy
adb shell am start com.rom1v.sndcpy/.MainActivity
ffmpeg -y -ar 48000 -ac 2 -f s16le -i tcp://localhost:28200 -acodec flac %recfile%

これを好きな名前でバッチファイルとして保存すれば、クリックしてすぐに録音ができます。 何も指定しなかったとき、直接バッチファイルを実行したときは rec.flac という名前で保存されます。 コマンドラインではファイル名を指定できます。.\rec.bat 2022-03-21.flac と指定するとファイル名を変えられます。

なお、このスクリプトはsndcpyがインストールされている前提で組んでいます。 手動でインストールする場合は、sndcpy.apkを用意して以下のコマンドを実行してください。

adb install -t -g -r sndcpy.apk
adb shell appops set com.rom1v.sndcpy PROJECT_MEDIA allow

注意点

  • 前述の通り、Android 10以降でしか使えません。
  • 画面ミラーリングソフトのscrcpyとは共用可能ですが、その他のMediaProjection APIを使うアプリ(画面録画ソフトなど)とは共存できない可能性があります。もしそのアプリを動かしてsndcpyが止まってしまったら無理だと思ってください。
  • 通知音は拾えません。
  • サンプリング周波数は48000Hz、ビット深度は16ビット固定ですが、ソースコードを改変することで端末が対応できる範囲で引き上げられる可能性があります。興味のある方は挑戦してみてください(アプリの再ビルドが必要です)。