M5Cameraのindex.htmlをシンプルに書き換えてみた

###はじめに
M5Cameraをブラウザに繋ぐと、皆さんおなじみの設定画面が出てきますよね。
フレームサイズを変えたり、ストリーミングのON/OFFができたりするあれです。
このindex.htmlにあたる部分を書き換える記事がいくつかありますが、圧縮/解凍しなければいけなかったり、元のhtml自体も長くて難しかったりして、改造のハードルが高そうでした。
そこで、自分に分かるくらいまで削りに削ったindex.htmlを作ってみました。

###参考文献
この記事では以下のサイトの情報を利用させていただいています。
有益な情報を共有してくださった皆様に感謝申し上げます。

「M5CAMERAのサンプルコード
camera_index.hは圧縮ファイルで読めない！……」
https://twitter.com/ZZZONEV32384623/status/1323272566866239488

ESP32（M5Cameraとか）でHTTPサーバを立ち上げたときのHTMLの内容を変更する方法
https://qiita.com/saka-guti/items/a2e07e4a9c85374a4973

M5cameraでWebカメラを作る
https://ambidata.io/samples/m5stack/m5camera/


#動作画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607008/7b9a7f5f-d5e3-ca47-ad29-2831d862b2cc.png)
動画が表示されている状態です。
設定変更メニューなどはばっさりカットです。
設定って、一度決めたらそんなに変えるものでもなくないですか？

#元ファイルからの変更点
CameraWebServerのスケッチのcamera_index.hの内容を以下に差し替えています。
元はhtmlを圧縮してありましたが、平文のほうが編集しやすいので圧縮しないようにしました。
短いのでスケッチのサイズ的にも問題ないと思います。

```
const char index_html[] = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
  <title>M5Camera Monitor</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <h1>M5Camera Monitor</h1>
  <figure>
    <img id="stream" src="" width=100% height:auto>
  </figure>
  <p><button id="button1">Start Stream</button>
     <button id="button2">Stop Stream</button></p>
  <p><button id="button3" >LED On </button>
     <button id="button4" >LED Off</button></p>
</body>
<script>
  document.addEventListener('DOMContentLoaded', function (event) {
    var baseHost = document.location.origin
    var streamUrl = baseHost + ':81'

    const view = document.getElementById('stream')
    const startButton  = document.getElementById('button1')
    const stopButton   = document.getElementById('button2')
    const ledonButton  = document.getElementById('button3')
    const ledoffButton = document.getElementById('button4')

    startButton.onclick = () => {
      view.src = `${streamUrl}/stream`
    }
    stopButton.onclick = () => {
      view.src = ``
      window.location.reload(true);
    }

    const query0 = `${baseHost}/control?var=led&val=0`
    const query1 = `${baseHost}/control?var=led&val=1`

    ledonButton.onclick = () => {
      fetch(query0)
    }
    ledoffButton.onclick = () => {
      fetch(query1)
    }
})
</script>
</html>
)rawliteral";
```

そしてこの内容ををブラウザに送る処理をしている、app_httpd.cpp内のindex_handlerを以下のように書き換えます。
元は二種類のイメージセンサにあわせて分岐するようになっていましたが、M5cameraのイメージセンサは一種類しかないので簡潔にします。

```
static esp_err_t index_handler(httpd_req_t *req){
    sensor_t * s = esp_camera_sensor_get();
    return httpd_resp_send(req, (const char *)index_html,sizeof(index_html));
}
```

ここまでで動画を配信する用意はできました。
必要に応じて静止画のキャプチャ機能なんかを付け足すと良さそうですね。

なお、M5CameraのLEDをON/OFFさせたい場合にはapp_httpd.cpp内のコマンドハンドラの該当部分に追加が必要です。

```
...（略）
    else if(!strcmp(variable, "led")) {
      if(val == 0) {
        digitalWrite(GPIO_NUM_14, LOW);
        Serial.println("control: led: 0");
      }
      if(val == 1) {
        digitalWrite(GPIO_NUM_14, HIGH);  
        Serial.println("control: led: 1");
      }
    }
...（略）

```

もちろんメインのスケッチのsetup()内でピンモードをOUTPUTにしておくことを忘れずに。
  `pinMode(GPIO_NUM_14, OUTPUT); // LEDを点滅させるために必要`
#終わりに
これくらいシンプルだと、カスタマイズもしやすくて良いのではないでしょうか。

なお、設定は/controlで後から変更できます。
ただし再起動すると初期設定に戻ってしまうので、毎回設定しなおすのが面倒ならコード内に書いておいたほうが楽かもしれません。

設定を変更する例:
ブラウザからhttp://(M5cameraのIPアドレス)/control?var=framesize&val=10にアクセス
(画面サイズが最大に設定されます)

それでは楽しいプログラミングを。