6.9 KiB
6.9 KiB
YX ASR - Sherpa ONNX 使用指南
本文档详细说明如何使用基于 sherpa_onnx 的 YX ASR 语音识别插件。
🎯 核心优势
与原生识别的对比
| 特性 | 原生识别 | sherpa_onnx |
|---|---|---|
| 网络依赖 | 需要网络 | 完全离线 |
| 隐私保护 | 数据上传云端 | 本地处理 |
| 识别一致性 | 平台差异 | 跨平台一致 |
| 自定义能力 | 受限 | 高度可定制 |
| 包体积 | 无增加 | +40-60MB |
| 识别精度 | 高(云端) | 高(本地模型) |
📦 安装配置
1. 添加依赖
dependencies:
yx_asr: ^1.0.0
2. 下载模型文件
从 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
🚀 使用方法
基本使用
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 ? '停止录音' : '开始录音'),
),
],
),
);
}
}
使用录音按钮组件
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: '点击开始录音',
)
多语言支持
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 模型成功');
}
}
}
⚙️ 高级配置
自定义采样率
await _asr.initializeWithModel(
'assets/models/zh-cn',
sampleRate: 16000, // 默认 16kHz
);
await _asr.startListening(
partialResults: true,
sampleRate: 16000,
);
错误处理
_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. 内存管理
@override
void dispose() {
_asr.dispose(); // 释放资源
super.dispose();
}
3. 批量处理
// 对于长时间录音,定期获取结果
Timer.periodic(Duration(seconds: 5), (timer) {
if (_asr.isListening) {
// 可以在这里保存中间结果
}
});
📱 平台特定配置
Android
<!-- android/app/src/main/AndroidManifest.xml -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
iOS
<!-- ios/Runner/Info.plist -->
<key>NSMicrophoneUsageDescription</key>
<string>此应用需要麦克风权限进行语音识别</string>
🐛 常见问题
Q: 模型文件太大怎么办?
A: 可以考虑:
- 使用模型压缩
- 动态下载模型
- 只包含必要的语言模型
Q: 识别精度不够怎么办?
A: 可以尝试:
- 使用更新的模型
- 调整音频参数
- 在安静环境中测试
- 训练自定义模型
Q: 如何实现实时显示?
A: 启用 partialResults: true 并监听结果流:
_asr.onResult.listen((result) {
if (result.finalResult) {
// 最终结果
finalText = result.recognizedWords;
} else {
// 实时结果
partialText = result.recognizedWords;
}
});
📚 参考资源
🤝 技术支持
如有问题,请提交 Issue 或参考示例代码。