screenrecordの問題点を解決して活用してみる


はじめに

この記事は【その2】ドリコム Advent Calendar 2015 - Adventarの12日目です。
11日目はちゃんもさんです。
ちゃんもさんの記事はこちら→アニメーション美術背景製作あれこれ | ちゃんも's Ownd
【その2】があるということは【その1】ドリコム Advent Calendar 2015 - Adventarもありますのでこちらもどうぞ。
【その3】は知りません。たぶんないです。

自己紹介

ドリコムでクライアントエンジニアやってる新卒です。
こういう記事を書くのは初めてなので至らぬところが多々あると思いますが、最後まで読んでいただければ嬉しいです。

screenrecordって?

タイトルにもありますが、screenrecordAndroid 4.4 (KitKat) から利用できるADB (Android Debug Brigde) Shell のコマンドで、 Android端末で描画しているものを動画として端末に記憶できる機能です。
screenrecordコマンドによってプレイ動画の設定や別のカメラで画面を撮影することなく、またアプリの開発や運用のフェーズに関係なくそのアプリの挙動を動画として残すことができるようになりました。

Android SDKのダウンロードや設定、端末のデバッグ用の設定等は必要ですが、特別なソフト等がいらないのでお手軽さがあると思います。 (そもそもAndroidアプリを開発する時点で上記の設定は済んでいるはずですし。)

開発時の動画の活用

開発時に動画を使うと便利だなと思った場面がいくつかあります。

  • アニメーションや演出の確認
  • 表示系のバグ
  • 再現方法が不明なバグ

それぞれについて少しばかり説明します。 (ここはAndroidに限らない話だと思うので。)

アニメーションや演出の確認

アニメーションや演出を実装して、いざデザイナーさんに見せようと思ったがデザイナーさんがいない時ってあると思うんです。
その時に、実装した演出が行われている動画を送ることで、その演出を見てもらえるのでデザイナーさんを探す手間が省けます。

数種類の演出を実装して他職種の方にどの演出がいいか見てもらいたい時ってどうしましょう。
演出を切り替えられるようにするのも1つの手だと思いますが、繰り返しみたり、切り替えを何度もして比較してもらうのであれば、動画を演出の種類分送ることでそのコストを少しばかり減らせるんじゃないかと思っています。

表示系のバグ

表示がおかしいだけでクラッシュしないバグです。
このバグの何がつらいってクラッシュログが飛ばないことですよね。
気づいた頃には表示がおかしくなっていたりするので・・・・。
そういう時に動画で残しておくとどこから表示がおかしくなったか見返すことができ、原因に少しでも近いところからバグの原因の調査ができるように思います。

再現方法が不明なバグ

先ほどの「表示系のバグ」と似ているところもあるのですが、再現方法が不明なバグもいつの間にかバグが発生していたりするわけです。
動画として残していれば、バグが発生するまでにどんな操作をしていたか、もしくはその操作によって画面上ではなにが起こっていたかを見返すことができます。
するとこの操作が怪しいとかあたりをつけることができて、次はその操作をする、しないでバグが発生するかしないか確認するといった問題の切り分けが行えます。
やみくもにバグを再現させようとするよりは効率的なんじゃないかなと思っています。

じゃあscreenrecordを使ってみよう

Android端末とPCをUSBでつないで、adb shell screenrecord /sdcard/hoge.mp4ってコマンドうって、ぽちぽち・・・・おっ!このバグが発生したぞ!
動画を見返してみると・・・あれっ?・・・動画終わっちゃった。バグが発生するだいぶ前に録画終わっちゃってた・・・orz

残念ながらscreenrecordは1回のコマンドで最大180秒までしか録画できません。
180秒しかないのでバグが起こるタイミングがわかってる時はいいかもしれませんが、実機テストを行っている時など、これからバグが起こりうるかもしれない、かつそのバグを逃したくないみたいな時にはもっと長時間の録画が必要だと思います。

録画時間を延ばす

今回はシェルスクリプトとして書いてみました。
コード全体はこちらに。
(なのでWindowsでは使えません、ごめんなさい。使いたい場合はCygwinとかでなんとかしてください。)

アルゴリズム的な

発想としては簡単で、180秒しか録画できないのなら180秒ごとに録画して動画つなげればいいんじゃねって感じです。

