Flutter中 TTS(播放文本功能)的使用


需求

在flutter中指定一段文字,播放语音。

实现

1.添加库引用

我们这里使用Dart的 tts库,首先在配置文件中添加这个库的引用:

在pubspec.yaml文件中添加如下代码引用:

dependencies:
  tts: ^1.0.2

执行命令,获取该库:

flutter packages get

使用时引入头文件:

import 'package:tts/tts.dart';

2.创建tts_helper类,作为使用tts的帮助类


import 'package:tts/tts.dart'; import 'dart:async'; import 'dart:io'; /// Singleton tool class for tts /// Use TtsHelper step: /// /// Method : #isLanguageAvailable judge language, here language is _languageMap's values like "en-US",instead of the type of 'en' etc.. /// /// Method : #getTtsLanguage help you convert "en" to "en-US". /// /// Method : #setLanguage help you set Language , but "en-US" is default value /// /// use example: /// TtsHelper.instance.speak("speech content"); /// or /// TtsHelper.instance.setLanguageAndSpeak("speech content", "en-US"); /// ... class TtsHelper { // Locale to tss language map static final Map<String, String> _languageMap = { 'en': "en-US", 'zh': "zh-CN", "ar": "ar-SA", "cs": "cs-CZ", "da": "da-DK", "de": "de-DE", "el": "el-GR", "es": "es-ES", "fi": "fi-FI", "fr": "fr-CA", "he": "he-IL", "hi": "hi-IN", "hu": "hu-HU", "id": "id-ID", "it": "it-IT", "ja": "ja-JP", "ko": "ko-KR", "nl": "nl-BE", "no": "no-NO", "pl": "pl-PL", "pt": "pt-BR", "ro": "ro-RO", "ru": "ru-RU", "sk": "sk-SK", "sv": "sv-SE", "th": "th-TH", "tr": "tr-TR", 'en-US': "en-US", 'zh-CN': "zh-CN", "ar-SA": "ar-SA", "cs-CZ": "cs-CZ", "da-DK": "da-DK", "de-DE": "de-DE", "el-GR": "el-GR", "es-ES": "es-ES", "fi-FI": "fi-FI", "fr-CA": "fr-CA", "he-IL": "he-IL", "hi-IN": "hi-IN", "hu-HU": "hu-HU", "id-ID": "id-ID", "it-IT": "it-IT", "ja-JP": "ja-JP", "ko-KR": "ko-KR", "nl-BE": "nl-BE", "no-NO": "no-NO", "pl-PL": "pl-PL", "pt-BR": "pt-BR", "ro-RO": "ro-RO", "ru-RU": "ru-RU", "sk-SK": "sk-SK", "sv-SE": "sv-SE", "th-TH": "th-TH", "tr-TR": "tr-TR", }; static final String _defaultL = "en-US"; List<String> _languages; static TtsHelper _instance; static TtsHelper get instance => _getInstance(); factory TtsHelper() =>_getInstance(); static TtsHelper _getInstance() { if (_instance == null) { _instance = new TtsHelper._internal(); } return _instance; } TtsHelper._internal() { // Initialize _initPlatformState(); } _initPlatformState() async { _languages = await Tts.getAvailableLanguages(); // If getAvailableLanguages is null, add "en-US" to _languages. if (_languages == null) { _languages = [_defaultL]; } // Default set en-US language _setLanguage(_defaultL); } String _getTtsLanguage(String localeStr) { if(localeStr == null || localeStr.isEmpty || !_languageMap.containsKey(localeStr)) { return _defaultL; } return _languageMap[localeStr]; } // Return whether the result if set language is successful Future<bool> _setLanguage (String lang) async { String language = _getTtsLanguage(lang); if (language == null || language.isEmpty) { language = _defaultL; } if(Platform.isIOS && !_languages.contains(language)) { return false; } final bool isSet = await Tts.setLanguage(language); return isSet; } // Returns whether the supported language is supported Future<bool> _isLanguageAvailable (String language) async { final bool isSupport = await Tts.isLanguageAvailable(language); return isSupport; } void speak (String text) async { if (text == null || text.isEmpty) { return;} Tts.speak(text); } void setLanguageAndSpeak(String text, String language) async { String ttsL = _getTtsLanguage(language); var setResult = await _setLanguage(ttsL); if(setResult != null) { var available = await _isLanguageAvailable(ttsL); if(available != null) { speak(text); } } } }

3.添加测试页面

import 'package:flutter_tts/tts_helper.dart';

import 'package:flutter/material.dart';

class VoiceSetPage extends StatefulWidget {
  VoiceSetPage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _VoiceSetPageState createState() => _VoiceSetPageState();
}

class _VoiceSetPageState extends State<VoiceSetPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(

        backgroundColor: Colors.blue,
        title: Text(widget.title),
        elevation: 5.0, // shadow the bottom of AppBar
      ),
      body: Center(
        child: ListView(
          children: <Widget>[
            ListTile(
              title: Text(
                'test vioce',
                style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20.0),
              ),
              onTap: () {
                showAlertDialog(context);
                TtsHelper.instance.setLanguageAndSpeak("你好我是声音播放器", "zh");
              },
            ),
            Divider(
              height: 1,
            )
          ],
        ),
      ),
    );
  }
}

void showAlertDialog(BuildContext context) {
  NavigatorState navigator =
  context.rootAncestorStateOfType(const TypeMatcher<NavigatorState>());
  debugPrint("navigator is null?" + (navigator == null).toString());
  showDialog(
      context: context,
      builder: (_) => new AlertDialog(
          title: new Text("Dialog Title"),
          content: new Text("This is my content"),
          actions: <Widget>[
            new FlatButton(
              child: new Text("CANCEL"),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
            new FlatButton(
              child: new Text("OK"),
              onPressed: () {
                Navigator.of(context).pop();
              },
            )
          ]));
}

4.在main中添加测试入口

import 'package:flutter/material.dart';
import 'package:flutter_tts/voice_set_page.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  void _incrementCounter() {
    Navigator.push(context, MaterialPageRoute(builder: (context) => VoiceSetPage(title: "Setting")));
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '点击浮动按钮跳转到语音测试页',
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: '跳转',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

测试可用,希望能帮助到你。

完成demo下载地址:

文件信息:
文件名称:完整例子
下载地址:
百度网盘

发表评论

关闭菜单