在进行前后端对接口时,发现前端使用微软Azure库用来语音转文本效率较低,本周我重写了前端的语音转文本接口,实现了实时转录,同时以字节流的形式显示在页面上,供前端参考。
项目采用flutter中的speech_to_text库,首先在我本地搭建了flutter运行环境,配置speech_to_text,在正常安装了flutter sdk后,在项目的pubspec.yaml里新建依赖:
dev_dependencies:
flutter_test:
sdk: flutter
speech_to_text: ^6.6.2
代码实现功能:
通过点击麦克风按钮说话,文本实现实时转录显示在屏幕上,并且该功能将在听到声音后的10分钟内保持激活状态。
在 initState
方法中初始化 SpeechToText
实例。
@override
void initState() {
super.initState();
_speech = stt.SpeechToText();
}
在 _listen
方法中启动语音识别,使用 Future.delayed
方法在 10 分钟后停止监听。
Future<void> _listen() async {
if (!_isListening) {
bool available = await _speech.initialize(
onStatus: (val) => print('onStatus: $val'),
);
if (available) {
setState(() => _isListening = true);
_speech.listen(
onResult: (val) {
setState(() {
_text = val.recognizedWords;
});
},
cancelOnError: false,
partialResults: true,
localeId: 'en_US',
);
Future.delayed(Duration(minutes: 10), _stopListening);
} else {
setState(() => _isListening = false);
}
}
}
在 build
方法中使用 Text
小部件显示转录结果,并在需要换行时自动换行。
Expanded(
child: SingleChildScrollView(
padding: const EdgeInsets.all(8.0),
child: Text(
_text,
style: TextStyle(fontSize: 24.0),
maxLines: null,
softWrap: true,
textAlign: TextAlign.center,
),
),
),
完整代码:
import 'package:flutter/material.dart';
import 'package:speech_to_text/speech_recognition_error.dart';
import 'package:speech_to_text/speech_recognition_result.dart';
import 'package:speech_to_text/speech_to_text.dart' as stt;
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late stt.SpeechToText _speech;
bool _isListening = false;
String _text = 'Press and hold the button to speak';
double _confidence = 1.0;
@override
void initState() {
super.initState();
_speech = stt.SpeechToText();
}
Future<void> _listen() async {
if (!_isListening) {
bool available = await _speech.initialize(
onStatus: (val) => print('onStatus: $val'),
);
if (available) {
setState(() => _isListening = true);
_speech.listen(
onResult: (val) {
setState(() {
_text = val.recognizedWords;
});
},
cancelOnError: false, // 不停止监听出错
partialResults: true, // 允许部分结果
localeId: 'en_US',
);
Future.delayed(Duration(minutes: 10), _stopListening);
} else {
setState(() => _isListening = false);
}
}
}
Future<void> _stopListening() async {
if (_isListening) {
setState(() => _isListening = false);
await _speech.stop();
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Speech to Text Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Confidence: ${(_confidence * 100.0).toStringAsFixed(1)}%',
),
SizedBox(height: 100),
Expanded(
// child: SingleChildScrollView(
// child: Padding(
// padding: const EdgeInsets.all(8.0),
child: Text(
_text,
style: TextStyle(fontSize: 24.0),
maxLines: 50,
softWrap: true,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
),
),
// ),
// ),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _isListening ? _stopListening : _listen,
child: Icon(_isListening ? Icons.stop : Icons.mic),
),
),
);
}
}