全身鏡が欲しいけど買うとデカくて捨てにくいので、使ってないディスプレイを縦置きにすれば全身鏡の代わりになるんじゃないかと思いました。 試しに23インチぐらいのディスプレイとiPadを繋いでフロントカメラで撮影したみて、1.5m~2.0mぐらい離れれば全身が十分見える感じでした。

ただし、ディスプレイを鏡とする場合にスイッチを入れるのはリモートでやりたいので、iPadではリモートから起動が難しくて別のPCが必要でした。 ちょうど、普段あんまり使えてないmac miniがあったので、これをディスプレイと繋いで作ってみることにしました。

あと、せっかくディスプレイに表示するので、そのディスプレイ(鏡)に写した内容を半自動的に記録できるといいなと思いました。 こういうストック的なメモにはNotionを使ってたので、撮影した画像を自動的にNotionへアップロードする仕組みも作りました。

必要なもの

  • ウェブカメラ
  • PC
    • 今回はmac mini
    • ウェブカメラと繋げられるもの。カメラ内蔵ならそっちもいいけど、PCのカメラは遠距離苦手が多い
  • Bluetoothキーボードとなるシャッターリモコン
    • スマホ用シャッターリモコンでググると出てくる
    • ON/OFF/シャッターボタンの3つぐらいボタンがあると嬉しい

仕組み

ディスプレイを全身鏡にする仕組み

ディスプレイを鏡にする仕組みは結構単純です。 ウェブカメラで撮影している映像を、ディスプレイに表示するだけです。

縦置きのディスプレイに表示するので、カメラの向きとかも縦長になるように撮影する必要があります。 自分の場合は、ロジクールStreamCamで縦長に撮影してQuick Cameraで映像を横に回転してディスプレイに表示しています。(本当はカメラ自体が縦に対応しているらしいけど…)

イメージとしては次のような感じです。

ロジクールStreamCamは、ちゃんと2mぐらいの距離とかもフォーカス合わせてくれるので全身をみるにも十分でした。 ただ、明るさの変更とかで自動で調整が入るのですが、1秒ぐらいかかることがあるので実際の鏡よりフォーカスや明るさの変化に弱いです(目の性能による)。 静止している状態 や 左右に揺れてるぐらいなら(距離の変化には弱い)、反応や画質も悪くなく十分かなという感じでした。

ディスプレイ(鏡)に写った映像をNotionに記録する仕組み

こっちがディスプレイを鏡として使うメリットです。 Quick Cameraにはウェブカメラの映像が写っているので、これをスクショして記録できれば、鏡の内容をそのまま記録できます。その時の服装とか部屋の様子だったりとかポチッと記録できるので便利です。

これは、Quick Cameraのスクショを撮って、Notionにアップロードするスクリプトを書いて対応しています。

サンプルは次のリポジトリに置いてあります。

このスクリプトは、Notionの特定のデータベースに YYYY/MM/DD のタイトルのページにQuick Cameraで映してる映像のスクショをアップロードします。 YYYY/MM/DDというタイトルのページは事前に作っておく前提となっています。(やろうと思えば、該当ページがないなら作るのもNotion APIでできると思います。)

一方でNotionのAPIには画像をアップロードするAPIは公開されていません。 そのため、次のような手法で画像をアップロードしています。

  1. スクリーンショットを撮影し、クリップボードにコピーする
  • screencapture -c で撮影してる
  1. 指定したページをNotion.appで開く
  • open notion://<user>/<page>
  1. ページを開いたらクリップボードをペーストしてアップロードする
  • キー入力のエミュレートにはRobotJSを利用

クリップボードを使うことで、APIを使わずにアプリ経由でアップロードできます。 Notionのアプリは notion://<userid>/<pageid> で特定のページを開けます。

あとは、このスクリプトを実行するたびに、Quick Cameraの映像を 2022/10/08 のようなページにアップロードできます。

📝 仕組み的に実行するたびにNotionにフォーカスが移動してしまうので、Quick Cameraに対して”常に最前面で表示する”オプションを実装しています。

