speech_to_text我快疯了.

在我的应用程序中,我有各种表格,每个表格都有不同的TextFormFields. 对于每个输入,我都必须连接一个麦克风,以便我转录所说的内容. 我已经用Basic SpeechToText实现了所有内容,但由于各种初始化,它出现了一些问题. 然后我通过切换到SpeechToTextProvider并获取灵感from this code made available by the plugin来修改所有内容.

然而,我无法确保口语文本逐字逐句地转录到输入中. 这在SpeechToText中是通过监听事件的onResult参数处理的,但这在Provider 上不可用!

有人能帮助我吗? 一千谢谢!

以下是表单的代码,为了简单起见,只有一个输入:

class WeekForm extends StatefulWidget {
  const WeekForm({required this.week, super.key});

  final Week week;

  @override
  State<WeekForm> createState() => _WeekFormState();
}

class _WeekFormState extends State<WeekForm> {
  Week get week => widget.week;

  final _formKey = GlobalKey<FormState>(debugLabel: "WeekForm");

  final TextEditingController _learnedController = TextEditingController();
  String _lastTextChange = '';

  void _setLastTextChange(inputKey, lastText) {
    setState(() {
      _lastTextChange = lastText;
    });
  }

  void _saveLearn(week, appState) async {
    if (_formKey.currentState!.validate()) {
      week.learned = _learnedController.text;

      // save data to Firebase
      appState.setWeek(week);
    }
  }

  @override
  void initState() {
    ///fetched data from firebase showing on controller
    super.initState();
    _learnedController.text = week.learned ?? "";
    _setLastTextChange("learned", _learnedController.text);
  }

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          // Add TextFormFields and ElevatedButton here.
          Row(
            children: [
              Expanded(
                child: TextFormField(
                  controller: _learnedController,
                  decoration: const InputDecoration(
                    border: OutlineInputBorder(),
                  ),
                  onChanged: (value) {
                    _setLastTextChange("learned", value);
                  },
                ),
              ),
              SpeechProvider(
                key: const ValueKey("learned"),
                controller: _learnedController,
                lastInputChange: _lastTextChange,
                setLastInputChange: _setLastTextChange,
              ),
            ],
          ),
          Consumer<ApplicationState>(
            builder: (context, appState, _) => Align(
              alignment: Alignment.bottomRight,
              child: ElevatedButton(
                onPressed: () => _saveLearn(week, appState),
                child: const Text("Save"),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

以下是拨打SpeechToTextProvider的代码:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:speech_to_text/speech_to_text_provider.dart';

class SpeechProvider extends StatefulWidget {
  const SpeechProvider({
    super.key,
    required this.controller,
    required this.lastInputChange,
    required this.setLastInputChange,
  });

  final TextEditingController controller;
  final String lastInputChange;
  final void Function(String, String) setLastInputChange;

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

class SpeechProviderState extends State<SpeechProvider> {
  String lastWords = '';
  String lastStatus = '';

  late SpeechToTextProvider speechProvider;

  void startListening() {
    if (speechProvider.isAvailable && speechProvider.isNotListening) {
      lastWords = '';

      speechProvider.listen(
        // I want something like this!!! but this is available only in basic SpeechToText
        onResult: resultListener,
      );
    }
  }

  void stopListening() {
    if (speechProvider.isListening) {
      speechProvider.stop();
      widget.setLastInputChange((widget.key as ValueKey<dynamic>).value, widget.controller.text);
      setState(() {});
    }
  }

  /// This callback is invoked each time new recognition results are
  /// available after `listen` is called.
  void resultListener() {
    var result = speechProvider.lastResult;

    if (result!.finalResult) {
      widget.setLastInputChange((widget.key as ValueKey<dynamic>).value, widget.controller.text);
    } else {
      setState(() {
        lastWords = result.recognizedWords;
      });
      widget.controller.text = '${widget.lastInputChange} $lastWords';
    }
  }

  @override
  Widget build(BuildContext context) {
    speechProvider = Provider.of<SpeechToTextProvider>(context);

    if (speechProvider.isNotAvailable) {
      return const Center(
        child: Text('Speech recognition not available, no permission or not available on the device.'),
      );
    }
    return MicrophoneWidget(speechProvider.isListening, startListening, stopListening, key: UniqueKey());
  }
}

class MicrophoneWidget extends StatelessWidget {
  const MicrophoneWidget(this.isListening, this.startListening, this.stopListening, {super.key});

  final bool isListening;
  final void Function() startListening;
  final void Function() stopListening;

  @override
  Widget build(BuildContext context) {
    return TapRegion(
      onTapOutside: (tap) => isListening ? stopListening() : null,
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: SizedBox(
          child: FloatingActionButton(
            onPressed: isListening ? stopListening : startListening,
            shape: const RoundedRectangleBorder(
              borderRadius: BorderRadius.all(Radius.circular(80.0)),
            ),
            child: Icon(isListening ? Icons.mic : Icons.mic_off),
          ),
        ),
      ),
    );
  }
}

推荐答案

根据您的描述,我认为您希望有一种方法在有新的时候获得SpeechRecognitionResult分.SpeechToTextProvider公开了一个stream getter,您可以收听它并访问它发出的事件的识别结果:

speechProvider.stream.listen((event) {
  final result = event.recognitionResult;
});

Flutter相关问答推荐

我遇到了一个问题,从showDialogue()调用Navigator.pop()两次导致屏幕空白

从Flutter应用程序解释蓝牙BLE数据:了解Sylvania压力值

底部导航栏项目在抖动中不更改 colored颜色

我的flutter代码显示一个小部件被认为是死代码,为什么?

在Flutter TextField中计算子字符串位置

如何在Flutter 中共享选定文本

如何让经过Firebase身份验证的用户能够将Zip文件上载到Firebase云存储?

为什么我的页面控制器在使用Riverpod时没有更改我的页面视图?

运行调试flutter应用程序时出错:B/BL超出范围(最大+/-128MB)到'';

如何在flutter中更改showModalBottomSheet小部件中CheckboxListTile小部件的值?

如何将取消图标放置在右上角

小部件堆栈未显示顶层

我想在一个屏幕上有两个相同区域的列表视图,我该如何设置?

Flutter RawMaterialButton 常量相对大小

如何获得Flutter 的时差?

Flutter 如何要求用户在应用程序中设置电话密码?

根据索引/变量更改小部件的 colored颜色

Flutter 平台通道将多数据传递给 windows 功能

参数类型Future>不能分配给参数类型Future>?

如何从dart 中的当前日期时间中减go 1 天?