試してみたブログ

AI関連・iPhone/Pixelなどのガジェット・音声入力・サーマルプリンタなど興味をある事をどんどん試してみた際の記録

大富豪の記録PWAに音声入力モードをつける

背景

tameshitemita.blog

  • 上記記事で大富豪のカード記録をつけるPWAを作った

daifugo.netlify.app

  • タップするのもちょっと大変なので音声入力機能をつけたい

試してみた

  • PWAでWeb Speech APIを使えばいけそう
  • ブラウザネイティブの音声認識APIがある
  • 日本語認識、リアルタイム結果を取得、連続認識モードもある
  • firefox以外であれば動きそう
  • まずはClaudeと仕様についての壁打ち実施
  • 決まった仕様
## 全体概要

- 目的  
  - 既存の「手動入力で大富豪のカード枚数をカウントする PWA」に、音声入力でもカウントできる機能を統合する。 [developer.mozilla](https://developer.mozilla.org/ja/docs/Web/API/Web_Speech_API)
- 対象環境  
  - 主に Chrome 系ブラウザ(デスクトップ / Android)。  
  - iOS PWA では Web Speech API が動作しない・不安定なため、音声機能は「対応外または制限付き」とする。 [zenn](https://zenn.dev/meimei_kr/scraps/6aef854096d199)

## 音声認識まわりの仕様

- 利用 API  
  - Web Speech API の `SpeechRecognition`(`window.SpeechRecognition || webkitSpeechRecognition`)。 [developer.mozilla](https://developer.mozilla.org/ja/docs/Web/API/Web_Speech_API)  
- 設定  
  - `lang = 'ja-JP'`  
  - `interimResults = true`:途中結果をリアルタイム表示。 [developer.mozilla](https://developer.mozilla.org/ja/docs/Web/API/SpeechRecognition/interimResults)
  - `continuous = true`(PC)/モバイルは安定性を見て再起動ループ方式も検討。 [stackoverflow](https://stackoverflow.com/questions/29996350/speech-recognition-run-continuously)
- マイク権限  
  - 初回利用時にブラウザのマイク許可ダイアログが表示される。HTTPS 必須。 [developer.mozilla](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)

## UI / UX 仕様

- 画面構成(既存カウンタに追加)  
  - 「音声入力開始 / 停止」トグルボタン。  
  - 「リアルタイム文字表示エリア」:`interimResults` を常時表示。確定分はログに移動。 [developer.mozilla](https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition/interimResults)
  - 既存のカードカウント一覧(例: 各数字・絵札ごとの枚数)は共通コンポーネントを使用し、手動入力と音声入力の両方から更新する。  

- 音声入力のフロー  
  1. ユーザーが「音声入力開始」ボタンを押す。  
  2. マイク権限が許可されていなければブラウザが確認ダイアログを表示。許可後に認識開始。 [developer.mozilla](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)
  3. 認識結果の `isFinal = false` の間は、リアルタイムテキストとして画面に薄色で表示。  
  4. `isFinal = true` になったテキストをパーサに渡してカードカウントを更新し、ログに追記。  

## 音声→カードカウントの仕様

- 想定する発話例  
  - 「さんがにまい」  
  - 「よん一枚」  
  - 「さん二枚 よん一枚」  
  - 「じぇい二枚」 など  
- パースルール(例)  
  - 数値・ランクのマッピング  
    - 「いち」「ワン」「1」→ 1  
    - 「に」「ツー」「2」→ 2  
    - 「さん」「スリー」「3」→ 3  
    - 「よん」「フォー」「4」→ 4  
    - …  
    - 「じぇい」「ジェイ」「J」→ J  
    - 「きんぐ」「キング」「K」→ K など  
  - 枚数のマッピング  
    - 「いちまい」「1枚」→ 1  
    - 「にまい」「2枚」→ 2  
    - 「さんまい」「3枚」→ 3 …  
  - 文中から「[ランク][枚数]」の組をすべて抽出し、該当ランクのカウンタを加算する。  
  - 誤認識が多い言い回しは、ログ表示&手動修正 UI でリカバリ。  

## PWA / 既存アプリとの統合仕様

- PWA 部分  
  - 既存の manifest.json と Service Worker 構成はそのまま利用。  
  - 音声認識はオンライン前提(Web Speech API がクラウド認識に依存するため)。オフライン時は「音声入力ボタンを無効化」+メッセージ表示。 [toyama-reha.or](https://www.toyama-reha.or.jp/techno/engineering/enchant/enchant11.html)

- 状態管理  
  - カードカウントの状態は既存と同じストア(例: React state, Zustand, Vuex など)で一元管理。  
  - 手動入力・音声入力どちらからでも同じアクション(`incrementCount(rank, n)` のような関数)を呼ぶことで、一貫した挙動にする。  

- エラー・フォールバック  
  - Web Speech API 非対応ブラウザでは、  
    - 音声ボタンを非表示または「このブラウザでは音声入力は利用できません」と表示。 [zenn](https://zenn.dev/meimei_kr/scraps/6aef854096d199)
  - 認識中に `onerror` / `onend` が頻発する環境では、  
    - 自動再スタート(`onend` 内で `start()`)を試みつつ、一定回数失敗したらユーザーへメッセージを表示。 [stackoverflow](https://stackoverflow.com/questions/29996350/speech-recognition-run-continuously)

完成

  • 所感としては、8割ぐらいの精度では動作する
  • 入力が楽になったかと言われれば、ちょっと怪しい、、
  • 言うこととちゃんと動作したかに精一杯になって、ゲームの進行についていけなくなる事がある
  • 今の所は、メインカードのみを記録したい場合は、タップモードでやる
  • 全部記録したい場合は、音声で頑張ってみるぐらいになりそう・・・