こんな感じに撮れます

youtu.be

4分くらいの動画のつなぎ目部分だけを抜き出してます。
10秒くらいがつなぎ目です。
フレームが飛んでるのは裏でpullとかが動いてたりするからですね。
(あと端末がNexus7 2012でとても古いのも原因だと思われ)

コード

主な部分だけ抜粋して説明します。

long_screenrecord.sh

screenrecord コマンドを180秒ごとに発行しているやつです。

メイン部分

while [ $STOP = 0 ]
do
    sh my_screenrecord.sh ${FILE_NAME} ${PATH_LOCAL} &
    PID=$!
    PID_ARRAY+=(${PID})
    sleep 180
done

wait ${PID_ARRAY[@]}

my_screenrecord.shを180秒ごとに実行してます。
my_screenrecord.shについては後述します。
waitコマンドは引数として渡されたPIDを持つプロセスが終了するまで処理を待ってくれるコマンドです。
ここではバックグラウンドで走らせてる録画処理などが全て終わるまで待ってくれています。

STOPフラグの管理

function stop_record() {
    kill ${PID}
    STOP=1
}

trap stop_record 2 15

trapは特定のシグナルを受け取った時の処理を記述できます。
2は割り込みシグナル (Ctrl-C)、15はプロセス終了シグナルです。
終了シグナルをもらってスクリプトが止まってしまうと、Android端末から録画した動画をPCに取り込めないからです。(途中で無理やり終了させる時は強制終了(番号だと9)を想定してます)。

動画連結

ffmpeg -f concat -i ${LIST_FILE} -c copy temp.mp4

ffmpegコマンドに関しては詳しくありませんが、画像処理周りでいろいろ使えそうな気がしてます。(主に動画変換で使ったりするんですかね。)

my_screenrecord.sh

実際にscreenrecordコマンドを発行しているスクリプトです。
録画して、PCに転送して、Android端末から消去するをひとまとめにしています。

録画本体

function stop_screenrecord() {
    echo "record stop"
    kill ${PID}
}

adb shell screenrecord ${PATH_ANDROID}${FILE_NAME} &
PID=$!

trap stop_screenrecord 2 15

wait ${PID}

主役のscreenrecordを裏で走らせてます。
先ほどと同じようなコードですが、ここでも終了シグナルでスクリプトが終了しないようにしています。
waitコマンドに待ってもらってscreenrecordが終わってからのちの処理を行えるようにしています。

ここでAndroid端末に保存している動画をPCに転送しています。

trap '' 2 15 # 無効にする
adb pull ${PATH_ANDROID}${FILE_NAME} ${PATH_LOCAL}
adb shell rm ${PATH_ANDROID}${FILE_NAME}
trap 2 15 # 元に戻す

trap '' 2 15は割り込みシグナルを受けたら''を実行する→何もしないということになります。 trap コマンドはシグナル番号だけ渡すとシグナルをもらった時の処理を元に戻せます。

工夫した点

  • 1回のscreenrecordのたびにadb pulladb shell rmをしているのでAndroid端末の容量が厳しくても長い時間録画可能(後述の方法だと1本の長い動画が端末に入ってしまうので容量を圧迫してしまう)
  • 動画のエンコード時間も配慮してバックグランドでの処理
  • waitを用いてうまく同期とる
  • trapを用いて従来のscreenrecord命令と同じ録画の止め方を再現

今後の改善点

  • 動画のつなぎ目のなめらかさ
  • screenrecordpullを裏で同時に走らせるため端末のスペックによってはカクつく
  • screenrecordのオプションを活かす
  • Android端末が複数ある場合の処理
  • Windowsにも対応したいなぁ

その他の方法

こんな方法もあるそうです。

[Android] 長時間録画できるscreenrecordを作りました - adakoda

おわりに

最後まで読んでいただいてありがとうございます。
発想自体は簡単だったんですが、エラー処理とかいろいろ考えると思ったより時間かかっちゃっていろいろ未熟さを感じますね。
あと作ったはいいけど使われないのは作った甲斐がないので使われるように広めていけるように頑張りたいです。

次はちゃんまきさんのきれいで分かりやすい!心を動かすプレゼン用パワーポイントを作る方法 - Makiko BLOGです。