USB ウェブカメラをソフト的に無効化する

OS は Debian Linux、デスクトップ環境は XFCE で、ウェブカメラを使用している。必要なときだけ USB のプラグを挿しそれ以外のときはプラグを抜くようにしていたのだが、頻繁に抜き挿しするうちに接触不良ぎみになってしまった。

挿しっぱなしにする代わりに物理的なレンズキャップをとも考えたがそれも面倒くさい。USB ポートの論理接続を切り替えることにした。物理的に取り外しのできないノート PC などにも応用できるだろう。

modprobe -r uvcvideo という方法もあるようだが、それではすべての USB カメラデバイスも同時に消えてしまう。特定のカメラだけを無効化したい。

事前情報

lsusb -t で事前にウェブカメラの番号を調べておく。

/:  Bus 003.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/4p, 480M
    |__ Port 001: Dev 002, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 002: Dev 004, If 0, Class=Video, Driver=uvcvideo, 480M
        |__ Port 002: Dev 004, If 1, Class=Video, Driver=uvcvideo, 480M
        |__ Port 002: Dev 004, If 2, Class=Audio, Driver=snd-usb-audio, 480M
        |__ Port 002: Dev 004, If 3, Class=Audio, Driver=snd-usb-audio, 480M

のような情報から、

  • Bus 003
  • Port 1 (外付または内部の USB ハブ)
  • Port 2 (カメラ本体)

がわかり、Linuxの sysfs 上の表記でこれは 3-1.2 という ID になる。

それがわかれば、/sys/bus/usb/devices/3-1.2/authorized に 0 を書き込めば無効化、1 を書き込めば有効化できる。

bash のコマンドラインで使うなら、エイリアス

alias cam-off="echo '0' | sudo tee /sys/bus/usb/devices/3-1.2/authorized"
alias cam-on="echo '1' | sudo tee /sys/bus/usb/devices/3-1.2/authorized"

にしておけば楽。

0 を書き込んだ後に lsusb -t で見てみると、Port 2 の項目が消えていることが確認できる。

XFCE パネルへの組み込み

さらに楽にするために、ふだん使用しているデスクトップ環境の XFCE のパネルに切り替えスイッチを設置したい。

制御スクリプトの作成

実行するたびに有効化/無効化を切り替えるメインスクリプトを /usr/local/bin/toggle_camera.sh あたりに作成する。

#!/bin/bash

# 設定: 事前に特定したカメラのパス
DEV_PATH="/sys/bus/usb/devices/3-1.2"

# 現在の状態を取得 (1=ON, 0=OFF)
CURRENT_STATUS=$(cat "$DEV_PATH/authorized")

if [ "$CURRENT_STATUS" -eq "1" ]; then
    # OFFにする
    echo 0 | sudo tee "$DEV_PATH/authorized" > /dev/null
    echo "Camera OFF"
else
    # ONにする
    echo 1 | sudo tee "$DEV_PATH/authorized" > /dev/null
    echo "Camera ON"
fi

実行権限を与えておく。chmod +x /usr/local/bin/toggle_camera.sh

sudo パスワードの回避

パネルからクリックした際に sudo のパスワード入力を求められないようにしておく。

/etc/sudoers の末尾に以下を追記する (username は実際のユーザー名)。

username   ALL=(ALL) NOPASSWD: /usr/local/bin/toggle_camera.sh

パネル表示用スクリプトの作成

XFCE のパネルプラグイン(Generic Monitor)に状態とアイコンを渡すためのスクリプトを ~/bin/cam-status.sh あたりに作成する。

#!/bin/bash

DEV_PATH="/sys/bus/usb/devices/3-1.2"
TOGGLE_SCRIPT="sudo /usr/local/bin/toggle_camera.sh"

# アイコンの設定
if [ -f "$DEV_PATH/authorized" ] && [ "$(cat "$DEV_PATH/authorized")" -eq "1" ]; then
    # ON
    #echo "<img>/usr/share/icons/Adwaita/symbolic/devices/camera-web-symbolic.svg</img>"
    echo "<icon>camera-web</icon>"
    echo "<tool>ウェブカメラは有効(クリックで無効化)</tool>"
else
    # OFF
    #echo "<img>/usr/share/icons/Adwaita/symbolic/status/camera-disabled-symbolic.svg</img>"
    echo "<icon>camera-disabled-symbolic</icon>"
    echo "<tool>ウェブカメラは無効(クリックで有効化)</tool>"
fi

