useSpeechRecognition
用於 React 的響應式語音識別 API
支持實時語音識別、可配置选项、跨瀏覽器兼容性和 TypeScript 支持。非常适合语音控制应用程序、听写功能和无障碍增强。
基本用法
即時編輯器
function Demo() { const { isSupported, isListening, isFinal, result, error, start, stop, toggle, } = useSpeechRecognition(); if (!isSupported) { return <div>此瀏覽器不支持語音識別</div>; } return ( <div> <div style={{ marginBottom: '20px' }}> <p><strong>狀態:</strong> {isListening ? '正在監聽...' : '已停止'}</p> <p><strong>结果:</strong> {result || '未檢測到语音'}</p> <p><strong>最终结果:</strong> {isFinal ? '是' : '否'}</p> {error && <p style={{ color: 'var(--ifm-color-danger)' }}><strong>错误:</strong> {error.error}</p>} </div> <div style={{ display: 'flex', gap: '10px' }}> <button onClick={start} disabled={isListening}> 开始 </button> <button onClick={stop} disabled={!isListening}> 停止 </button> <button onClick={() => toggle()}> 切换 </button> </div> </div> ); }
結果
狀態: 已停止
结果: 未檢測到语音
最终结果: 否
自定义配置选项
即時編輯器
function Demo() { const { isSupported, isListening, result, start, stop, } = useSpeechRecognition({ continuous: true, interimResults: true, lang: 'zh-CN', maxAlternatives: 1, }); if (!isSupported) { return <div>不支持語音識別</div>; } return ( <div> <div style={{ marginBottom: '20px' }}> <p><strong>识别结果:</strong></p> <div style={{ padding: '10px', border: '1px solid var(--ifm-color-emphasis-200)', borderRadius: '4px', minHeight: '60px', backgroundColor: 'var(--ifm-background-surface-color)', color: 'var(--ifm-color-content)' }}> {result || '开始说话...'} </div> </div> <div style={{ display: 'flex', gap: '10px' }}> <button onClick={start} disabled={isListening} style={{ backgroundColor: isListening ? 'var(--ifm-color-emphasis-300)' : 'var(--ifm-color-primary)', color: 'var(--ifm-color-white)', border: 'none', padding: '8px 16px', borderRadius: '4px', cursor: 'pointer' }} > {isListening ? '正在監聽...' : '开始识别'} </button> <button onClick={stop} disabled={!isListening} style={{ backgroundColor: !isListening ? 'var(--ifm-color-emphasis-300)' : 'var(--ifm-color-danger)', color: 'var(--ifm-color-white)', border: 'none', padding: '8px 16px', borderRadius: '4px', cursor: 'pointer' }} > 停止 </button> </div> </div> ); }
結果
识别结果:
开始说话...
多语言支持
即時編輯器
function Demo() { const [selectedLang, setSelectedLang] = React.useState('zh-CN'); const { isSupported, isListening, result, start, stop, } = useSpeechRecognition({ lang: selectedLang, continuous: true, interimResults: true, }); const languages = [ { code: 'zh-CN', name: '中文 (简体)' }, { code: 'en-US', name: '英語 (美國)' }, { code: 'ja-JP', name: '日本語' }, { code: 'ko-KR', name: '한국어' }, { code: 'es-ES', name: 'Español' }, { code: 'fr-FR', name: 'Français' }, ]; if (!isSupported) { return <div>不支持語音識別</div>; } return ( <div> <div style={{ marginBottom: '20px' }}> <label> <strong>语言:</strong> <select value={selectedLang} onChange={(e) => setSelectedLang(e.target.value)} style={{ marginLeft: '10px', padding: '4px', backgroundColor: 'var(--ifm-background-color)', color: 'var(--ifm-color-content)', border: '1px solid var(--ifm-color-emphasis-300)', borderRadius: '4px' }} disabled={isListening} > {languages.map(lang => ( <option key={lang.code} value={lang.code}> {lang.name} </option> ))} </select> </label> </div> <div style={{ marginBottom: '20px' }}> <div style={{ padding: '10px', border: '1px solid var(--ifm-color-emphasis-200)', borderRadius: '4px', minHeight: '80px', backgroundColor: 'var(--ifm-background-surface-color)', color: 'var(--ifm-color-content)' }}> {result || `开始用${languages.find(l => l.code === selectedLang)?.name}说话...`} </div> </div> <div style={{ display: 'flex', gap: '10px' }}> <button onClick={() => start({ lang: selectedLang })} disabled={isListening}> 开始 ({selectedLang}) </button> <button onClick={stop} disabled={!isListening}> 停止 </button> </div> </div> ); }
結果
开始用中文 (简体)说话...
动态语言和模式切换
即時編輯器
function DynamicOptionsDemo() { const { isSupported, isListening, result, start, stop, } = useSpeechRecognition(); const quickOptions = [ { language: 'zh-CN', name: '中文 (连续)', flag: '🇨🇳', continuous: true, color: 'var(--ifm-color-primary)' }, { language: 'zh-CN', name: '中文 (单次)', flag: '🇨🇳', continuous: false, color: 'var(--ifm-color-secondary)' }, { language: 'en-US', name: '英語 (連續)', flag: '🇺🇸', continuous: true, color: 'var(--ifm-color-success)' }, { language: 'en-US', name: '英語 (單次)', flag: '🇺🇸', continuous: false, color: 'var(--ifm-color-warning)' }, ]; if (!isSupported) { return <div>不支持語音識別</div>; } return ( <div> <div style={{ marginBottom: '20px' }}> <p><strong>快速开始不同语言和模式:</strong></p> <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: '10px', marginBottom: '16px' }}> {quickOptions.map((option, index) => ( <button key={index} onClick={() => start({ lang: option.language, continuous: option.continuous })} disabled={isListening} style={{ padding: '12px 8px', border: '1px solid var(--ifm-color-emphasis-300)', backgroundColor: isListening ? 'var(--ifm-color-emphasis-300)' : option.color, color: 'var(--ifm-color-white)', borderRadius: '6px', cursor: isListening ? 'not-allowed' : 'pointer', fontSize: '13px', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '4px', textAlign: 'center' }} > <span style={{ fontSize: '18px' }}>{option.flag}</span> <span>{option.name}</span> </button> ))} </div> {isListening && ( <button onClick={stop} style={{ padding: '8px 16px', border: 'none', backgroundColor: 'var(--ifm-color-danger)', color: 'var(--ifm-color-white)', borderRadius: '4px', cursor: 'pointer', width: '100%' }} > 停止監聽 </button> )} </div> <div style={{ padding: '16px', border: '1px solid var(--ifm-color-emphasis-200)', borderRadius: '6px', minHeight: '80px', backgroundColor: 'var(--ifm-background-surface-color)', color: 'var(--ifm-color-content)' }}> <strong>结果:</strong> {result || '点击任意按钮开始说话...'} </div> <div style={{ marginTop: '12px', padding: '12px', backgroundColor: 'var(--ifm-background-surface-color)', borderRadius: '4px', fontSize: '14px', color: 'var(--ifm-color-content-secondary)' }}> <strong>提示:</strong> 连续模式会持续監聽直到您停止, 而单次模式在檢測到一个短语后会自动停止。 </div> </div> ); }
結果
快速开始不同语言和模式:
结果: 点击任意按钮开始说话...
提示: 连续模式会持续監聽直到您停止, 而单次模式在檢測到一个短语后会自动停止。
注意事项
- 需要 HTTPS: 此 API 在生产环境中需要 HTTPS
- 用户交互: 某些瀏覽器可能需要用户交互才能开始語音識別
- 权限: 瀏覽器会在首次使用时请求麦克风权限
- 隐私: 语音数据可能会发送到云服务进行處理
- 准确性: 结果可能因麦克风质量、环境噪音和口音而有所不同
常见用例
- 语音命令: 实现语音控制界面
- 听写: 为表单添加语音转文本功能
- 无障碍: 为行动不便的用户提供语音输入
- 搜索: 启用语音搜索功能
- 笔记: 創建语音备忘录应用程序
API
UseSpeechRecognitionOptions
| 參數名 | 描述 | 類型 | 預設值 |
|---|---|---|---|
| continuous | 控制是否为每次识别返回连续结果,或仅返回单个结果 | boolean | - |
| interimResults | 控制是否应返回临时结果(true)或不返回(false)。临时结果是尚未最终确定的结果 | boolean | - |
| lang | 语音识别的语言 | string | - |
| maxAlternatives | 表示每个结果返回的最大备选项数量的数字 | number | - |
useSpeechRecognition
Returns
{ readonly isSupported: boolean; readonly isListening: boolean; readonly isFinal: boolean; readonly recognition: SpeechRecognition | undefined; readonly result: string; readonly error: SpeechRecognitionErrorEvent | undefined; readonly toggle: (value?: boolean | undefined, startOptions?: Partial<UseSpeechRecognitionOptions> | undefined) => void; readonly start: (startOptions?: Partial<UseSpeechRecognitionOptions> | undefined) => void; readonly stop: () => void; }: 包含以下元素的對象:
- 是否支持語音識別。
- 是否正在監聽。
- 識別結果是否為最終結果。
- SpeechRecognition 實例。
- 識別結果文本。
- 錯誤信息。
- 切換監聽狀態的函數。
- 開始監聽的函數。
- 停止監聽的函數。
Arguments
| 參數名 | 描述 | 類型 | 預設值 |
|---|---|---|---|
| options | 可选的语音识别配置参数 | UseSpeechRecognitionOptions | undefined | - |