B-Teck!

お仕事からゲームまで幅広く

macOSで音声入力の言語をキーボードショートカットで切り替える

macOSの音声入力を使っていると、日本語と英語を切り替えたくなることがある。
しかし、OS標準でのキーボードショートカットは用意されておらず、システム設定から「キーボード → 音声入力 → 言語」と辿って変更する必要がある。

何か良い方法はないかと調べてみたところ、シェルスクリプトで音声入力の言語を直接変更できることがわかった。 これをAutomatorでキーボードショートカットに割り当てることで簡略化する。

仕組み

Keyboard Maestro Forum - Switch Dictation Languages が参考になった。

macOSの音声入力の言語設定は defaults コマンドで変更できる。具体的には、以下の設定キーを操作する:

  • DictationIMNetworkBasedLocaleIdentifier: 現在の言語
  • DictationIMPreferredLanguageIdentifiers: 優先言語のリスト

設定変更後、DictationIM プロセスを再起動すれば即座に反映される。

実装

スクリプトの作成

まず、言語を切り替えるスクリプトを作成する。

mkdir -p ~/bin
cat > ~/bin/dictation-lang-toggle.sh << 'EOF'
#!/bin/bash

prefs="com.apple.speech.recognition.AppleSpeechRecognition.prefs"
key_locale="DictationIMNetworkBasedLocaleIdentifier"
key_order="DictationIMPreferredLanguageIdentifiers"

langA="ja_JP"
langB="en_US"

get_lang() {
    defaults read "$prefs" "$key_locale" 2>/dev/null || echo "$langA"
}

set_lang() {
    local lang1="$1"
    local lang2="$2"
    defaults write "$prefs" "$key_locale" "$lang1"
    defaults write "$prefs" "$key_order" "($lang1, $lang2)"
    killall -HUP DictationIM 2>/dev/null
}

toggle_lang() {
    local current=$(get_lang)
    if [ "$current" = "$langA" ]; then
        set_lang "$langB" "$langA"
    else
        set_lang "$langA" "$langB"
    fi
}

case "$1" in
    -g) get_lang ;;
    -t) toggle_lang ;;
    *) echo "Usage: $0 [-g|-t]" ;;
esac
EOF

chmod +x ~/bin/dictation-lang-toggle.sh

動作確認

スクリプトが正しく動作するか確認する。

# 現在の言語を確認
~/bin/dictation-lang-toggle.sh -g

# 切り替え
~/bin/dictation-lang-toggle.sh -t

# 再度確認
~/bin/dictation-lang-toggle.sh -g

初回は ja_JP、トグル後は en_US と表示されれば成功。

キーボードショートカットの設定

Automatorで、スクリプトをキーボードショートカットから実行できるようにする。

  1. Automator.app を起動
  2. 「クイックアクション」を選択
  3. 「シェルスクリプトを実行」アクションを追加
  4. スクリプト内容: ~/bin/dictation-lang-toggle.sh -t
  5. 名前を付けて保存(例: "Toggle Dictation Language")
  6. システム設定 → キーボード → キーボードショートカット → サービス
  7. "Toggle Dictation Language" にショートカットを割り当て

使い方

設定したキーボードショートカットを押すだけで、音声入力の言語が日本語⇔英語で切り替わる。再度音声入力を起動すれば、選択した言語で入力できる。

カスタマイズ

スクリプト内の langAlangB を変更すれば、他の言語ペアにも対応できる。

例: 韓国語⇔英語

langA="ko_KR"
langB="en_US"

制限事項: 音声入力の自動起動について

当初は、言語切り替え後に再度音声入力を起動することも試みた。 AppleScriptで 音声入力起動キーの押下をシミュレートすれば良いと考えたが、以下のエラーで動作しなかった:

osascript is not allowed to send keystrokes

これはmacOSのアクセシビリティ権限の制限によって、osascriptからのキーストローク送信が許可されていないことにより発生するものだった。
システム設定でアクセシビリティ権限を付与すれば解決する可能性もあるが、セキュリティ上の懸念もあり、今回は見送った。 ただし、言語切り替えだけでも十分に便利だったので、実用上は問題を感じていない。