# クリック時の動作
#echo "<click>$TOGGLE_SCRIPT</click>"
echo "<iconclick>$TOGGLE_SCRIPT</iconclick>"

<img> の場合はフルパスで指定、<icon> なら camera-web-symbolic のように名前で指定する。なお <img> のときは <click> にし、<icon> のときは <iconclick> にする。

実行権限を与えておく。 sudo chmod +x ~/bin/cam-status.sh

XFCE パネルへの組み込み

  1. GenMon のインストール: Debian なら sudo apt install xfce4-genmon-plugin
  2. パネルに追加: パネルを右クリック → 新しいアイテムの追加 → ジェネリックモニター
  3. 設定: 追加されたアイコンを右クリック → プロパティ
    • コマンド: cam-status.sh (またはフルパス)
    • ラベル: (チェックを外す)
    • 間隔(秒): 10 (適当に)

以上で、アイコンをクリックするだけで即座に切り替えられる。

起動時の状態

起動時に必ずウェブカメラを無効化の状態にするには、システム起動時に一度だけ authorized を 0 に書き換える設定を追加する。cron@reboot 指定を使う。

root の crontab に

@reboot echo 0 > /sys/bus/usb/devices/3-1.2/authorized

を追加する。

注意

もしポートの場所が変わってしまう可能性がある (USB の挿し口を変えたなど) 場合は、ベンダー ID で自動探索などがいいのかもしれないが、今回は決め打ちとした。

それが変わったときは、2つのスクリプトと root の crontab の計3か所の中のパスを書き換えるのを忘れずに。

Emacs 風キーバインド

先日、久しぶりに勉強会のようなところへ出かけてみました。そこで会の主要なテーマとは直接関係のない Mac のキーバインドの話を聞きました。私は Mac にはほとんど触れたことがないので知りませんでしたが、おやこれは「Emacs風キーバインド」ではないかと思いました。起源はもう忘れられているかもしれません。

さて、そこで Debian をデスクトップで使っているという自分の環境を思い返してみました。エディターは主に Emacs なので、いろいろなところを「Emacs風キーバインド」にしたいと思いながら、ウィンドウマネージャーを変更したりブラウザーがバージョンアップして拡張機能が効かなくなっていたり、と、いつの間にか不便な状態になっていて、まあそのうち、と思いながら過ごしていたのです。

これを機会に、ちょっと探してみました。ほとんど自分用メモですが、Mac から Linux に乗り換えたい人への情報になるかもしれません。

Xfce4

以前 Gnome を使っていた頃はどこかで設定していたのですが、数年前に Xfce4 に切り替えてから、どうすればいいのか調べてもおらず、そのままになっていました。

「設定」→「設定エディター」で、「チャネル」の一番下の xsettings を開き、Gtk のグループの中のプロパティ KeyThemeName の値に Emacs と入力します。

これで、Xfce4 上で開く多くのアプリケーションで、C-aC-eC-k などが有効になりました。ただし C-y で取り出せるバッファが C-k と連動していないところが Emacs や次の bash と違う挙動で、ときどき混乱してしまいます。

Bash

ターミナル内のシェル は bash です。これは元々「Emacs風キーバインド」のようで、入力行で C-aC-eC-k が使えて、C-k したものを C-y で貼り付けることができます。C-pC-n で履歴をたどれるなど、かなり多くのキーバインドが使えます

Firefox

以前は、拡張機能でそういうのがあったのですが、ブラウザー本体のバージョンアップで使えなくなっていました。

上述の Xfce4 の設定で、いくらかのキーが使えるようになりました。しかし、上下に動かしたいときについ C-pC-n と打って「印刷」「新しいウィンドウを開く」になってしまったり、ページ内検索のつもりでつい C-s と打って「ファイルに保存」になってしまうことがしょっちゅうなので、この辺りを補ってくれるものはないかなあと思っています。

GhostText

Firefox の入力欄 (textarea) で、好きな外部エディターを使えます。以前は別の拡張機能を使っていたのですが、やはりブラウザー本体のバージョンアップで使えなくなってしまい、また別の拡張機能も WordPress の新しい入力画面 Gutenberg との相性が悪そうなので、現在は GhostText を使っています ((GhostText という拡張機能は Firefox にも Chrome にもあり、元々 Emacs 以外のエディターを使うものだったので、それらのどの組み合わせでも使えます。))。

Emacs 側でも準備が必要で、atomic-chrome パッケージをインストールして、設定しておきます。