【问题标题】:Playing or not playing in text to speech在文本到语音中播放或不播放
【发布时间】:2021-02-10 04:31:13
【问题描述】:

我有一个程序可以将文本翻译成语音,在颤振中,到目前为止一切都很好,问题是如何让程序显示一个文本,说明程序中“正在播放”和“未播放”的状态,即在播放语音的同时,显示“正在播放”状态。

非常感谢您的回复。

这是我的代码:

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

class TextVoicePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: TextVoice(),
    );
  }
}

class TextVoice extends StatefulWidget {
  @override
  _Speak createState() => _Speak();
}

class _Speak extends State<TextVoice> {
  final FlutterTts flutterTts = FlutterTts();

  @override
  Widget build(BuildContext context) {
    bool speaking = false;
    TextEditingController textEditingController = TextEditingController();

    Future _speak(String text) async {
      await flutterTts.setLanguage("es-MX");
      await flutterTts.setPitch(1);
      await flutterTts.speak(text);
    }

    Future _stop() async {
      await flutterTts.stop();
    }

    return Scaffold(
        body: Stack(
          children: <Widget>[
            Padding(
              padding: EdgeInsets.all(30.0),
              child: TextFormField(
                controller: textEditingController,
              ),
            ),
          ],
        ),
        floatingActionButtonLocation:
            FloatingActionButtonLocation.miniCenterDocked,
        floatingActionButton: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              FloatingActionButton(
                backgroundColor: Colors.green,
                foregroundColor: Colors.white,
                heroTag: "btn",
                onPressed: () => _speak(textEditingController.text),
                child: Icon(Icons.play_arrow),
              ),
              SizedBox(
                width: 130,
              ),
              FloatingActionButton(
                foregroundColor: Colors.white,
                backgroundColor: Colors.red,
                heroTag: "btn2",
                onPressed: () => _stop(),
                child: Icon(Icons.stop),
              )
            ],
          ),
        ));
  }
}

