Flutter实现语音转文字,让App听懂你的话!
语音输入、语音搜索、语音笔记……你的App离“听懂人话”只差这一篇!
语音转文字(Speech-to-Text,STT)正在成为移动应用的标配功能——用户懒得打字时直接说话,会议记录自动转成文字,甚至可以用语音控制App。
Flutter开发者如何快速实现这个功能?今天这篇文章,15分钟带你跑通语音转文字的全流程,支持Android/iOS双平台。
一、插件选型——哪个最适合你?
Flutter语音转文字插件有很多,我整理了几个主流选择:
|
|
|
|
|---|---|---|
flutter_speech_to_text |
|
通用场景,首选 |
ym_speech_to_text |
|
|
jm_baidu_stt_plugin |
|
|
flutter_google_stt |
|
|
|
|
|
|
我的推荐:flutter_speech_to_text。理由:
-
基于原生框架(iOS Speech/Android SpeechRecognizer),无需额外服务
-
实时返回结果,支持置信度
-
API简洁,文档完善
-
完全免费,无调用限制
二、环境配置(成败在此)
添加依赖
dependencies:flutter_speech_to_text: ^1.2.1 # 请使用最新版
执行 flutter pub get。
Android 配置
打开 android/app/src/main/AndroidManifest.xml,添加权限:
<uses-permissionandroid:name="android.permission.RECORD_AUDIO" /><uses-permissionandroid:name="android.permission.INTERNET" />
插件会自动处理运行时权限请求。
⚠️ 注意:如果你的 targetSdkVersion >= 30,还需要添加:
<queries><intent><actionandroid:name="android.speech.RecognitionService" /></intent></queries>
iOS 配置
打开 ios/Runner/Info.plist,添加两个描述:
<key>NSSpeechRecognitionUsageDescription</key><string>我们需要语音识别来将您的语音转为文字</string><key>NSMicrophoneUsageDescription</key><string>我们需要访问麦克风来录制您的语音</string>
注意:iOS模拟器可能不支持语音识别,建议在真机上测试。
三、极简实现:10行代码让App听懂人话
基础示例
import 'package:flutter/material.dart';import 'package:flutter_speech_to_text/flutter_speech_to_text.dart';class SpeechPage extends StatefulWidget {@override_SpeechPageState createState() => _SpeechPageState();}class _SpeechPageState extends State<SpeechPage> {final SpeechToText _speech = SpeechToText();String _transcript = '';bool _isListening = false;@overridevoid initState() {super.initState();_initSpeech();}// 初始化语音识别void _initSpeech() {_speech.onResult.listen((result) {setState(() {_transcript = result.transcript;});print('置信度: ${result.confidence}');});_speech.onError.listen((error) {print('错误: ${error.message}');setState(() => _isListening = false);});_speech.onEnd.listen((_) {setState(() => _isListening = false);});}// 开始监听Future<void> _startListening() async {final available = await _speech.isAvailable();if (!available) {print('语音识别不可用');return;}final hasPermission = await _speech.requestPermissions();if (!hasPermission) {print('权限被拒绝');return;}await _speech.start(); // 使用设备默认语言setState(() => _isListening = true);}// 停止监听Future<void> _stopListening() async {await _speech.stop();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('语音转文字')),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Container(padding: EdgeInsets.all(20),child: Text(_transcript.isEmpty ? '点击开始说话' : _transcript,style: TextStyle(fontSize: 18),),),ElevatedButton(onPressed: _isListening ? _stopListening : _startListening,child: Text(_isListening ? '停止' : '开始'),),],),),);}@overridevoid dispose() {_speech.dispose();super.dispose();}}
✅ 就这么简单! 核心代码不到20行。
四、进阶功能:让语音识别更智能
1. 指定识别语言
// 支持的语言代码[citation:1][citation:4]await _speech.start(language: 'en-US'); // 英语await _speech.start(language: 'zh-CN'); // 中文普通话await _speech.start(language: 'ja-JP'); // 日语await _speech.start(language: 'es-ES'); // 西班牙语
2. 区分实时结果和最终结果
_speech.onResult.listen((result) {if(result.isFinal) {// 这是最终结果,可以保存或提交print('最终结果: ${result.transcript}');} else {// 这是实时结果,用于界面预览print('实时结果: ${result.transcript}');}});
3. 获取置信度分数
_speech.onResult.listen((result) {print('识别文本: ${result.transcript}');print('置信度: ${result.confidence}'); // 0.0 - 1.0});
置信度可以用来判断识别结果是否可靠,低于0.5的可能需要用户确认。
4. 处理错误状态
_speech.onError.listen((error) {switch (error.errorCode) {case SpeechErrorCode.permissionDenied:// 引导用户开启权限break;case SpeechErrorCode.notAvailable:// 设备不支持语音识别break;case SpeechErrorCode.networkError:// 网络问题break;default:print('未知错误: ${error.message}');}});
5. 连续监听模式
默认情况下,语音识别会在用户停止说话后自动结束。如果需要连续监听,可以在 onEnd 中重新启动:
_speech.onEnd.listen((_) {setState(() => _isListening = false);// 如果需要连续监听,可以在这里再次调用 _startListening()// 注意:可能需要加一个短暂延迟,避免频繁启动});
五、避坑指南(必读)
❌ 语音识别不可用
-
Android:确保设备安装了Google App或语音识别服务
-
iOS:需要iOS 10+,且必须在真机测试
-
检查权限:确保已在Info.plist/Manifest.xml中配置
❌ 权限被拒
-
Android:运行时请求权限,引导用户去设置开启
-
iOS:权限弹窗只会出现一次,如果用户拒绝,需要引导用户去系统设置开启
❌ 识别结果不准确
-
确保麦克风清晰,环境安静
-
尝试指定正确的语言代码
-
注意:原生语音识别对特定领域词汇(如医学术语)可能不准确,这时可以考虑商业服务
❌ 识别中途停止
-
iOS和Android都有静音检测机制,长时间不说话会自动停止
-
可以通过
listen方法的pause参数控制
❌ Web平台支持
-
ym_speech_to_text支持Web,但需要浏览器支持Web Speech API -
不同浏览器支持程度不同,Chrome最好
六、完整示例:带界面的语音输入框
classVoiceInputFieldextendsStatefulWidget{final Function(String) onTextSubmitted;VoiceInputField({required this.onTextSubmitted});@override_VoiceInputFieldState createState() => _VoiceInputFieldState();}class_VoiceInputFieldStateextendsState<VoiceInputField> {final SpeechToText _speech = SpeechToText();final TextEditingController _controller = TextEditingController();bool _isListening = false;String _interimText = '';@overridevoid initState() {super.initState();_initSpeechListener();}void _initSpeechListener() {_speech.onResult.listen((result) {setState(() {if(result.isFinal) {// 最终结果,添加到输入框_controller.text = result.transcript;_interimText = '';} else {// 临时结果,用于预览_interimText = result.transcript;}});});_speech.onError.listen((error) {setState(() => _isListening = false);ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('语音识别出错: ${error.message}')),);});_speech.onEnd.listen((_) {setState(() => _isListening = false);});}Future<void> _toggleListening() async {if(_isListening) {await _speech.stop();} else {final available = await _speech.isAvailable();if(!available) {ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('语音识别不可用')),);return;}final hasPermission = await _speech.requestPermissions();if(!hasPermission) {ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('需要麦克风权限')),);return;}await _speech.start(language: 'zh-CN');setState(() => _isListening = true);}}@overrideWidget build(BuildContext context) {return Container(padding: EdgeInsets.all(16),child: Row(children: [Expanded(child: TextField(controller: _controller,decoration: InputDecoration(hintText: _interimText.isNotEmpty ? _interimText : '点击麦克风说话',border: OutlineInputBorder(),),),),IconButton(icon: Icon(_isListening ? Icons.mic : Icons.mic_none,color: _isListening ? Colors.red : null,),onPressed: _toggleListening,),IconButton(icon: Icon(Icons.send),onPressed: () {if(_controller.text.isNotEmpty) {widget.onTextSubmitted(_controller.text);_controller.clear();}},),],),);}@overridevoid dispose() {_speech.dispose();_controller.dispose();super.dispose();}}
这个组件可以嵌入任何需要语音输入的地方,用户点击麦克风开始说话,实时显示识别结果,点击发送提交文字。
七、进阶选择:商业服务 vs 原生
|
|
|
|
|---|---|---|
| 原生语音识别 |
|
|
| 百度语音 |
|
|
| Google Cloud STT |
|
|
| 腾讯云/GME |
|
|
建议:
-
通用场景:原生语音识别足够
-
垂直领域:考虑百度/Google/腾讯的定制模型
-
需要翻译:腾讯GME支持流式识别+翻译
八、总结
Flutter实现语音转文字,核心就是三步:
-
选择插件(推荐
flutter_speech_to_text) -
配置权限(AndroidManifest.xml + Info.plist)
-
调用API(
start→onResult→stop)
整个过程不超过30行核心代码,就能让你的App拥有“听懂人话”的能力。
无论你是要做语音输入框、语音笔记,还是语音助手,这套方案都能快速满足需求。
如果你有任何问题或实践经验,欢迎在评论区分享交流!
谢谢你读到最后。
若觉得尚可,恳请点赞、在看、转发分享。
山高水长,我们下期再会。
夜雨聆风
