Flutter文本转语音插件text_to_speech的使用
Flutter文本转语音插件text_to_speech的使用
Text To Speech
一个Flutter插件,提供TTS (Text-To-Speech) 服务。这个插件旨在提供iOS、Android、Web和macOS TTS API的大部分功能。
Getting Started
要使用此插件,在您的pubspec.yaml
文件中添加text_to_speech
作为依赖项:
dependencies:
text_to_speech: ^0.2.3
Installation
Android
- 最低SDK版本:
21
- 针对SDK 30(Android 11)的应用程序需要在Android清单文件中的
queries
元素中声明TextToSpeech.Engine.INTENT_ACTION_TTS_SERVICE
(参见Android文档)。
<queries>
<intent>
<action android:name="android.intent.action.TTS_SERVICE" />
</intent>
</queries>
iOS & macOS
- iOS最低版本:
7.0
- macOS最低版本:
10.14
(参见Apple文档)
Features
Feature | Android | iOS | Web | macOS |
---|---|---|---|---|
speak | ✅ | ✅ | ✅ | ✅ |
stop | ✅ | ✅ | ✅ | ✅ |
pause | - | ✅ | ✅ | ✅ |
resume | - | ✅ | ✅ | ✅ |
set volume | ✅ | ✅ | ✅ | ✅ |
set rate | ✅ | ✅ | ✅ | ✅ |
set pitch | ✅ | ✅ | ✅ | ✅ |
set language | ✅ | ✅ | ✅ | ✅ |
get language | ✅ | ✅ | ✅ | ✅ |
get voice | ✅ | ✅ | ✅ | ✅ |
Usages
首先,在代码中导入依赖项:
import 'package:text_to_speech/text_to_speech.dart';
然后,创建TextToSpeech
类的实例:
TextToSpeech tts = TextToSpeech();
Speak
String text = "Hello, Good Morning!";
tts.speak(text);
Set Volume
音量范围:0-1
,其中0是静音,1是最大音量(默认行为)。
double volume = 1.0;
tts.setVolume(volume);
Set Rate
速率范围:0-2
。
1.0是正常且默认的语速。较低的值会减慢语速(0.5是正常语速的一半)。较高的值会加快语速(2.0是正常语速的两倍)。
double rate = 1.0;
tts.setRate(rate);
Set Pitch
音调范围:0-2
。
1.0是正常音调,较低的值会降低合成声音的音调,较高的值会提高音调。
double pitch = 1.0;
tts.setPitch(pitch);
Set Language
接受特定语言的locale标签名,例如’en-US’。您可以使用getLanguage
函数检索支持的语言列表。
String language = 'en-US';
tts.setLanguage(language);
Get Languages
提供以locale标签格式表示的支持语言代码列表,例如’en-US’。您可以获取特定语言代码的显示名称
String language = 'en-US';
tts.setLanguage(language);
Get Voice
我们可以获取所有可用的声音或获取特定语言的声音。此函数将返回特定的声音名称。
List<String> voices = await tts.getVoices();
String language = 'en-US';
List<String> voices = await tts.getVoiceByLang(language);
Native API Reference
Example
完整的示例代码如下:
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:text_to_speech/text_to_speech.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final String defaultLanguage = 'en-US';
TextToSpeech tts = TextToSpeech();
String text = '';
double volume = 1; // Range: 0-1
double rate = 1.0; // Range: 0-2
double pitch = 1.0; // Range: 0-2
String? language;
String? languageCode;
List<String> languages = <String>[];
List<String> languageCodes = <String>[];
String? voice;
TextEditingController textEditingController = TextEditingController();
@override
void initState() {
super.initState();
textEditingController.text = text;
WidgetsBinding.instance?.addPostFrameCallback((_) {
initLanguages();
});
}
Future<void> initLanguages() async {
/// populate lang code (i.e. en-US)
languageCodes = await tts.getLanguages();
/// populate displayed language (i.e. English)
final List<String>? displayLanguages = await tts.getDisplayLanguages();
if (displayLanguages == null) {
return;
}
languages.clear();
for (final dynamic lang in displayLanguages) {
languages.add(lang as String);
}
final String? defaultLangCode = await tts.getDefaultLanguage();
if (defaultLangCode != null && languageCodes.contains(defaultLangCode)) {
languageCode = defaultLangCode;
} else {
languageCode = defaultLanguage;
}
language = await tts.getDisplayLanguageByCode(languageCode!);
/// get voice
voice = await getVoiceByLang(languageCode!);
if (mounted) {
setState(() {});
}
}
Future<String?> getVoiceByLang(String lang) async {
final List<String>? voices = await tts.getVoiceByLang(languageCode!);
if (voices != null && voices.isNotEmpty) {
return voices.first;
}
return null;
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Text-to-Speech Example'),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Center(
child: Column(
children: <Widget>[
TextField(
controller: textEditingController,
maxLines: 5,
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Enter some text here...'),
onChanged: (String newText) {
setState(() {
text = newText;
});
},
),
Row(
children: <Widget>[
const Text('Volume'),
Expanded(
child: Slider(
value: volume,
min: 0,
max: 1,
label: volume.round().toString(),
onChanged: (double value) {
initLanguages();
setState(() {
volume = value;
});
},
),
),
Text('(${volume.toStringAsFixed(2)})'),
],
),
Row(
children: <Widget>[
const Text('Rate'),
Expanded(
child: Slider(
value: rate,
min: 0,
max: 2,
label: rate.round().toString(),
onChanged: (double value) {
setState(() {
rate = value;
});
},
),
),
Text('(${rate.toStringAsFixed(2)})'),
],
),
Row(
children: <Widget>[
const Text('Pitch'),
Expanded(
child: Slider(
value: pitch,
min: 0,
max: 2,
label: pitch.round().toString(),
onChanged: (double value) {
setState(() {
pitch = value;
});
},
),
),
Text('(${pitch.toStringAsFixed(2)})'),
],
),
Row(
children: <Widget>[
const Text('Language'),
const SizedBox(
width: 20,
),
DropdownButton<String>(
value: language,
icon: const Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: const TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (String? newValue) async {
languageCode =
await tts.getLanguageCodeByName(newValue!);
voice = await getVoiceByLang(languageCode!);
setState(() {
language = newValue;
});
},
items: languages
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
],
),
const SizedBox(
height: 20,
),
Row(
children: <Widget>[
const Text('Voice'),
const SizedBox(
width: 20,
),
Text(voice ?? '-'),
],
),
const SizedBox(
height: 20,
),
Row(
children: <Widget>[
Expanded(
child: Container(
padding: const EdgeInsets.only(right: 10),
child: ElevatedButton(
child: const Text('Stop'),
onPressed: () {
tts.stop();
},
),
),
),
if (supportPause)
Expanded(
child: Container(
padding: const EdgeInsets.only(right: 10),
child: ElevatedButton(
child: const Text('Pause'),
onPressed: () {
tts.pause();
},
),
),
),
if (supportResume)
Expanded(
child: Container(
padding: const EdgeInsets.only(right: 10),
child: ElevatedButton(
child: const Text('Resume'),
onPressed: () {
tts.resume();
},
),
),
),
Expanded(
child: Container(
child: ElevatedButton(
child: const Text('Speak'),
onPressed: () {
speak();
},
),
))
],
)
],
),
),
),
),
),
);
}
bool get supportPause => defaultTargetPlatform != TargetPlatform.android;
bool get supportResume => defaultTargetPlatform != TargetPlatform.android;
void speak() {
tts.setVolume(volume);
tts.setRate(rate);
if (languageCode != null) {
tts.setLanguage(languageCode!);
}
tts.setPitch(pitch);
tts.speak(text);
}
}
TODO
- ❌ Utterance Status Listener
- ❌ Linux Implementation
- ❌ Windows Implementation
更多关于Flutter文本转语音插件text_to_speech的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter文本转语音插件text_to_speech的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter应用中使用text_to_speech
插件来实现文本转语音功能的代码示例。这个插件允许你在Flutter应用中轻松集成文本转语音功能。
步骤 1: 添加依赖
首先,你需要在pubspec.yaml
文件中添加text_to_speech
依赖:
dependencies:
flutter:
sdk: flutter
text_to_speech: ^5.3.0 # 请确保使用最新版本
然后运行flutter pub get
来安装依赖。
步骤 2: 导入插件
在你的Dart文件中导入text_to_speech
插件:
import 'package:text_to_speech/text_to_speech.dart';
步骤 3: 使用插件
以下是一个简单的示例,展示了如何在Flutter应用中使用text_to_speech
插件:
import 'package:flutter/material.dart';
import 'package:text_to_speech/text_to_speech.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Text to Speech Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final TextToSpeech _tts = TextToSpeech();
@override
void initState() {
super.initState();
_initTts();
}
Future<void> _initTts() async {
bool isAvailable = await _tts.isLanguageAvailable("en-US");
if (isAvailable) {
setState(() {});
} else {
// Language not supported
}
}
Future<void> _speak(String text) async {
try {
await _tts.setLanguage("en-US");
await _tts.speak(text);
} catch (e) {
print("Failed to speak: $e");
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Text to Speech Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Hello, press the button to listen to a message!',
style: TextStyle(fontSize: 24),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
_speak("Hello, this is a text to speech demo.");
},
child: Text('Speak'),
),
],
),
),
);
}
@override
void dispose() {
_tts.stop();
_tts.dispose();
super.dispose();
}
}
解释
- 依赖添加:在
pubspec.yaml
文件中添加text_to_speech
依赖。 - 导入插件:在需要使用文本转语音功能的Dart文件中导入
text_to_speech
插件。 - 初始化插件:在
initState
方法中调用_initTts
方法来检查并初始化TTS插件。 - 文本转语音功能:
_speak
方法接受一个字符串参数,并使用_tts.speak
方法将其转换为语音。 - UI部分:一个简单的UI,包含一个按钮,点击按钮时调用
_speak
方法。 - 资源释放:在
dispose
方法中停止并释放TTS资源。
这个示例展示了如何在Flutter应用中使用text_to_speech
插件来实现基本的文本转语音功能。你可以根据需要进一步扩展和优化这个示例。