工作

Circuit Playground ExpressでZoom meetingのマイクとカメラをOn-Off

動機

ZoomやMicrosoft Teamsでのオンランミーティングが仕事や生活の一部になりました。操作にはずいぶん慣れましたが、とくにマイクのミュート、アンミュートは頻繁に使う機能です。話の隙間を狙ってアンミュートしようと、カーソルをマイクコントロールアイコンの上にのせてタイミングを待つマウスの上の手がつらい。

ボタン一発でマイクやカメラのOn-Offができるものがあればいいのに。

あればいい、なら作ってみたら?ということで引き出しに入りっぱなしだったAdafruit Circuit Playground Express(CPX)を引っ張り出して活躍してもらうことにしました。

しくみ

CPXからキーボードショートカットをパソコンに送出するという仕掛けです。今の状態を表すために、Neopixelがついたり消えたりするようにもしました。(On-Offどちらも同じショートカットでトグルさせているだけなので、NeopixelのOn-Off状態と合わせるために、最初にパソコン側でマイクとカメラをOffにしてから使い始めるという、”なんちゃって仕様”です。CPXをキーボードとして使っているのだけなので、パソコン側の今の状態を引き出すことはできないのです。できるともっといいのですが。今回は今すぐほしい、を優先しました。)

windowsとmacとではショートカットキーの組み合わせが違うので、CPXのスライドスイッチでどちらで使うのかを切り替えることができるようにしました。

Windowsでのショートカットキー

  • microphone: Alt + A
  • camera: Alt + V

Macでのショートカットキー

  • microphone: Command + Shift + A
  • camera: Command + Shift + V

見た目はこんな感じ

左がマイク用のAボタン、右がカメラ用のBボタンです。真ん中下にあるのがスライドスイッチで、この個体ではWindows用、Mac用を切り替えられるようにしてあります。(もう一つの個体ではZoomとMicrosoft Teamsとを切り替えられるようにしました)

Neopixelで今の状態をお知らせ。左(赤)がマイク、右(青)がカメラ。点灯がunmute (on)を表す。

動作の様子

code

Circuitpythonで書きました。Neopixelとbuttonの部分がうまく動くのを確認した後、スライドスイッチの部分を書き足そうと、adafruit_circuitplayground libを読み込んでエラー。少々混乱しましたが、何とか書けました。

import board
import time
import usb_hid
import adafruit_fancyled.adafruit_fancyled as fancy
from digitalio import DigitalInOut, Direction, Pull
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from adafruit_circuitplayground import cp

# cp.switch: left=True, right=False
# left: windows
# right: mac

# Zoom/Windows
# toggle microphone: Alt + A
# toggle camera: Alt + V

# Zoom/Mac
# toggle microphone: Cmd + Shift + A
# toggle camera: Cmd + Shift + V

# Set up a keyboard device.
kbd = Keyboard(usb_hid.devices)

# colors
mic_color = fancy.CHSV(0, 1.0, 0.01).pack()  # hue, saturation, value
cam_color = fancy.CHSV(0.6, 1.0, 0.01).pack()  # hue, saturation, value

# neopixel on cpx
npx = cp.pixels

# neopixel hue demo
i = 0
while i < 1:
    for pp in range(10):
        h = (pp * (1.0/10) + i) % 1.0
        hsvcolor = fancy.CHSV(h, 1.0, 0.01)  # hue, saturation, value
        npx[pp] = hsvcolor.pack()
        npx.show()
        time.sleep(0.03)
    i = i + 0.1
# off all
npx.fill((0, 0, 0))
npx.show()

# previous status
mic_status = False
cam_status = False


def neopix_control(idxs, rgb):
    for i in idxs:
        npx[i] = rgb  # set with CHSV().pack(), brigntness included
    npx.show()


while True:
    # when button pressed
    if cp.button_a:
        if cp.switch:  # True=Left=Windows
            kbd.send(Keycode.ALT, Keycode.A)  # --- windows
        else:  # False=Right=Mac
            kbd.send(Keycode.COMMAND, Keycode.SHIFT, Keycode.A)  # --- mac
        if mic_status:  # was on.  turn it off
            neopix_control([1, 2, 3], (0, 0, 0))
        else:  # was off.  turn it on
            neopix_control([1, 2, 3], mic_color)
        # toggle status
        mic_status = not mic_status

        while cp.button_a:
            pass

    if cp.button_b:
        if cp.switch:  # True=Left=Windows
            kbd.send(Keycode.ALT, Keycode.V)  # --- windows
        else:  # False=Right=Mac
            kbd.send(Keycode.COMMAND, Keycode.SHIFT, Keycode.V)  # --- mac
        if cam_status:  # was on.  turn it off
            neopix_control([6, 7, 8], (0, 0, 0))
        else:  # was off.  turn it on
            neopix_control([6, 7, 8], cam_color)
        # toggle status
        cam_status = not cam_status

        while cp.button_b:
            pass

使ってみて

便利。

buttonがdebounceで複数押しになってしまうことがあるので、debounce対策をコードにいれるべき。

CPXのpinoutはいくつかがtouch sensorとしても使えるので、二つのボタンにとどまらず、もっとショートカットをアサインしてさらに便利にしたいと思っています。スクリーンシェアの切り替えや、ホスト以外をミュートなど、キーボードショートカットのあるものならなんでもできるハズ。家族にも聞いて必要なものを組み込んで使ってみます。

Zoom, Teams切り替えバージョン(Windows専用)も作って使っています。

ABOUT ME
misson
ものづくりが趣味。頭の中でモヤモヤと渦巻くガスを形として沈殿させるのが趣味。座右の銘は:こたえは常に自分の中にある


follow us in feedly

COMMENT

メールアドレスが公開されることはありません。