Flutter文本转语音插件galli_text_to_speech的使用

Flutter 文本转语音插件 galli_text_to_speech 的使用

简介

galli_text_to_speech 是一个 Flutter 插件,用于实现文本转语音(TTS)功能。它支持 iOS、Android、web 和 macOS 平台。

开始使用

添加依赖

pubspec.yaml 文件中添加 galli_text_to_speech 作为依赖项:

dependencies:
  galli_text_to_speech: ^0.2.3

然后运行 flutter pub get 更新依赖。

安装
Android
  • 最低 SDK 版本为 21
  • 针对 SDK 30 (Android 11) 的应用需要在 AndroidManifest.xml 中声明 TextToSpeech.Engine.INTENT_ACTION_TTS_SERVICE:
<queries>
  <intent>
      <action android:name="android.intent.action.TTS_SERVICE" />
  </intent>
</queries>
iOS & macOS
  • iOS 最低版本为 7.0
  • macOS 最低版本为 10.14

功能

功能 Android iOS Web macOS
说话
停止
暂停 -
恢复 -
设置音量
设置语速
设置音调
设置语言
获取语言
获取声音

使用示例

首先,在你的代码中导入 galli_text_to_speech

import 'package:galli_text_to_speech/galli_text_to_speech.dart';

创建 GalliTextToSpeech 实例:

GalliTextToSpeech tts = GalliTextToSpeech();
说话
String text = "Hello, Good Morning!";
tts.speak(text);
设置音量

音量范围为 0-1,其中 0 表示静音,1 表示最大音量(默认行为)。

double volume = 1.0;
tts.setVolume(volume);
设置语速

语速范围为 0-21.0 是正常且默认的语速。较小的值会减慢语速(例如,0.5 是正常语速的一半)。较大的值会加速语速(例如,2.0 是正常语速的两倍)。

double rate = 1.0;
tts.setRate(rate);
设置音调

音调范围为 0-21.0 是正常的音调,较小的值会降低音调,较大的值会提高音调。

double pitch = 1.0;
tts.setPitch(pitch);
设置语言

接受特定语言的语言标签名称,例如 'en-US'。可以使用 getLanguages 函数获取支持的语言列表。

String language = 'en-US';
tts.setLanguage(language);
获取语言

提供支持的语言代码列表,格式为 locale tag name,例如 'en-US'。可以使用 getDisplayLanguageByCode 获取特定语言代码的显示名称。

String language = 'en-US';
tts.setLanguage(language);
获取声音

可以获取所有可用的声音或特定语言的声音。此函数将返回特定的声音名称。

List<String> voices = await tts.getVoices();

String language = 'en-US';
List<String> voices = await tts.getVoiceByLang(language);

示例代码

以下是一个完整的示例代码,展示了如何使用 galli_text_to_speech 插件。

