コンテンツへスキップ

はじめに

  1. パッケージをインストール

    Terminal window
    npm i @capgo/capacitor-speech-recognition
  2. ネイティブプロジェクトと同期

    Terminal window
    npx cap sync
  3. プラットフォームのパーミッションを設定(以下を参照)

アプリのInfo.plistファイルに以下のキーを追加します:

<key>NSSpeechRecognitionUsageDescription</key>
<string>音声を文字起こしするために音声認識へのアクセスが必要です</string>
<key>NSMicrophoneUsageDescription</key>
<string>文字起こし用の音声を録音するためにマイクへのアクセスが必要です</string>

プラグインは自動的に必要なRECORD_AUDIOパーミッションをAndroidManifest.xmlに追加します。追加の設定は必要ありません。

音声認識を使用する前に、デバイスで利用可能かどうかを確認します:

import { SpeechRecognition } from '@capgo/capacitor-speech-recognition';
const checkAvailability = async () => {
const { available } = await SpeechRecognition.available();
if (!available) {
console.warn('Speech recognition is not supported on this device');
return false;
}
return true;
};

認識を開始する前に必要なパーミッションをリクエストします:

const requestPermissions = async () => {
const { speechRecognition } = await SpeechRecognition.requestPermissions();
if (speechRecognition === 'granted') {
console.log('Permission granted');
return true;
} else {
console.log('Permission denied');
return false;
}
};

オプションの設定で音声のリスニングを開始します:

// 基本的な使用方法
await SpeechRecognition.start({
language: 'en-US',
maxResults: 3,
partialResults: true,
});
// すべてのオプションを使用
await SpeechRecognition.start({
language: 'en-US',
maxResults: 5,
prompt: 'Speak now...', // Androidのみ
popup: false, // Androidのみ
partialResults: true,
addPunctuation: true, // iOS 16+のみ
allowForSilence: 2000, // Androidのみ、ミリ秒
});

認識がアクティブな間、部分的な結果を購読します:

const partialListener = await SpeechRecognition.addListener(
'partialResults',
(event) => {
const transcription = event.matches?.[0];
console.log('Partial result:', transcription);
}
);
// 完了したらリスナーを削除することを忘れずに
await partialListener.remove();

リスニングを停止し、リソースをクリーンアップします:

await SpeechRecognition.stop();

プラグインの使用方法を示す完全な例:

import { SpeechRecognition } from '@capgo/capacitor-speech-recognition';
export class VoiceRecognitionService {
private partialListener: any = null;
private isListening = false;
async initialize(): Promise<boolean> {
// 利用可能性を確認
const { available } = await SpeechRecognition.available();
if (!available) {
throw new Error('Speech recognition not available');
}
// パーミッションをリクエスト
const { speechRecognition } = await SpeechRecognition.requestPermissions();
if (speechRecognition !== 'granted') {
throw new Error('Permission denied');
}
return true;
}
async startListening(
onPartialResult: (text: string) => void,
onFinalResult: (text: string) => void
): Promise<void> {
if (this.isListening) {
console.warn('Already listening');
return;
}
try {
// 部分結果リスナーをセットアップ
this.partialListener = await SpeechRecognition.addListener(
'partialResults',
(event) => {
const text = event.matches?.[0] || '';
onPartialResult(text);
}
);
// 認識を開始
const result = await SpeechRecognition.start({
language: 'en-US',
maxResults: 3,
partialResults: true,
addPunctuation: true,
});
this.isListening = true;
// partialResultsがfalseの場合の最終結果を処理
if (result.matches && result.matches.length > 0) {
onFinalResult(result.matches[0]);
}
} catch (error) {
console.error('Error starting speech recognition:', error);
throw error;
}
}
async stopListening(): Promise<void> {
if (!this.isListening) {
return;
}
try {
await SpeechRecognition.stop();
// リスナーをクリーンアップ
if (this.partialListener) {
await this.partialListener.remove();
this.partialListener = null;
}
this.isListening = false;
} catch (error) {
console.error('Error stopping speech recognition:', error);
throw error;
}
}
async getSupportedLanguages(): Promise<string[]> {
const { languages } = await SpeechRecognition.getSupportedLanguages();
return languages;
}
async checkListeningState(): Promise<boolean> {
const { listening } = await SpeechRecognition.isListening();
return listening;
}
}

現在のデバイスでネイティブ音声認識サービスが使用可能かどうかを確認します。

const result = await SpeechRecognition.available();
// 戻り値: { available: boolean }

音声のキャプチャと文字起こしを開始します。