リモコンを使ってシャッターを切る

鏡なのでPCを起動しないと見れないのは不便です。 macはキー入力があればスリープから復帰できる(ただしパスワード入力をスキップする設定にする必要はあるけど、家専用なので)ので、Bluetoothのキーボードがあれば、リモートから起動できて便利です。

スマホ用シャッターリモコンはBluetoothで繋ぐものがあって、これのシャッターリモコンとmac miniをBluetoothで繋いでいます。 また、ボタンがいくつかあるので、シャッターを切るボタン(先程のスクリプトを実行するボタン)とPCをスリープするボタンなどの設定をKarabiner-Elementsでしています。

Karabiner-Elementsはデバイスごとのキー設定ができ、またキーに対してShell Scriptを設定できます。

たとえば、自分が持ってるスマホシャッターは3つボタンがあって、調べるとvolume down/upとenterキーになっていたので、それぞれに対応する処理を割り当てています。

    "profiles": [
        {
            "complex_modifications": {
                "rules": [
                    {
                        "description": "[Shutter] Focus QuickCamera −",
                        "conditions": [
                            {
                                "type": "device_if",
                                "identifiers": [
                                    {
                                        "product_id": xx,
                                        "vendor_id": xxxx
                                    }
                                ]
                            }
                        ],
                        "manipulators": [
                            {
                                "from": {
                                    "consumer_key_code": "volume_decrement"
                                },
                                "to": [
                                    {
                                        "lazy": true,
                                        "repeat": true,
                                        "shell_command": "pmset sleepnow"
                                    }
                                ],
                                "type": "basic"
                            }
                        ]
                    },
                    {
                        "description": "[Shutter] Focus QuickCamera +",
                        "conditions": [
                            {
                                "type": "device_if",
                                "identifiers": [
                                    {
                                        "product_id": xxx,
                                        "vendor_id": xxxx
                                    }
                                ]
                            }
                        ],
                        "manipulators": [
                            {
                                "from": {
                                    "consumer_key_code": "volume_decrement"
                                },
                                "to": [
                                    {
                                        "lazy": true,
                                        "repeat": true,
                                        "shell_command": "open -a 'Quick Camera'"
                                    }
                                ],
                                "type": "basic"
                            }
                        ]
                    },
                    {
                        "description": "[Shutter] Screenshot to Notion X",
                        "conditions": [
                            {
                                "type": "device_if",
                                "identifiers": [
                                    {
                                        "product_id": xxx,
                                        "vendor_id": xxxx
                                    }
                                ]
                            }
                        ],
                        "manipulators": [
                            {
                                "from": {
                                    "key_code": "return_or_enter"
                                },
                                "to": [
                                    {
                                        "lazy": true,
                                        "repeat": true,
                                        "shell_command": "/path/to/notion-upload-image/run.sh"
                                    }
                                ],
                                "type": "basic"
                            }
                        ]
                    }
            }
        }
    ]
    

これをすることで、スマホシャッターでPCを起動(何かのボタンを押す)、シャッターボタンでスクショをNotionにアップロードするスクリプトを実行、余ったボタンでPCをスリープできています。

おわりに

結構適当に組み合わせて作りましたが、シャッターボタンを押すとscreencaptureが実行されシャッター音のSEを出してくれるので、結構シャッター切ってる感があって面白いです。 スマホシャッターはBluetoothのキーボードと同じなので、レイテンシーはほとんど感じないです(どちらかというとNotionにアップロードする時間の方がかかるので、上げ切るまでにスリープしないようにする必要がある)。

わざわざ新しくディスプレイとPCを用意するほどのものではないですが、鏡に機能性を追加すると意外と面白いのかなーと思いました。

“鏡 ディスプレイ”で調べてみると、鏡にディスプレイを乗せたものはありました。

あと、Quick Cameraは左右反転とかもできるので、鏡と違って左右反転しないミラーにもできたりします。