FlutterSoundRecorder.onProgress在StreamBuilder中从未包含数据

swvgeqrz  于 2022-12-14  发布在  Flutter
关注(0)|答案(1)|浏览(209)

我在下面这5分钟video设置一个录音机在Flutter。
当我点击ElevatedButton开始录制音频时,它确实在播放和停止之间切换,并创建了一个音频文件,但snapshot.hasData总是假的,所以Text在录制过程中保持00:00。我找到的唯一信息是关于setSubscriptionDuration的,我确实设置了它。我还尝试了flutter clean等。它还能是什么?
我在macOS上使用Flutter 3.3.8,flutter_sound: ^9.1.9。我在真实的的iPhone XR上运行该应用程序,flutter run
我是新来的flutter。我真的很感激你能提供的任何帮助!
我已经
1.流生成器

StreamBuilder<RecordingDisposition>(
          stream: recorder.onProgress,
          builder: (context, snapshot) {
            print('snapshot.hasData :${snapshot.hasData}');
            final duration =
                snapshot.hasData ? snapshot.data!.duration : Duration.zero;

            print('duration :$duration');
            String twoDigits(int n) => n.toString().padLeft(2, '0');
            final twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
            final twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
            return Text(
              '$twoDigitMinutes:$twoDigitSeconds',
              style: const TextStyle(
                fontSize: 20,
              ),
            );
          },
        ),

1.升高按钮

ElevatedButton(
          child: Icon(
            recorder.isRecording ? Icons.stop : Icons.mic,
            size: 20,
          ),
          onPressed: () async {
            if (recorder.isRecording) {
              await stop();
            } else {
              await record();
            }

            setState(() {});
          },
        )

1.正确初始化记录仪

final recorder = FlutterSoundRecorder();
  Future<void> initRecorder() async {
    final status = await Permission.microphone.request();
    if (status != PermissionStatus.granted) {
      throw 'Microphone permission not granted';
    }
    await recorder.openRecorder();
    isRecorderReady = true;
    recorder.setSubscriptionDuration(
      const Duration(
        microseconds: 100,
      ),
    );
  }
  @override
  void initState() {
    super.initState();
    initRecorder();
  }

这是目前为止的情况:

laik7k3q

laik7k3q1#

因此,我找到了一个解决方案,但是StreamBuilder问题没有得到回答。不要使用StreamBuilder,而是创建一个有状态的TimerWidget,它由ValueNotifier初始化。

import 'dart:async';
import 'package:flutter/material.dart';
enum Time { start, pause, reset }

class TimerController extends ValueNotifier<Time> {
  TimerController({Time time = Time.reset}) : super(time);
  void startTimer() => value = Time.start;
  void pauseTimer() => value = Time.pause;
  void resetTimer() => value = Time.reset;
}

class TimerWidget extends StatefulWidget {
  final TimerController controller;
  const TimerWidget({
    Key? key,
    required this.controller,
  }) : super(key: key);

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

class _TimerWidgetState extends State<TimerWidget> {
  Duration duration = const Duration();
  Timer? timer;

  @override
  void initState() {
    super.initState();
    widget.controller.addListener(() {
      switch (widget.controller.value) {
        case Time.start:
          startTimer();
          break;
        case Time.pause:
          stopTimer();
          break;
        case Time.reset:
          reset();
          stopTimer();
          break;
      }
    });
  }

  void reset() => setState(() => duration = const Duration());

  void addTime() {
    const addSeconds = 1;
    setState(() {
      final seconds = duration.inSeconds + addSeconds;
      if (seconds < 0) {
        timer?.cancel();
      } else {
        duration = Duration(seconds: seconds);
      }
    });
  }

  void startTimer({bool resets = true}) {
    if (!mounted) return;
    timer = Timer.periodic(const Duration(seconds: 1), (_) => addTime());
  }
  void stopTimer() {
    if (!mounted) return;
    setState(() => timer?.cancel());
  }

  @override
  Widget build(BuildContext context) => Center(child: buildTime());

  Widget buildTime() {
    String twoDigits(int n) => n.toString().padLeft(2, "0");
    final twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
    final twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));

    return Text(
      '$twoDigitMinutes:$twoDigitSeconds',
      style: const TextStyle(
        fontSize: 80,
        fontWeight: FontWeight.bold,
      ),
    );
  }
}

相关问题