指パッチンで動画の再生・停止を操作できるChrome拡張を作ってみた

# はじめに
この記事は [東京高専プロコンゼミAdvent Calendar 2021その2](https://adventar.org/calendars/6569) 6日目の記事です．(その1は[こちら](https://adventar.org/calendars/6568))

# なぜこれを作ったのか
アドベントカレンダーに登録したはいいもののネタがなくて苦しんでいたところ，たまたま授業でTeachable Machineに触れる機会があり，これで指パッチンを判別して動画の操作ができたら面白そう(小並感)という思い付きで作ることにしました．

# [Teachable Machine](https://teachablemachine.withgoogle.com/)とは
Teachable Machineは、Googleが開発しているウェブベースのGUI操作のみで機械学習モデルを作成できるサービスのことです．現在は画像，ポーズ，音声の3つのモデルに対応しており，誰でも簡単に"無料で"機械学習に触れることができます．

# 指パッチンの検出モデルを作ってみる
まずは https://teachablemachine.withgoogle.com/ にアクセスし，下図のように音声プロジェクトを新規作成します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547432/8a921f48-3d56-d795-9551-7127457e36f2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547432/43bd81da-b6a2-3415-7481-9e3b4816591c.png)

音声プロジェクトを作ると，最初は「バックグラウンド ノイズ」と「Class2」の二つの分類があります．
バックグラウンド ノイズはその名の通り目的以外の音のことです．ここには，指パッチンの音の認識精度が上がるように適当なデータを与えてやります．

今回は，何も音を鳴らさずにホワイトノイズを20秒の他に，指パッチンの音と似ているマウスのクリック音とキーボードのタイプ音，鼻をすする音をそれぞれ20秒録音してサンプルとしたいと思います．

録音方法は下図のように「マイク」ボタンを押した後に「20秒録画する」ボタンを押して音を鳴らし，「サンプルを抽出」ボタンを押すだけです．ちなみに一度の録音時間は歯車アイコンのメニューから変更することもできます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547432/0670e07f-bb51-d607-16a8-77e38db258ff.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547432/ee90fe61-616b-bb93-b400-241f1da7d21b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547432/b9a063be-b580-94fa-bca9-bcb84f9e0798.png)

次は，指パッチンの音を録音します．下図のようにペンアイコンを押して分類の名前を「snap」に変えたらバックグラウンド ノイズの時と同じように録音するだけです．録音時間は1秒でサンプル数は15ぐらいあれば十分だと思います．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547432/1fb0f381-9255-fdd2-d656-06f3cd6a35af.png)

サンプルの録音が終わったら学習をしてみましょう！
といってもやることは簡単で，真ん中の「モデルをトレーニングする」ボタンを押して待つだけです．

トレーニングが終わると下図のようにリアルタイムに音声を取得して判別することができます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547432/90493d61-8aca-5660-53a2-4eb980319459.png)
![15.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547432/481e1d4b-55e2-78c7-2e17-fd9c31f20bbd.gif)

また，モデルはダウンロードまたはクラウド上にアップロードして使うこともできます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547432/3aa8f856-2c55-f9b9-8195-be4f1e35dc9d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547432/3551a1c6-2f12-9220-390b-2e58b0c2a074.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547432/0d4d0934-38e4-519f-0221-2039224b4969.png)

# Chrome拡張を作る
先ほど作ったモデルをクラウドにアップロードしてリンクを取得し，それをもとにTensorflow.jsを使って声を認識します．
リアルタイムでの音声の取得とTensorflowを使った音の判別の実装は，Googleがすでにコードスニペットととして公開してくれているのでこれを利用して終わりです．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547432/7635a9ed-689d-3942-d87e-2b45dfdb9094.png)

あとは，音の判別結果をもとにChrome側で動画の再生・停止を操作するだけです．
動画の再生・停止は，video要素の`paused`プロパティーが動画を停止しているときに`true`，再生しているときに`false`になるのでこれを使って切り替えるだけで大丈夫です．

```javascript
const video = document.getElementsByTagName("video")[0];
if(video.paused){
    video.play();
}else {
    video.pause();
}
```

これらを組み合わせていい感じにChrome拡張として動くようにした完成品がこちらになります．
https://github.com/fazerog02/SnapVideoController

# 配布
一応配布します(Chromeストアは審査に時間がかかるので，拡張ファイルでの配布)．
https://drive.google.com/file/d/1_ohZuAQiB7pSy_suoxLL64qKe_nGstdC/view?usp=sharing

導入はChrome設定の拡張機能ページに，crxファイルをドラッグアンドドロップするだけです．

# おわりに
記事投稿，遅刻してすみませんでした...(一応ハワイ標準時ではセーフ？)

作ってみた感想ですが，Chrome拡張開発は初めてで，一から調べながらやったので結構大変でした．また，以前からTampermonkeyのカジュアルさに慣れていたのもあって，割と慣れるまでに時間がかかりました．
Teachable Machineの方はかなり簡単に機械学習モデルを生成できて便利でした．皆さんも是非遊んでみてください！

最後になりますが，拙い文章にここまでお付き合いいただきありがとうございました！！