Web会議ミュートショートカットキー問題を解消

この記事はMac OS X向けです．

# Web会議ショートカットキー問題
ウェブ会議で，音声のミュートやビデオのオンオフを切り替えたいとき，いちいちマウスを持って画面上のアイコンをクリックしていたら，会話が途切れ途切れになってしまいます．

そこで，迅速に切り替えるためにショートカットキーで切り替える事を考えます．ただ，ここでWeb会議アプリショートカットキー問題にぶち当たります．

例えば，MS TeamsとZoomでは以下のようにミュート・ビデオオンオフのショートカットキーが異なります．

+ ミュート切り替え
    + Teams: Command + Shift + M
    + Zoom: Command + Shift + A
+ ビデオ切り替え
    + Teams: Command + Shift + O
    + Zoom: Command + Shift + V

いちいち憶えてられません．ホントクソです．

# 解決策
Teamsでも，Zoomでも，同じ直ぐに押せる簡単な方法でミュート・ビデオのオンオフを切り替えれるようにします．
具体的には，以下の2つを実現します．

- ミュートオンオフ切り替え: 右シフト2回押し
- ビデオオンオフ切り替え: 左シフト2回押し

## Hammerspoonを使って実現
Hammerspoonのインストール方法は割愛します．

まず，少し長いコードになるので，`init.lua`を直接編集せず，ファイルを分けるために，以下を追記．

``` ~/.hammerspoon/init.lua
local mute = require('mute')
```

以下の様な`mute.lua`を作成．

``` ~/.hammerspoon/mute.lua
-- 右shift2回押しでミュートの解除・左shift 2回押しでビデオのオンオフ切り替え
-- 
firstShift = false
secondShift = false
local function cancelShift()
    firstShift = false
    secondShift = false
end

local function toggleMuteVideoZoom(event)
    local c = event:getKeyCode()
    local f = event:getFlags()
    if event:getType() == hs.eventtap.event.types.flagsChanged then
        if f['shift'] then
            if c == 60 then -- 右シフト 60
                if firstShift then
                    secondShift = true
                end
                firstShift = true
                hs.timer.doAfter(0.5, function()
                    cancelShift()
                end)
                if firstShift and secondShift then
                    cancelShift()
                    hs.eventtap.keyStroke({"cmd", "shift"}, "A")
                end
            elseif c == 56 then -- 左シフト 56 
                if firstShift then
                    secondShift = true
                end
                firstShift = true
                hs.timer.doAfter(0.5, function()
                    cancelShift()
                end)
                if firstShift and secondShift then
                    cancelShift()
                    hs.eventtap.keyStroke({"cmd", "shift"}, "V")
                end
            else
                cancelShift()
            end
        end
    end
end
toggleMuteVideoZoomEvent = hs.eventtap.new({hs.eventtap.event.types.flagsChanged}, toggleMuteVideoZoom)

local function toggleMuteVideoTeams(event)
    local c = event:getKeyCode()
    local f = event:getFlags()
    if event:getType() == hs.eventtap.event.types.flagsChanged then
        if f['shift'] then
            if c == 60 then -- 右シフト 60
                if firstShift then
                    secondShift = true
                end
                firstShift = true
                hs.timer.doAfter(0.5, function()
                    cancelShift()
                end)
                if firstShift and secondShift then
                    cancelShift()
                    hs.eventtap.keyStroke({"cmd", "shift"}, "M")
                end
            elseif c == 56 then -- 左シフト 56
                if firstShift then
                    secondShift = true
                end
                firstShift = true
                hs.timer.doAfter(0.5, function()
                    cancelShift()
                end)
                if firstShift and secondShift then
                    cancelShift()
                    hs.eventtap.keyStroke({"cmd", "shift"}, "O")
                end
            else
                cancelShift()
            end
        end
    end
end
toggleMuteVideoTeamsEvent = hs.eventtap.new({hs.eventtap.event.types.flagsChanged}, toggleMuteVideoTeams)


hs.window.filter.new('zoom.us')
  :subscribe(hs.window.filter.windowFocused, function() toggleMuteVideoZoomEvent:start() end)
  :subscribe(hs.window.filter.windowUnfocused, function() toggleMuteVideoZoomEvent:stop() end)

hs.window.filter.new('Microsoft Teams')
  :subscribe(hs.window.filter.windowFocused, function() toggleMuteVideoTeamsEvent:start() end)
  :subscribe(hs.window.filter.windowUnfocused, function() toggleMuteVideoTeamsEvent:stop() end)
```

# 参考にしたページ
- https://mac-ra.com/alt-alt-terminal/
    - 2回押しで何かを実行する方法について参照しました．
- https://qiita.com/baba163/items/e2390c4529ec0448151d
    - Macのキーコードについて参照しました．
- https://qiita.com/yohm/items/ed2bbc8f7c4340a55695
    - 特定のアプリでのみ関数を有効にする方法について参考にしました．