「ちょっと待てぃ!!」で動画を止める #相席食堂


こんにちは、皆さんも相席食堂の **ちょっと待てぃ!!ボタンで動画を止めたい**って思うことありますよね？
こんな感じのものを作ってみました。動画みてね☆

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ちょっと待てぃ!! ボタンを実装したので自分の発言にちょっと待てぃ!! してみた<br><br>BluetoothキーボードとChrome拡張機能のセットです。<a href="https://twitter.com/hashtag/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E8%99%8E?src=hash&amp;ref_src=twsrc%5Etfw">#プログラミングの虎</a> <a href="https://twitter.com/hashtag/%E7%9B%B8%E5%B8%AD%E9%A3%9F%E5%A0%82?src=hash&amp;ref_src=twsrc%5Etfw">#相席食堂</a> <a href="https://twitter.com/hashtag/iotlt?src=hash&amp;ref_src=twsrc%5Etfw">#iotlt</a> <a href="https://twitter.com/hashtag/m5stack?src=hash&amp;ref_src=twsrc%5Etfw">#m5stack</a> <a href="https://t.co/7ooLvXt9nU">pic.twitter.com/7ooLvXt9nU</a></p>&mdash; 菅原のびすけ （プロトアウト9期募集中) (@n0bisuke) <a href="https://twitter.com/n0bisuke/status/1719959603511951612?ref_src=twsrc%5Etfw">November 2, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