import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:galli_text_to_speech/galli_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';

  GalliTextToSpeech tts = GalliTextToSpeech();

  String text = '';
  double volume = 1; // 范围: 0-1
  double rate = 1.0; // 范围: 0-2
  double pitch = 1.0; // 范围: 0-2

  String? language;
  String? languageCode;
  List<String> languages = [];
  List<String> languageCodes = [];
  String? voice;

  TextEditingController textEditingController = TextEditingController();

  @override
  void initState() {
    super.initState();
    textEditingController.text = text;
    WidgetsBinding.instance?.addPostFrameCallback((_) {
      initLanguages();
    });
  }

  Future<void> initLanguages() async {
    /// 填充语言代码(即 en-US)
    languageCodes = await tts.getLanguages();

    /// 填充显示语言(即 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!);

    /// 获取声音
    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: [
                  TextField(
                    controller: textEditingController,
                    maxLines: 5,
                    decoration: const InputDecoration(
                        border: OutlineInputBorder(),
                        hintText: '输入一些文本...'),
                    onChanged: (String newText) {
                      setState(() {
                        text = newText;
                      });
                    },
                  ),
                  Row(
                    children: [
                      const Text('音量'),
                      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: [
                      const Text('语速'),
                      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: [
                      const Text('音调'),
                      Expanded(
                        child: Slider(
                          value: pitch,
                          min: 0,
                          max: 2,
                          label: pitch.round().toString(),
                          onChanged: (double value) {
                            setState(() {
                              pitch = value;
                            });
                          },
                        ),
                      ),
                      Text('(${pitch.toStringAsFixed(2)})'),
                    ],
                  ),
                  const SizedBox(
                    height: 20,
                  ),
                  Row(
                    children: [
                      const Text('声音'),
                      const SizedBox(
                        width: 20,
                      ),
                      Text(voice ?? '-'),
                    ],
                  ),
                  const SizedBox(
                    height: 20,
                  ),
                  Row(
                    children: [
                      Expanded(
                        child: Container(
                          padding: const EdgeInsets.only(right: 10),
                          child: ElevatedButton(
                            child: const Text('停止'),
                            onPressed: () {
                              tts.stop();
                            },
                          ),
                        ),
                      ),
                      if (supportPause)
                        Expanded(
                          child: Container(
                            padding: const EdgeInsets.only(right: 10),
                            child: ElevatedButton(
                              child: const Text('暂停'),
                              onPressed: () {
                                tts.pause();
                              },
                            ),
                          ),
                        ),
                      if (supportResume)
                        Expanded(
                          child: Container(
                            padding: const EdgeInsets.only(right: 10),
                            child: ElevatedButton(
                              child: const Text('恢复'),
                              onPressed: () {
                                tts.resume();
                              },
                            ),
                          ),
                        ),
                      Expanded(
                          child: Container(
                        child: ElevatedButton(
                          child: const Text('播放'),
                          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);
  }
}

运行示例

你可以找到示例代码并运行来检查实现。

  • 移动到示例目录:
$ cd example
  • 运行 Android/iOS:
$ flutter run -d <device_name>
  • 运行 Web:
$ flutter run -d chrome
  • 运行 macOS:
$ flutter run -d macOS

更多关于Flutter文本转语音插件galli_text_to_speech的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter文本转语音插件galli_text_to_speech的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


galli_text_to_speech 是一个 Flutter 插件,用于将文本转换为语音(Text-to-Speech,TTS)。它允许你在 Flutter 应用程序中轻松地实现文本朗读功能。以下是使用 galli_text_to_speech 插件的步骤和示例代码。

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 galli_text_to_speech 依赖:

dependencies:
  flutter:
    sdk: flutter
  galli_text_to_speech: ^latest_version

然后运行 flutter pub get 来获取依赖。

2. 初始化插件

在你的 Dart 代码中,导入 galli_text_to_speech 并初始化它。

import 'package:flutter/material.dart';
import 'package:galli_text_to_speech/galli_text_to_speech.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: TextToSpeechDemo(),
    );
  }
}

class TextToSpeechDemo extends StatefulWidget {
  @override
  _TextToSpeechDemoState createState() => _TextToSpeechDemoState();
}

class _TextToSpeechDemoState extends State<TextToSpeechDemo> {
  final GalliTextToSpeech tts = GalliTextToSpeech();

  @override
  void initState() {
    super.initState();
    tts.init(); // 初始化 TTS
  }

  @override
  void dispose() {
    tts.dispose(); // 释放资源
    super.dispose();
  }

  void speak(String text) async {
    await tts.speak(text);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Text to Speech Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () => speak("Hello, how are you?"),
              child: Text("Speak"),
            ),
          ],
        ),
      ),
    );
  }
}

3. 使用插件

在上面的示例中,GalliTextToSpeech 被初始化和使用。speak 方法用于将文本转换为语音。

4. 配置和选项

galli_text_to_speech 可能支持一些配置选项,例如语言、音调、速度等。你可以通过查阅插件的文档来了解如何调整这些参数。

// 设置语言
await tts.setLanguage("en-US");

// 设置音调
await tts.setPitch(1.0);

// 设置语速
await tts.setSpeechRate(0.5);

5. 处理错误

在使用 TTS 时,可能会遇到一些错误,例如设备不支持 TTS 引擎或语言不支持。你可以通过捕获异常来处理这些错误。

try {
  await tts.speak("Hello, how are you?");
} catch (e) {
  print("Error: $e");
}
回到顶部