【问题标题】:Flutter Text To Speech: Speak several strings subsequently with different SpeechRatesFlutter Text To Speech:随后用不同的 SpeechRates 说出几个字符串
【发布时间】:2019-09-22 03:56:16
【问题描述】:

我对 Flutter Text To Speech 包有疑问。 单击 FloatingActionButton 时,我想随后说出/播放几个字符串(具有不同的 Speechrates)。但是,这样做时,我只能听到传递给函数的最后一个字符串,而不是第一个。

正如您在下面的代码中看到的,我尝试使用异步编程(async / await)。

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

class SpeakerClass extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
  // TODO: implement createState
  return _SpeakerClassState();
  }
}

class _SpeakerClassState extends State<SpeakerClass>{
  String text1 = 'eins';
  String text2 = 'zwei';
  String text3 = 'drei';
  String text4 = 'vier';
  String currentTtsString;
  double ttsSpeechRate1 = 0.5;
  double ttsSpeechRate2 = 1.0;
  double currentSpeechRate;


  Future playTtsString1() async {
    currentTtsString = text1;
    currentSpeechRate = ttsSpeechRate1;
    await runTextToSpeech(currentTtsString, currentSpeechRate);
    return null;
  }

  Future playTtsString2() async {
    currentTtsString = text2;
    currentSpeechRate = ttsSpeechRate2;
    await runTextToSpeech(currentTtsString, currentSpeechRate);
    return null;
  }

  @override
  Widget build(BuildContext context) {
  return Scaffold(
    body: FloatingActionButton (
      backgroundColor: Colors.blue,
      child: Icon(Icons.volume_up, color: Colors.white),
      onPressed: () async {
        await playTtsString1();
        await playTtsString2();
      },
    )
  );
  }

}


Future<void> runTextToSpeech(String currentTtsString, double currentSpeechRate) async {
  FlutterTts flutterTts;
  flutterTts = new FlutterTts();
  await flutterTts.setLanguage("en-GB");
  await flutterTts.setVolume(1.0);
  await flutterTts.setPitch(1.0);
  await flutterTts.isLanguageAvailable("en-GB");
  await flutterTts.setSpeechRate(currentSpeechRate);
  await flutterTts.speak(currentTtsString);
}

当按下 FloatingActionButton 时,我希望程序首先执行函数 playTtsString1(“eins”,速度为 0.5),然后执行函数 playTtsString2(“zwei”,速度为 1)。

但是,不知怎的,我只能听到程序说“zwei”。我猜程序不是在等待第一个函数“playTtsString1”完成,而是已经执行了第二个函数“playTtsString2”。在这件事上我真的很感激任何帮助!

【问题讨论】:

    标签: dart flutter async-await text-to-speech future


    【解决方案1】:
    import 'package:flutter/material.dart';
    import 'dart:async';
    import 'package:flutter_tts/flutter_tts.dart';
    
    class SpeakerClass extends StatefulWidget{
      @override
      State<StatefulWidget> createState() {
      // TODO: implement createState
      return _SpeakerClassState();
      }
    }
    
    class _SpeakerClassState extends State<SpeakerClass>{
      String text1 = 'eins';
      String text2 = 'zwei';
      String text3 = 'drei';
      String text4 = 'vier';
      String currentTtsString;
      double ttsSpeechRate1 = 0.5;
      double ttsSpeechRate2 = 1.0;
      double currentSpeechRate;
    
      FlutterTts flutterTts;
      bool bolSpeaking = false;
    
      Future playTtsString1() async {
        bolSpeaking = true;
        currentTtsString = text1;
        currentSpeechRate = ttsSpeechRate1;
        await runTextToSpeech(currentTtsString, currentSpeechRate);
        return null;
      }
    
      Future playTtsString2() async {
        bolSpeaking = true;
        currentTtsString = text2;
        currentSpeechRate = ttsSpeechRate2;
        await runTextToSpeech(currentTtsString, currentSpeechRate);
        return null;
      }
    
      @override
      Widget build(BuildContext context) {
      return Scaffold(
        body: FloatingActionButton (
          backgroundColor: Colors.blue,
          child: Icon(Icons.volume_up, color: Colors.white),
          onPressed: () async {
            // Play String 1
            await playTtsString1();
    
            // Check String 1 Finish
            new Future.delayed(new Duration(milliseconds: 100), () async {
                // loop until bolSpeaking = false
                while (bolSpeaking) {
                  await Thread.sleep(100);
                }
    
                // play String 2
                await playTtsString2();
            }
          },
        )
      );
      }
    }
    
    
    Future<void> runTextToSpeech(String currentTtsString, double currentSpeechRate) async {
      flutterTts = new FlutterTts();
      await flutterTts.setLanguage("en-GB");
      await flutterTts.setVolume(1.0);
      await flutterTts.setPitch(1.0);
      await flutterTts.isLanguageAvailable("en-GB");
      await flutterTts.setSpeechRate(currentSpeechRate);
    
      flutterTts.setCompletionHandler(() {
        setState(() {
          // The following code(s) will be called when the TTS finishes speaking
          bolSpeaking = false;
        });
      });
    
      flutterTts.speak(currentTtsString);
    }
    

    【讨论】:

    • 嘿,谢谢你的回答!不幸的是,它仍然无法按预期工作。我按照您的建议编辑了代码,但是,按下按钮时我只能听到第二个文本而不是第一个文本。
    • 这意味着 flutterTts.speak() 调用后立即返回,无需等待发言完成
    • 好的,我记得,有一个setCompletionHandler,我会更新答案
    • 请。检查更新的答案。我可能在代码中犯了错误,即某些代码的[位置]可能不正确。在我的原始代码中,每次我想说出一个字符串时,我都没有 [NEW] 一个 [flutterTts],相反,我的 flutterTts 是另一个 dart 文件中的静态变量,并且只在我的整个应用程序中初始化了一次。所以我不确定这个变量是否要多次初始化,flutterTts.setCompletionHandler 是否仍然有效!
    • 非常感谢您的帮助!不知何故,代码仍然不起作用。里面好像有不少错误。
    【解决方案2】:

    这现在应该适用于最新的 flutter_tts 版本。

    您只需要在说话发生之前设置 awaitSpeakCompletion。 您可以像这样更新您的运行方法:

    Future<void> runTextToSpeech(String currentTtsString, double currentSpeechRate) async {
      FlutterTts flutterTts;
      flutterTts = new FlutterTts();
      await flutterTts.awaitSpeakCompletion(true);
      await flutterTts.setLanguage("en-GB");
      await flutterTts.setVolume(1.0);
      await flutterTts.setPitch(1.0);
      await flutterTts.isLanguageAvailable("en-GB");
      await flutterTts.setSpeechRate(currentSpeechRate);
      await flutterTts.speak(currentTtsString);
    }
    

    【讨论】:

    • 这个答案很完美。添加 awaitSpeakCompletion 作品
    猜你喜欢
    • 2019-08-11
    • 1970-01-01
    • 1970-01-01
    • 2017-11-16
    • 2022-07-14
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多