祝(?)[Chromeのストア](https://chromewebstore.google.com/detail/%E3%81%A1%E3%82%87%E3%81%A3%E3%81%A8%E5%BE%85%E3%81%A6%E3%81%83/igekcdidbcbeiglbieknbnljlkjnenlj?hl=ja&pli=1)にも公開しました！

> ![スクリーンショット 2023-12-01 17.16.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/3a819bfa-8157-3884-0291-20d5c310c649.png "スクリーンショット 2023-12-01 17.16.15.png")

ということで[IoTLTアドベントカレンダー](https://qiita.com/advent-calendar/2023/iotlt)1日目ですね！今年もやっていきましょう〜

## 有名TV番組、相席食堂のアレをやりたい

[相席食堂](https://www.asahi.co.jp/aisekishokudou/)はお笑い芸人の千鳥の二人が事前収録の動画(VTR)を見ながら、 **気になる点があれば手元の「ちょっと待てぃ!!」ボタンを押してVTRを止め、ツッコミを入れる**といった番組です。

> 参考: https://ja.wikipedia.org/wiki/%E7%9B%B8%E5%B8%AD%E9%A3%9F%E5%A0%82
> ![スクリーンショット 2023-12-01 12.51.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/cc4fae50-505f-314b-e2a1-2f942e4a94f2.png "スクリーンショット 2023-12-01 12.51.02.png")
> 引用: [Google検索](https://www.google.com/search?q=%E7%9B%B8%E5%B8%AD%E9%A3%9F%E5%A0%82&sca_esv=586845846&tbm=isch&sxsrf=AM9HkKnc3pMLIUteZRhTrmdxKCTJMklSWg:1701402644551&source=lnms&sa=X&ved=2ahUKEwjb9v3hqu2CAxU1ga8BHR-ODEkQ_AUoA3oECAIQBQ&biw=1650&bih=935&dpr=1.8)

これやりたくなりますよね。作ってみました（冒頭の動画↑）。

## ガシャポン品ちょっと待てぃ!!ボタンを改造してキーボード化

調べると既製品として、ちょっと待てぃ!!ボタンのおもちゃが発売されていた模様でした。

https://gashapon.jp/products/detail.php?jan_code=4549660719878000

> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/48b4d743-14e7-8794-b031-fe3c71680b44.png" width="300px" />

**このおもちゃは音が出るだけ**なので、これを **改造してキーボード化してPCで再生している動画を止めてみよう**と思います。

> ![スクリーンショット 2023-12-01 13.03.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/edf21dad-8944-c4dc-688a-e0e16f148c7f.png "スクリーンショット 2023-12-01 13.03.50.png")

動画編集をする人だと馴染みがあると思いますが、YouTubeや動画再生ツールはスペースキーで停止・再生が出来ます。なのでボタンを押すとスペースキーが発火されるキーボードデバイス化をすればそれっぽい挙動になります。

### ステップ1. ちょっと待てぃ!!ボタンの解剖

（製造停止しているため）中古購入したちょっと待てぃ!!ボタンを解剖して信号を取り出せないか検討します。

開けてみると、中の導電性の素材がボタンを押されて接触 -> 通電して「ちょっと待てぃ!!」の音が出るといったものみたいです。

> ![スクリーンショット 2023-12-01 15.22.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/4144b5c9-a5e0-595e-5319-9a883988518b.png "スクリーンショット 2023-12-01 15.22.28.png")

> ![スクリーンショット 2023-12-01 16.56.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/8e798a7a-3829-e1bb-7180-970f8f51e537.png "スクリーンショット 2023-12-01 16.56.04.png")

最初は圧力センサなどを入れられないかなど思ってましたが、 @kitazaki さんに相談したところ、タクトスイッチと同じですねと言われて確かにと思ったので、タクトスイッチの要領で信号を取ってみました。

> ![スクリーンショット 2023-12-01 16.50.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/cda13939-eca9-4080-30df-8f3267f71179.png "スクリーンショット 2023-12-01 16.50.09.png")
> 引用元: デバイスプラスさん https://deviceplus.jp/arduino/arduino_f06/

プルダウン抵抗を挟んで信号を取得することができました。

> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/518901b8-8b66-7c38-713c-841de7da2f12.png" width="250px" />

> 検証時にはobnizを利用

一旦これでボタンを押したらマイコンボード側で信号を受け取ることができました。

### ステップ2. 自作キーボード

信号を受け取ることができたので、次はPCにスペースキーとして送るためのキーボード化です。

自作キーボードを作るにあたっては[M5Atom Lite](https://www.switch-science.com/products/6262)を利用しました。 

ESP32-BLE-Keyboardというライブラリを使ってBluetoothキーボードとしてPCに認識させます。

https://github.com/T-vK/ESP32-BLE-Keyboard

M5系は先人が記事書いてくれてる率が高くて助かりますね。

> 参考: ラズパイの実さんの記事 https://knt60345blog.com/blekeyboard1/

ちなみにエンターキーにする場合は`bleKeyboard.write(KEY_RETURN);`とするのですが、KEY_SPACEみたいなものはなくて、通常にスペースを送る感じの実装でした。ここちょっと悩んだ苦笑

- ❌ `bleKeyboard.write(KEY_SPACE);`
- ⭕️ `bleKeyboard.print(" ");`

こんな感じで信号をみて押下されたかどうか検知 & スペースキーの送信です。

```src/main.cpp
//ちょっと待てぃが押下されたかどうか 抜粋
if(digitalRead(IN_SW) == LOW){
  M5.dis.drawpix(0, dispColor(0, 0, 255));
}else{
  M5.dis.drawpix(0, dispColor(20, 20, 20));
  bleKeyboard.print(" "); //スペースキー
  delay(chotMatePress_ms); //連続で押されないように少しウェイトさせる
}
```

<details><summary>コード全て</summary><div>

```src/main.cpp
#include "M5Atom.h"
#include <BleKeyboard.h>  // https://github.com/T-vK/ESP32-BLE-Keyboard

BleKeyboard bleKeyboard("CHOTO MATEI KB");  //デバイス名

const int longPress_ms = 300;  // 長押し判定時間(ms)
const int chotMatePress_ms = 1000;
#define IN_SW 25

CRGB dispColor(uint8_t r, uint8_t g, uint8_t b) {
  return (CRGB)((r << 16) | (g << 8) | b);
}

void setup() {
  M5.begin(true, false, true);
  M5.dis.drawpix(0, 0x000000);  // LED OFF
  pinMode(IN_SW, INPUT); //ちょっと待てぃの信号を受ける

  Serial.begin(115200);
  Serial.println("BLEキーボードアプリ開始");
  
  bleKeyboard.begin();
}

void loop() {

  M5.update();

  // BLE接続中かどうか
  if(bleKeyboard.isConnected()){
	
	// ちょっと待てぃ!!ボタンが押下されているか
    if(digitalRead(IN_SW) == LOW){
      M5.dis.drawpix(0, dispColor(0, 0, 255));
    }else{

      M5.dis.drawpix(0, dispColor(20, 20, 20));
      bleKeyboard.print(" "); //スペースキー
      
      delay(chotMatePress_ms);
    }
    
    // ATOMのボタン側もデバッグ用で
    if(M5.Btn.wasPressed()){
      // M5ATOMのボタンが押されたら一定時間待つ
      delay(longPress_ms);
      // // キーが押されたままだったら長押しと判定
      if(M5.Btn.read() == true){
        //　長押し時の処理
        M5.dis.drawpix(0, 0x00f0f0);  // LED MAGENTA

        Serial.println(" 長押し時は、Returnキー押下 を送信 ");
        // bleKeyboard.write(KEY_RETURN);
        bleKeyboard.print(" "); //スペースキー
        delay(100);
      // キーがリリースされていたら短押しと判定
      }else{
        // 短押し時の処理
        M5.dis.drawpix(0, 0xf00000);  // LED GREEN

        Serial.println(" 短押し時は、文字列 Hello World を送信 ");
        // bleKeyboard.print(" Hello World ");
        bleKeyboard.print(" "); //スペースキー
        delay(100);       
      }
    }
    // BLE接続であることを、ATOMのLED（青）を知らせる
    M5.dis.drawpix(0, 0x0000f0);  // LED BLUE
  }else{
    // BLE未接続であることを、ATOMのLED（赤）を知らせる
    M5.dis.drawpix(0, 0x00f000);  // LED RED
  }
  delay(10);
}
```
</div></details>


ちなみんPlatformIOでやってますが設定はこんなでした。

```platformio.ini
[env:m5stack-atom]
platform = espressif32
board = m5stack-atom
framework = arduino
lib_deps = 
	m5stack/M5Atom@^0.1.1
	fastled/FastLED@^3.6.0
	M5Atom
	t-vk/ESP32 BLE Keyboard@^0.3.2
monitor_speed = 115200
```

最後に銅線を内部に通して一旦完成です。一旦。。。

> ![スクリーンショット 2023-12-01 17.04.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/02cb8df4-bf6d-5c57-419f-0b650917db22.png "スクリーンショット 2023-12-01 17.04.34.png")

ちなみに、銅線は千石電商さんでこういうのを購入して利用してます。半田付けをした箇所だけ表面のフィルムが溶けて通電するけど他の箇所は絶縁された状態を保てるとのことで今回みたいに接触可能性がある場所に仕込むにはちょうどよかったです。

> ![スクリーンショット 2023-12-01 17.06.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/1e331ae8-502e-ba16-e692-29262dc8162b.png "スクリーンショット 2023-12-01 17.06.14.png")
> https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-04KM

## ここで気付く。「ちょっと待てぃ!!」感が足りない! - Chrome拡張開発

ここまでで一旦実装できたのですが、 **使ってみて思ったのは、圧倒的「ちょっと待てぃ!!」感のなさ**でした。

動画を止めるだけではなく、エフェクトとしてちょっと待てぃ!!が出ないと満足できなかったんですね。

ということで、YouTube用にChromeエクステンションを作ることにして、YouTube画面でスペースキーが押されたらちょっと待てぃ!!の画像が出るような仕組みを作りました。

### ちょっと待てぃ!!素材

ちょっと待てぃ!!の画像素材はニコニ・コモンズに自作して公開されてる方( https://twitter.com/oyu_bgm さん)がいてこれを使わせてもらいました。 

https://commons.nicovideo.jp/works/nc273587

### YouTubeで画像レイヤーを変える

YouTubeのプレイヤーエリアにはytd-playerというidが振られている模様でした。

> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/75a1e6e3-3356-8248-e1a1-5a9e0e5117b6.png" width="400px" />

ほぼChatGPTに書いてもらいましたが、こんな感じでプレイヤーレイヤーの上に画像レイヤーを作って表示される処理を作りました。

> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/8042bbea-55d1-0392-1b3b-8f9c3127a9f0.png" width="400px" />

```main.js
function ytCoverChange(){
	const playerContainer = document.getElementById('ytd-player'); //プレイヤー部分
	const imgLayer = document.getElementById('my-yt-cover');
	console.log(imgLayer);

	if (playerContainer) {

		if(imgLayer){
			imgLayer.remove();
		}else{
			// 新しい画像要素を作成
			const imgLayer = document.createElement('img');
			imgLayer.src = chrome.runtime.getURL('./images/choto_matei_text.png');
			imgLayer.style.position = 'absolute'; // 位置を絶対位置にする
			imgLayer.style.top = '0'; // トップに配置
			imgLayer.style.left = '0'; // 左に配置
			imgLayer.style.width = '100%'; // コンテナの幅に合わせる
			imgLayer.style.height = '100%'; // コンテナの高さに合わせる
			imgLayer.style.zIndex = '1000'; // 必要に応じてz-indexを高めることで他の要素の上に表示させる
			imgLayer.id = 'my-yt-cover';

			// 画像レイヤーをプレイヤーコンテナの最初の子として追加
			playerContainer.insertBefore(imgLayer, playerContainer.firstChild);
		}
	}

}
```

### スペースキーが効かない問題 - 既存ショートカットの排除

先ほど書いた関数をスペースキーを押したイベントに紐付けて発火させれば良いのですが、スペースキーはすでにYouTube側で何か処理がされていて、 **スペースキーだけうまくイベント取得が出来ない問題**が発生しました。

なんとかして既存のショートカットキーを無効化できないか？を調べていたところ、 **YouTubeのショートカットキーを無効化する拡張機能を作って公開している人が...!**

https://chromewebstore.google.com/detail/remove-youtube-hotkeys/ajabfhplebocnmdcejfleginmigkhjdj

たぶん同じようなことをしたかったのかなと思います。

これを使いながら開発を一旦行いました。

### スペースキーを押すとスクロールしてしまう問題

これでスペースキーを押すとちょっと待てぃが表示されていい感じだったのですが、

ただ今度はスペースを押すと下にスクロールしてしまいました。当然と言えば当然ですね。YouTube側はその辺を元々制御するようなスペースキー実装をしていたと思うのですがそれを無効化しちゃってるので当然です。

以下の質問を見つけて

https://teratail.com/questions/90805


`event.preventDefault()`で上手いこといけました。

> ![スクリーンショット 2023-12-01 17.30.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/e4fc91af-7c2f-58f4-3013-0dd7c83a2d5b.png "スクリーンショット 2023-12-01 17.30.49.png")

集合知ありがたや。。

### せっかくなのでストアに公開

[Chromeのストア](https://chromewebstore.google.com/detail/%E3%81%A1%E3%82%87%E3%81%A3%E3%81%A8%E5%BE%85%E3%81%A6%E3%81%83/igekcdidbcbeiglbieknbnljlkjnenlj?hl=ja&pli=1)にも公開しました！

> ![スクリーンショット 2023-12-01 17.16.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/3a819bfa-8157-3884-0291-20d5c310c649.png "スクリーンショット 2023-12-01 17.16.15.png")

最新版では、こちらのコードを取り入れて単体の拡張機能だけでちょっと待てぃが表示されるようになっています。

https://qiita.com/querykuma/items/4519f924288b37225e22

## 仕上げ: 箱に詰める

最後に、見栄えを考えて箱に詰めます。

配線はちょっと待てぃボタンの下側から出ているので箱の上にボタンを置いて、箱の中に配線を隠す形にしました。

> ![スクリーンショット 2023-12-01 17.36.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/0e02b384-51f6-9c10-fe0a-ff6616da50be.png "スクリーンショット 2023-12-01 17.36.15.png")

ボタンのスピーカーが下側にあるため絶妙に音が籠る感じがしたので、 **内蔵スピーカーから線を引き出して外部スピーカーに接続**しました。

> ![スクリーンショット 2023-12-01 17.34.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/bfda2e4b-9149-7547-eb7e-8dcdca1b09db.png "スクリーンショット 2023-12-01 17.34.32.png")

という感じで冒頭の動画のようなボタンキーボード&拡張機能が完成しました。

https://protopedia.net/prototype/4902

プロトぺディアにもまとめてあります。

## 大変だったところ

### ちょっと待てぃ!!ボタンが入手できない

これはM5Stackのユーザー会でLTした時のオチ的な感じだったのですが、実装だとハンダ付けがしんどい。。みたいな話題はありつつ、ちょっと待てぃ!!ボタンの入手が大変でした。最終的にメルカリで入手しましたが、 **ガシャポンが初めてすぎて**、どこかにあるのか,,, 秋葉原散策したらあるのか... と無駄に時間がかかってしまいました。ググっても出てこないしツイッターの情報は古いしでなかなか難しいですね。

> ![スクリーンショット 2023-12-01 17.38.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/cd59ae8b-8b62-b41c-3c65-7a2ab5a5c62c.png "スクリーンショット 2023-12-01 17.38.09.png")

あと製造終了しているというのもあり、断線とかしてミスったときに買い増すのもちょっと面倒だったりするので冒険しづらさもありました。

### USBキーボード化しようとして沼る

USBキーボードとして使いたかったのですが、USBキーボード化するとATOM Liteが2回目以降にキーボードとして認識されてしまって書き込みがうまくいかず、デバッグがかなりやりにくいという状況になりました。

ただ、IoTLTで話をしたら有識者の方からこんな回答が！泣

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ファームつくるときにキーボードとして動き出すまでにウェイトをかけるようにつくるとか、GPIO監視してモードを分けるようにすると便利。<br>どうにもならなければ強制的にハードウェア的にBootモードのGPIOを下げてリセットして Download Ready にする。(早口) <a href="https://twitter.com/hashtag/IoTLT?src=hash&amp;ref_src=twsrc%5Etfw">#IoTLT</a></p>&mdash; nanbuwks (@nanbuwks) <a href="https://twitter.com/nanbuwks/status/1716796191822995645?ref_src=twsrc%5Etfw">October 24, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

なるほどっすなぁ。キーボードとして動き出す前にウェイトをかける... 言われてみれば確かにだけどそのとき思いつかなかったので目から鱗。

## 終わりに

という感じで、ちょっと待てぃをしたいだけだったけどChrome拡張機能を作ったりキーボード作ったりと色々勉強になることが多かったです。

現状ハンダづけして線を引き出してた部分のハンダが剥がれてしまって再起不能状態で転がってるので本体改造無しでやれる方法を少し探っています。

皆さんも「ちょっと待てぃ!!」やってみましょう。

そして、僕はいまだに相席食堂は見たことありません。

カレンダー明日は@kitazakiさんですね！お楽しみに〜〜