# YX ASR - Flutter Speech-to-Text Plugin 基于 sherpa_onnx 的 Flutter 语音识别插件,提供完全离线的实时语音转文字功能。 ## 特性 - 🎤 **实时语音识别**: 边说边转换的实时转录功能 - 🔄 **切换录音**: 简单的开始/停止录音,带有视觉反馈 - 🌍 **多语言支持**: 支持中文、英文等多种语言 - 📱 **跨平台**: 支持 iOS 和 Android 平台 - 🎛️ **自定义UI**: 灵活的录音按钮组件,支持自定义外观 - 🔒 **权限管理**: 自动处理麦克风权限申请 - ⚡ **完全离线**: 基于 sherpa_onnx,无需网络连接 - 🎯 **高精度识别**: 使用先进的神经网络模型 - 🚀 **低延迟**: 实时处理,响应迅速 - 🔐 **隐私保护**: 语音数据不会上传到云端 ## 安装 在您的 `pubspec.yaml` 文件中添加依赖: ```yaml dependencies: yx_asr: ^1.0.0 ``` 然后运行: ```bash flutter pub get ``` ## 模型文件准备 由于使用 sherpa_onnx,您需要下载对应的模型文件: 1. **中文模型** (推荐) - 下载地址: https://github.com/k2-fsa/sherpa-onnx/releases/ - 模型名称: `sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20` - 解压到: `assets/models/zh-cn/` 2. **英文模型** - 模型名称: `sherpa-onnx-streaming-zipformer-en-2023-02-21` - 解压到: `assets/models/en-us/` 3. **模型文件结构** ``` assets/models/ ├── zh-cn/ │ ├── encoder.onnx │ ├── decoder.onnx │ ├── joiner.onnx │ └── tokens.txt └── en-us/ ├── encoder.onnx ├── decoder.onnx ├── joiner.onnx └── tokens.txt ``` ## 平台配置 ### Android 在 `android/app/src/main/AndroidManifest.xml` 中添加权限: ```xml ``` ### iOS 在 `ios/Runner/Info.plist` 中添加权限: ```xml NSMicrophoneUsageDescription 此应用需要麦克风权限来录制您的语音进行识别 ``` 注意:由于使用 sherpa_onnx 进行离线识别,不需要网络权限和语音识别权限。 ## 快速开始 ### 基本使用 ```dart import 'package:yx_asr/yx_asr.dart'; class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State { final YxAsr _speechToText = YxAsr(); String _recognizedText = ''; bool _isListening = false; @override void initState() { super.initState(); _initializeSpeechToText(); } Future _initializeSpeechToText() async { // 使用中文模型初始化 bool initialized = await _speechToText.initializeWithModel('assets/models/zh-cn'); if (initialized) { // 监听识别结果 _speechToText.onResult.listen((result) { setState(() { _recognizedText = result.recognizedWords; }); }); // 监听错误 _speechToText.onError.listen((error) { print('语音识别错误: ${error.errorMsg}'); }); // 监听状态变化 _speechToText.onListeningStatusChanged.listen((isListening) { setState(() { _isListening = isListening; }); }); } } Future _toggleRecording() async { if (_isListening) { await _speechToText.stopListening(); } else { await _speechToText.startListening( partialResults: true, // 启用部分结果 ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('语音识别')), body: Column( children: [ Text('识别结果: $_recognizedText'), ElevatedButton( onPressed: _toggleRecording, child: Text(_isListening ? '停止' : '开始'), ), ], ), ); } } ``` ### Using the Recording Button Widget The plugin includes a customizable `RecordingButton` widget: ```dart import 'package:yx_asr/yx_asr.dart'; RecordingButton( onResult: (result) { print('Result: ${result.recognizedWords}'); }, onError: (error) { print('Error: ${error.errorMsg}'); }, onListeningStatusChanged: (isListening) { print('Listening: $isListening'); }, localeId: 'en-US', partialResults: true, size: 80.0, tooltip: 'Tap to record', ) ``` ## API Reference ### YxAsr Class #### Methods - `Future initialize()` - Initialize the speech recognition service - `Future isAvailable()` - Check if speech recognition is available - `Future hasPermission()` - Check if microphone permission is granted - `Future requestPermission()` - Request microphone permission - `Future startListening({String localeId, bool partialResults, bool onDevice})` - Start listening - `Future stopListening()` - Stop listening and get final result - `Future cancel()` - Cancel current recognition session - `Future get isListening` - Check if currently listening #### Streams - `Stream onResult` - Stream of recognition results - `Stream onError` - Stream of recognition errors - `Stream onListeningStatusChanged` - Stream of listening status changes ### SpeechRecognitionResult ```dart class SpeechRecognitionResult { final String recognizedWords; // The recognized text final bool finalResult; // Whether this is a final result final double confidence; // Confidence level (0.0 to 1.0) final List alternatives; // Alternative recognition results } ``` ### SpeechRecognitionError ```dart class SpeechRecognitionError { final SpeechRecognitionErrorType errorType; // Type of error final String errorMsg; // Human-readable error message final String? errorCode; // Platform-specific error code } ``` ### RecordingButton Widget #### Properties - `onResult` - Callback for recognition results - `onError` - Callback for recognition errors - `onListeningStatusChanged` - Callback for status changes - `localeId` - Language locale (default: 'en-US') - `partialResults` - Enable partial results (default: true) - `onDevice` - Use on-device recognition on iOS (default: false) - `size` - Button size (default: 80.0) - `idleColor` - Button color when not recording - `recordingColor` - Button color when recording - `disabledColor` - Button color when disabled - `enabled` - Whether the button is enabled (default: true) - `tooltip` - Tooltip text ## Supported Languages The plugin supports multiple languages including: - English (en-US, en-GB) - Chinese (zh-CN, zh-TW) - Japanese (ja-JP) - Korean (ko-KR) - Spanish (es-ES) - French (fr-FR) - German (de-DE) - Italian (it-IT) ## Error Handling The plugin provides comprehensive error handling through the `SpeechRecognitionError` class: ```dart _speechToText.onError.listen((error) { switch (error.errorType) { case SpeechRecognitionErrorType.permissionDenied: // Handle permission denied break; case SpeechRecognitionErrorType.network: // Handle network errors break; case SpeechRecognitionErrorType.noSpeech: // Handle no speech detected break; // ... handle other error types } }); ``` ## Best Practices 1. **Always check permissions** before starting recognition 2. **Handle errors gracefully** to provide good user experience 3. **Use partial results** for real-time feedback 4. **Stop listening** when done to conserve battery 5. **Test on real devices** as speech recognition doesn't work well on simulators ## Example App Check out the `example/` directory for a comprehensive example app that demonstrates: - Real-time speech recognition - Multiple language support - Error handling - Recognition history - Customizable settings ## Contributing Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository. ## License This project is licensed under the MIT License - see the LICENSE file for details. ## Troubleshooting ### Common Issues 1. **Permission Denied Error** - Ensure microphone permissions are added to platform manifests - Call `requestPermission()` before starting recognition 2. **Speech Recognition Not Available** - Check if device supports speech recognition with `isAvailable()` - Ensure Google app is installed and updated on Android 3. **No Speech Detected** - Check microphone hardware - Ensure app has microphone permission - Try speaking louder or closer to the microphone 4. **Network Errors** - Check internet connectivity - Some platforms require network for speech recognition ### Testing - Speech recognition doesn't work well on simulators/emulators - Always test on real devices - Test in quiet environments for better accuracy ## Support For issues and feature requests, please use the GitHub issue tracker.