303 lines
6.9 KiB
Markdown
303 lines
6.9 KiB
Markdown
# YX ASR - Sherpa ONNX 使用指南
|
|
|
|
本文档详细说明如何使用基于 sherpa_onnx 的 YX ASR 语音识别插件。
|
|
|
|
## 🎯 核心优势
|
|
|
|
### 与原生识别的对比
|
|
|
|
| 特性 | 原生识别 | sherpa_onnx |
|
|
|------|----------|-------------|
|
|
| **网络依赖** | 需要网络 | 完全离线 |
|
|
| **隐私保护** | 数据上传云端 | 本地处理 |
|
|
| **识别一致性** | 平台差异 | 跨平台一致 |
|
|
| **自定义能力** | 受限 | 高度可定制 |
|
|
| **包体积** | 无增加 | +40-60MB |
|
|
| **识别精度** | 高(云端) | 高(本地模型) |
|
|
|
|
## 📦 安装配置
|
|
|
|
### 1. 添加依赖
|
|
|
|
```yaml
|
|
dependencies:
|
|
yx_asr: ^1.0.0
|
|
```
|
|
|
|
### 2. 下载模型文件
|
|
|
|
从 [sherpa-onnx releases](https://github.com/k2-fsa/sherpa-onnx/releases/) 下载模型:
|
|
|
|
**推荐模型:**
|
|
- **中英双语**: `sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20`
|
|
- **纯中文**: `sherpa-onnx-streaming-zipformer-zh-2023-02-13`
|
|
- **纯英文**: `sherpa-onnx-streaming-zipformer-en-2023-02-21`
|
|
|
|
### 3. 模型文件结构
|
|
|
|
```
|
|
assets/models/
|
|
├── zh-cn/ # 中文模型
|
|
│ ├── encoder.onnx # 编码器
|
|
│ ├── decoder.onnx # 解码器
|
|
│ ├── joiner.onnx # 连接器
|
|
│ └── tokens.txt # 词汇表
|
|
├── en-us/ # 英文模型
|
|
│ ├── encoder.onnx
|
|
│ ├── decoder.onnx
|
|
│ ├── joiner.onnx
|
|
│ └── tokens.txt
|
|
└── bilingual/ # 双语模型
|
|
├── encoder.onnx
|
|
├── decoder.onnx
|
|
├── joiner.onnx
|
|
└── tokens.txt
|
|
```
|
|
|
|
## 🚀 使用方法
|
|
|
|
### 基本使用
|
|
|
|
```dart
|
|
import 'package:yx_asr/yx_asr.dart';
|
|
|
|
class SpeechRecognitionPage extends StatefulWidget {
|
|
@override
|
|
_SpeechRecognitionPageState createState() => _SpeechRecognitionPageState();
|
|
}
|
|
|
|
class _SpeechRecognitionPageState extends State<SpeechRecognitionPage> {
|
|
final YxAsr _asr = YxAsr();
|
|
String _result = '';
|
|
bool _isListening = false;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_initializeASR();
|
|
}
|
|
|
|
Future<void> _initializeASR() async {
|
|
// 初始化中文模型
|
|
final success = await _asr.initializeWithModel('assets/models/zh-cn');
|
|
|
|
if (success) {
|
|
// 监听识别结果
|
|
_asr.onResult.listen((result) {
|
|
setState(() {
|
|
_result = result.recognizedWords;
|
|
});
|
|
});
|
|
|
|
// 监听错误
|
|
_asr.onError.listen((error) {
|
|
print('错误: ${error.errorMsg}');
|
|
});
|
|
|
|
// 监听状态
|
|
_asr.onListeningStatusChanged.listen((isListening) {
|
|
setState(() {
|
|
_isListening = isListening;
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
Future<void> _toggleRecording() async {
|
|
if (_isListening) {
|
|
await _asr.stopListening();
|
|
} else {
|
|
await _asr.startListening(partialResults: true);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(title: Text('语音识别')),
|
|
body: Column(
|
|
children: [
|
|
Text('识别结果: $_result'),
|
|
ElevatedButton(
|
|
onPressed: _toggleRecording,
|
|
child: Text(_isListening ? '停止录音' : '开始录音'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
```
|
|
|
|
### 使用录音按钮组件
|
|
|
|
```dart
|
|
RecordingButton(
|
|
onResult: (result) {
|
|
print('识别结果: ${result.recognizedWords}');
|
|
print('是否最终结果: ${result.finalResult}');
|
|
print('置信度: ${result.confidence}');
|
|
},
|
|
onError: (error) {
|
|
print('错误: ${error.errorMsg}');
|
|
},
|
|
localeId: 'zh-CN', // 会自动选择对应模型
|
|
size: 80.0,
|
|
recordingColor: Colors.red,
|
|
idleColor: Colors.blue,
|
|
tooltip: '点击开始录音',
|
|
)
|
|
```
|
|
|
|
### 多语言支持
|
|
|
|
```dart
|
|
class MultiLanguageASR {
|
|
final YxAsr _asr = YxAsr();
|
|
String _currentLanguage = 'zh-cn';
|
|
|
|
Future<void> switchLanguage(String language) async {
|
|
String modelPath;
|
|
switch (language) {
|
|
case 'zh-cn':
|
|
modelPath = 'assets/models/zh-cn';
|
|
break;
|
|
case 'en-us':
|
|
modelPath = 'assets/models/en-us';
|
|
break;
|
|
case 'bilingual':
|
|
modelPath = 'assets/models/bilingual';
|
|
break;
|
|
default:
|
|
modelPath = 'assets/models/zh-cn';
|
|
}
|
|
|
|
final success = await _asr.initializeWithModel(modelPath);
|
|
if (success) {
|
|
_currentLanguage = language;
|
|
print('切换到 $language 模型成功');
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## ⚙️ 高级配置
|
|
|
|
### 自定义采样率
|
|
|
|
```dart
|
|
await _asr.initializeWithModel(
|
|
'assets/models/zh-cn',
|
|
sampleRate: 16000, // 默认 16kHz
|
|
);
|
|
|
|
await _asr.startListening(
|
|
partialResults: true,
|
|
sampleRate: 16000,
|
|
);
|
|
```
|
|
|
|
### 错误处理
|
|
|
|
```dart
|
|
_asr.onError.listen((error) {
|
|
switch (error.errorType) {
|
|
case SpeechRecognitionErrorType.permissionDenied:
|
|
// 处理权限被拒绝
|
|
showDialog(context: context, builder: (context) =>
|
|
AlertDialog(title: Text('需要麦克风权限')));
|
|
break;
|
|
case SpeechRecognitionErrorType.service:
|
|
// 处理服务错误
|
|
print('服务错误: ${error.errorMsg}');
|
|
break;
|
|
case SpeechRecognitionErrorType.audio:
|
|
// 处理音频错误
|
|
print('音频错误: ${error.errorMsg}');
|
|
break;
|
|
default:
|
|
print('未知错误: ${error.errorMsg}');
|
|
}
|
|
});
|
|
```
|
|
|
|
## 🔧 性能优化
|
|
|
|
### 1. 模型选择
|
|
- **小型应用**: 使用单语言模型 (~40MB)
|
|
- **多语言应用**: 使用双语模型 (~60MB)
|
|
- **专业应用**: 训练自定义模型
|
|
|
|
### 2. 内存管理
|
|
```dart
|
|
@override
|
|
void dispose() {
|
|
_asr.dispose(); // 释放资源
|
|
super.dispose();
|
|
}
|
|
```
|
|
|
|
### 3. 批量处理
|
|
```dart
|
|
// 对于长时间录音,定期获取结果
|
|
Timer.periodic(Duration(seconds: 5), (timer) {
|
|
if (_asr.isListening) {
|
|
// 可以在这里保存中间结果
|
|
}
|
|
});
|
|
```
|
|
|
|
## 📱 平台特定配置
|
|
|
|
### Android
|
|
```xml
|
|
<!-- android/app/src/main/AndroidManifest.xml -->
|
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
|
```
|
|
|
|
### iOS
|
|
```xml
|
|
<!-- ios/Runner/Info.plist -->
|
|
<key>NSMicrophoneUsageDescription</key>
|
|
<string>此应用需要麦克风权限进行语音识别</string>
|
|
```
|
|
|
|
## 🐛 常见问题
|
|
|
|
### Q: 模型文件太大怎么办?
|
|
A: 可以考虑:
|
|
1. 使用模型压缩
|
|
2. 动态下载模型
|
|
3. 只包含必要的语言模型
|
|
|
|
### Q: 识别精度不够怎么办?
|
|
A: 可以尝试:
|
|
1. 使用更新的模型
|
|
2. 调整音频参数
|
|
3. 在安静环境中测试
|
|
4. 训练自定义模型
|
|
|
|
### Q: 如何实现实时显示?
|
|
A: 启用 `partialResults: true` 并监听结果流:
|
|
```dart
|
|
_asr.onResult.listen((result) {
|
|
if (result.finalResult) {
|
|
// 最终结果
|
|
finalText = result.recognizedWords;
|
|
} else {
|
|
// 实时结果
|
|
partialText = result.recognizedWords;
|
|
}
|
|
});
|
|
```
|
|
|
|
## 📚 参考资源
|
|
|
|
- [sherpa-onnx 官方文档](https://github.com/k2-fsa/sherpa-onnx)
|
|
- [模型下载地址](https://github.com/k2-fsa/sherpa-onnx/releases/)
|
|
- [Flutter 音频处理](https://pub.dev/packages/record)
|
|
|
|
## 🤝 技术支持
|
|
|
|
如有问题,请提交 Issue 或参考示例代码。
|