中華アクションカメラのWiFi遠隔操作機能の中身を知る（しなさい）

#前置き
お酒飲みながらだらだら書いた。いつかちゃんとまとめる。
###背景
単刀直入に言うとカメラの録画と他の測定装置の記録を同期して行いたいという事情が出てきた！要するに、何らかの実験等で計測開始時に「測定器の操作もして…録画ボタンも一緒に押して…」だと手順が多すぎて時間が勿体ないしミスしやすいので、ボタン一発で時系列をそろえて動画と一緒に計測値も記録できる仕組みが必要というわけである。
###昨今多機能高品質になった廉価版アクションカメラ
GoProのような高級品を~~買えない~~荒い使い方できないし、ある程度の品質で目的を達成できれば十分というユーザーは一定数存在する。最近は4K画質や60FPSの動画に対応した機種も1万円以内で購入できるようになった。ここで特筆すべきはWiFi接続によりスマートフォンから録画ボタンの操作や、ファインダー越しの映像を確認できる機種が登場してきたことである。従来のようにカメラの筐体に触れることなく遠隔で操作できるようになったことで、危険が及ぶ場所や人の存在が介入することのない自然な環境においての録画が安価で可能となった。

調べてみても、案外中華アクションカメラの遠隔操作プロトコルについて解析してる人はいない。
ということで、今回は1年ほど前から使用している怪しいメーカーのアクションカメラを使って実現できる方法を模索するぜ！
まぁぶっちゃけWifi繋いどる時点でプロトコルは絞れるしなんとかなるっしょ。しらんけど！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823630/385a913d-1315-e9e8-cbd9-d4f64757b955.png)

##使用したカメラ
CrosstourというメーカーのCT9500を使用した。おそらく、異なる商品名でもこのカメラと中身は同等の商品は存在すると思われる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823630/9bde50d0-f83b-43b5-7e07-a856ed94eb0a.png)
https://www.amazon.co.jp/dp/B07Y1QXFLF/ref=cm_sw_r_tw_dp_dlC_x_cnCLFbKT8ABQ4 

また、WiFiを通じたスマートフォンからの遠隔操作にはYOUTUPROというアプリから操作を行う。名前からして動画サイトへのリスペクトを感じる。今回はこのアプリの動作を観察する。
https://play.google.com/store/apps/details?id=com.gku.yutupro&hl=ja

##Wire shark等を使ってパケットキャプチャできないか？
結論から言うとできなかった。アクセスポイント(カメラ)側の設定の問題なのか、スマホ-カメラ間のパケットを監視することはできなかった。（使いこなせてないだけかもしれない。）（ネットワーク詳しいひと教えて…）
一方、Android用のパケットキャプチャアプリは内部でVPNを置くことにより監視しているらしく、これでは既製品のカメラ操作用アプリを使用した際にエラーが発生してしまうので従来通りの使用方法を再現できず諦めた。

##ダメ元でAndroid Studioのデバッグ機能を使ってログチャットを覗いてみると…？
外から見るのがダメなら中身をみちゃえばいいじゃない！ってことで開発環境のデバッグ機能を使ってみることにした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823630/2985c8f7-80a7-b61f-7544-1cfdeac6eed4.png)
実機でカメラ操作アプリを動かしながらログを見てみる。ご丁寧にいろんな情報が出力されていた。簡体字の文字列が目立つ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823630/e9d98b55-842f-3f47-3ae6-a60c28ae0829.png)
操作メニューと思われる文字列が各言語で記述されていた。Androidアプリのフォーム記述に使うxmlっぽい？

ちらほらみてると、URLが見えてきた。どうやらカメラ自身がHTTPサーバとなっており、クライアント(Androidスマホ)からCGIスクリプトを動かす仕様らしい。マジかよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823630/b283df74-f0e8-04c6-2b48-0ebfb15a2bcb.png)


試しにPCからカメラにWiFi接続し、Webブラウザからログの中に見えたcgiスクリプトのURLにアクセスすると、カメラの機種の情報や、設定情報がレスポンスとして帰ってきた。なんか記述がJavascriptっぽい？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823630/ccfdc17f-1ba9-ac6e-71a6-26ffd4df551d.png)



スマートフォンから録画＆停止ボタンを押してみると、ログにクエリ文字列が吐き出された。これでもしかしたら最低限録画の開始と停止はできるかもしれない！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823630/c9aec34d-a545-6eb7-67ea-28c6b0a680e7.png)

見事予想的中。
スマホの既製品アプリを使わずとも録画開始&停止の操作成功！とりあえずちっちゃい目標達成となった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823630/d55da27f-ac79-84ff-3acf-33822f51b5ee.png)



##おまけ1　安心の日本語対応
普段留学生と話してる時の僕はこんな感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823630/8bb2bb56-c7fe-3d85-a82c-b7b4190f4f0d.png)
「本気ですか？」本気です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823630/af6b59af-b694-0b68-021d-c6b353caff57.png)
「静音」と書いて『シズネ』。娘ができたら命名したい。

##おまけ2 HTTPサーバーなら？
indexページは無く、ファイル一覧が表示される。言語設定用のファイルやらメインのバイナリが置いてあることからおそらくカメラ内部のFlash領域っぽい。
セキュリティガバガバかよ。
さらにSDカードにもアクセスできた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823630/56fa29db-340f-5690-bc10-7dbc9f95d2f0.png)




##おまけ3　クエリ文字列とレスポンス例
以下にログから得られたURLリクエストと帰ってきたレスポンスを示す。
機種やファームウェア情報

```HTTP:192.168.0.1/cgi-bin/hi3510/getdeviceattr.cgi
var name="Z2V2-Hi3559V2-458-RTL8189ES";
var serialnum="1";
var type="Hi3559V200";
var networkstatus="0";
var softversion="V3.1.0.1-A";
var hardversion="NewAPP";
var startdate="0";
var runtimes="3196252";
var model="3196252";
var timeout="0";
```

現在の撮影モードの取得？

```HTTP:192.168.0.1/cgi-bin/hi3510/getcurworkmode.cgi
var workmode="NormalVideo";
var value="";
```

```HTTP:192.168.0.1/cgi-bin/hi3510/getcurallinfo.cgi
var mode="NormalVideo";
var state="21";
var event="0";
var pasttime="0";
```

こちらはURLリクエストで、「通常撮影モードで撮影可能な画質一覧」と「現在の設定画質」のの取得

```http://192.168.0.1/cgi-bin/hi3510/getsecondmenuitem.cgi?-workmode=NormalVideo&-name=Resolution
var item="4K50,4K30,2.7K30,1440P60,1440P30,1080P60,1080P30,720P120,720P60";
var value="1440P60";
```