【问题讨论】:

    标签: flutter dart text-to-speech status


    【解决方案1】:

    我对代码进行了一些更改并添加了您正在寻找的行为。我将列举变化:

    1- 将变量 speakingtextEditingController 移动为类的属性,因为这是定义它们的正确位置。

    2- 我包含了一个 initState() 来初始化 textEditingController,正如我在 flutter_tts 文档中发现的那样,我添加了两个处理程序方法来切换文本从“正在播放”到“未播放”。

    3- 还添加了一个 dispose() 方法。主要是因为TextEditingController应该在widget生命周期结束时被释放(你可以在官方文档或in this great article阅读更多关于Flutter生命周期的内容)。

    4- 我用 Column 包装了 Stack 并附加了带有 Text 的 SizedBox 以显示状态(我认为 Stack 小部件可能不是在这种情况下使用的最佳选择。我会将其切换为简单的 Container也许)。

    5- 最后,我将 _speak_stop 方法从构建函数中移出,并将它们作为类的方法。

    您可能还想查看有关使用 setState 的官方 Flutter 文档。

    我已经指出了下面代码中的变化:

    import 'package:flutter/material.dart';
    import 'package:flutter_tts/flutter_tts.dart';
    
    class TextVoicePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: TextVoice(),
        );
      }
    }
    
    class TextVoice extends StatefulWidget {
      @override
      _Speak createState() => _Speak();
    }
    
    class _Speak extends State<TextVoice> {
      final FlutterTts flutterTts = FlutterTts();
      ///1
      bool speaking = false;
      TextEditingController textEditingController;
    
      @override ///2
      void initState() {
        textEditingController = TextEditingController();
        flutterTts.setStartHandler(() {
          ///This is called when the audio starts
          setState(() {
            speaking = true;
          });
        });
    
        flutterTts.setCompletionHandler(() {
          ///This is called when the audio ends
          setState(() {
            speaking = false;
          });
        });
        super.initState();
      }
    
      @override ///3
      void dispose() {
        textEditingController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            body: Column(
              children: [
                Stack(
                  children: <Widget>[
                    Padding(
                      padding: EdgeInsets.all(30.0),
                      child: TextFormField(
                        controller: textEditingController,
                      ),
                    ),
                  ],
                ),
                SizedBox( ///4
                  child: Text(
                    speaking ? "Playing" : "Not playing"
                  ),
                )
              ],
            ),
            floatingActionButtonLocation:
            FloatingActionButtonLocation.miniCenterDocked,
            floatingActionButton: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  FloatingActionButton(
                    backgroundColor: Colors.green,
                    foregroundColor: Colors.white,
                    heroTag: "btn",
                    onPressed: () => _speak(textEditingController.text),
                    child: Icon(Icons.play_arrow),
                  ),
                  SizedBox(
                    width: 130,
                  ),
                  FloatingActionButton(
                    foregroundColor: Colors.white,
                    backgroundColor: Colors.red,
                    heroTag: "btn2",
                    onPressed: () => _stop(),
                    child: Icon(Icons.stop),
                  )
                ],
              ),
            ));
      }
    
      ///5
      Future _speak(String text) async {
        await flutterTts.setLanguage("es-MX");
        await flutterTts.setPitch(1);
        await flutterTts.speak(text);
      }
    
      Future _stop() async {
        await flutterTts.stop();
      }
    }
    

    【讨论】:

    • 嗨,它真的很好用,非常感谢。
    【解决方案2】:

    我对代码进行了一些更改并添加了您正在寻找的行为。我将列举变化:

    1- 将变量 speakingtextEditingController 移动为类的属性,因为这是定义它们的正确位置。

    2- 我包含了一个 initState() 来初始化 textEditingController,正如我在 flutter_tts 文档中发现的那样,我添加了两个处理程序方法来切换文本从“正在播放”到“未播放”。

    3- 还添加了一个 dispose() 方法。主要是因为TextEditingController应该在widget生命周期结束时被释放(你可以在官方文档或in this great article阅读更多关于Flutter生命周期的内容)。

    4- 我用 Column 包装了 Stack 并附加了带有 Text 的 SizedBox 以显示状态(我认为 Stack 小部件可能不是在这种情况下使用的最佳选择。我会将其切换为简单的 Container也许)。

    5- 最后,我将 _speak_stop 方法从构建函数中移出,并将它们作为类的方法。

    您可能还想查看有关使用 setState 的官方 Flutter 文档。

    我已经指出了下面代码中的变化:

    class TextVoicePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: TextVoice(),
        );
      }
    }
    
    class TextVoice extends StatefulWidget {
      @override
      _Speak createState() => _Speak();
    }
    
    class _Speak extends State<TextVoice> {
      final FlutterTts flutterTts = FlutterTts();
      ///1
      bool speaking = false;
      TextEditingController textEditingController;
    
      @override ///2
      void initState() {
        textEditingController = TextEditingController();
        flutterTts.setStartHandler(() {
          ///This is called when the audio starts
          setState(() {
            speaking = true;
          });
        });
    
        flutterTts.setCompletionHandler(() {
          ///This is called when the audio ends
          setState(() {
            speaking = false;
          });
        });
        super.initState();
      }
    
      @override ///3
      void dispose() {
        textEditingController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            body: Column(
              children: [
                Stack(
                  children: <Widget>[
                    Padding(
                      padding: EdgeInsets.all(30.0),
                      child: TextFormField(
                        controller: textEditingController,
                      ),
                    ),
                  ],
                ),
                SizedBox( ///4
                  child: Text(
                    speaking ? "Playing" : "Not playing"
                  ),
                )
              ],
            ),
            floatingActionButtonLocation:
            FloatingActionButtonLocation.miniCenterDocked,
            floatingActionButton: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  FloatingActionButton(
                    backgroundColor: Colors.green,
                    foregroundColor: Colors.white,
                    heroTag: "btn",
                    onPressed: () => _speak(textEditingController.text),
                    child: Icon(Icons.play_arrow),
                  ),
                  SizedBox(
                    width: 130,
                  ),
                  FloatingActionButton(
                    foregroundColor: Colors.white,
                    backgroundColor: Colors.red,
                    heroTag: "btn2",
                    onPressed: () => _stop(),
                    child: Icon(Icons.stop),
                  )
                ],
              ),
            ));
      }
    
      ///5
      Future _speak(String text) async {
        await flutterTts.setLanguage("es-MX");
        await flutterTts.setPitch(1);
        await flutterTts.speak(text);
      }
    
      Future _stop() async {
        await flutterTts.stop();
      }
    }
    

    【讨论】:

      【解决方案3】:

      您可以为您的 Flutter 应用配置 FlutterToast 小部件,并根据您的状态向您的 Flutter 应用发送消息作为敬酒。

      添加依赖fluttertoast:^8.0.8

      示例代码:

      Fluttertoast.showToast(
          msg: 'Playing',
          toastLength: Toast.LENGTH_SHORT,
          gravity: ToastGravity.CENTER,
          timeInSecForIosWeb: 4,
          textColor: const Color.fromRGBO(0, 0, 0, 1),
          webPosition: "center",
          webBgColor: "linear-gradient(to right, #5aff15, #5aff15)",
          backgroundColor: const Color.fromRGBO(90,255,21,1),
        );
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多