interface SpeechRecognitionStartOptions {
language?: string; // ロケール識別子(例: 'en-US')
maxResults?: number; // 結果の最大数(デフォルト: 5)
prompt?: string; // Androidのみ: ダイアログプロンプト
popup?: boolean; // Androidのみ: システムダイアログを表示
partialResults?: boolean; // 部分結果をストリーム
addPunctuation?: boolean; // iOS 16+のみ: 句読点を追加
allowForSilence?: number; // Androidのみ: 無音タイムアウト(ミリ秒)
}
const result = await SpeechRecognition.start(options);
// 戻り値: { matches?: string[] }

リスニングを停止し、ネイティブリソースを解放します。

await SpeechRecognition.stop();

基礎となる認識エンジンでサポートされているロケールを取得します。

注意: Android 13+デバイスはこのリストを公開しなくなりました。その場合、languagesは空になります。

const result = await SpeechRecognition.getSupportedLanguages();
// 戻り値: { languages: string[] }

プラグインが積極的に音声をリスニングしているかどうかを返します。

const result = await SpeechRecognition.isListening();
// 戻り値: { listening: boolean }

現在のパーミッション状態を取得します。

const result = await SpeechRecognition.checkPermissions();
// 戻り値: { speechRecognition: 'prompt' | 'prompt-with-rationale' | 'granted' | 'denied' }

マイク+音声認識パーミッションをリクエストします。

const result = await SpeechRecognition.requestPermissions();
// 戻り値: { speechRecognition: 'prompt' | 'prompt-with-rationale' | 'granted' | 'denied' }

partialResultsが有効な間、部分的な文字起こし更新をリスニングします。

const listener = await SpeechRecognition.addListener(
'partialResults',
(event: { matches: string[] }) => {
console.log('Partial:', event.matches?.[0]);
}
);

セグメント化された認識結果をリスニングします。

const listener = await SpeechRecognition.addListener(
'segmentResults',
(event: { matches: string[] }) => {
console.log('Segment:', event.matches?.[0]);
}
);

セグメント化されたセッションの完了イベントをリスニングします。

const listener = await SpeechRecognition.addListener(
'endOfSegmentedSession',
() => {
console.log('Segmented session ended');
}
);

ネイティブリスニング状態の変更をリスニングします。

const listener = await SpeechRecognition.addListener(
'listeningState',
(event: { status: 'started' | 'stopped' }) => {
console.log('Listening state:', event.status);
}
);

登録されたすべてのリスナーを削除します。

await SpeechRecognition.removeAllListeners();
  1. 常に利用可能性とパーミッションを確認

    const { available } = await SpeechRecognition.available();
    if (!available) return;
    const { speechRecognition } = await SpeechRecognition.requestPermissions();
    if (speechRecognition !== 'granted') return;
  2. リスナーをクリーンアップ メモリリークを防ぐために、不要になったらリスナーを常に削除してください:

    await listener.remove();
    // または
    await SpeechRecognition.removeAllListeners();
  3. エラーを適切に処理

    try {
    await SpeechRecognition.start({ language: 'en-US' });
    } catch (error) {
    console.error('Speech recognition failed:', error);
    // ユーザーフレンドリーなエラーメッセージを表示
    }
  4. 視覚的なフィードバックを提供 listeningStateイベントを使用して、アプリがアクティブにリスニングしている時をユーザーに表示します。

  5. 異なるアクセントと言語でテスト 音声認識の精度は言語とアクセントによって異なります。ターゲットオーディエンスで徹底的にテストしてください。

  • iOS 10.0+が必要
  • ネイティブSFSpeechRecognizerを使用
  • iOS 16+で句読点をサポート
  • マイクと音声認識の両方のパーミッションが必要
  • デバイスの言語がリクエストされた言語と一致しない場合、認識が失敗する可能性があります
  • Android 6.0 (API 23)+が必要
  • SpeechRecognizer APIを使用
  • 設定可能な無音検出を伴うセグメント化されたセッションをサポート
  • Android 13+はサポートされている言語のリストを公開しません
  • 一部のデバイスではシステム認識UIが表示される場合があります
  • Web Speech API経由の限定サポート
  • すべてのブラウザが音声認識をサポートしているわけではありません
  • HTTPS接続が必要
  • ブラウザによって異なる動作をする可能性があります

パーミッションが拒否された場合、ユーザーをアプリ設定にガイドします:

const { speechRecognition } = await SpeechRecognition.checkPermissions();
if (speechRecognition === 'denied') {
// 設定でパーミッションを有効にする手順を表示
}
  • マイクが動作していることを確認
  • 静かな環境を確保
  • 言語コードがデバイスの機能と一致していることを確認
  • ネットワーク接続を確認(一部のプラットフォームで必要)
  • isListening()を使用して状態を確認
  • listeningStateイベントをリスニング
  • 必要に応じて自動再起動ロジックを実装