Canardoux / flutter_sound

Flutter plugin for sound. Audio recorder and player.
Mozilla Public License 2.0
876 stars 570 forks source link

There is a problem with onRecorderStateChanged on ios #324

Closed zhangruiyu closed 4 years ago

zhangruiyu commented 4 years ago

When I first record and play what I just recorded, and then I click on record again, onRecorderStateChanged has a 0 result all the way and cannot be recorded ''' import 'dart:io';

import 'package:chongmeng/constants/constants.dart'; import 'package:chongmeng/utils/date_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_sound/flutter_sound_player.dart'; import 'package:flutter_sound/flutter_sound_recorder.dart'; import 'package:intl/intl.dart'; import 'package:path_provider/path_provider.dart';

class PlayPage extends StatefulWidget { @override _PlayPageState createState() => _PlayPageState(); }

class _PlayPageState extends State { FlutterSoundPlayer soundPlayer; FlutterSoundRecorder soundRecorder; var recorderSubscription; var result;

@override void initState() { super.initState(); init(); }

init() async { soundPlayer = await FlutterSoundPlayer().initialize(); soundRecorder = await FlutterSoundRecorder().initialize(); }

void _onStartRecord() async { showToast("_onStartRecord"); Directory tempDir = await getTemporaryDirectory(); File outputFile = File('${tempDir.path}/${DateUtils.currentTimeMillis()}.aac'); result = outputFile.path; String a = await soundRecorder.startRecorder(uri: outputFile.path);

recorderSubscription = soundRecorder.onRecorderStateChanged.listen((e) {
  DateTime date =
      new DateTime.fromMillisecondsSinceEpoch(e.currentPosition.toInt());
  String txt = DateFormat('mm:ss:SS', 'en_US').format(date);

// if (txt.contains("00:02")) { // _onStopRecord(); // } }); soundRecorder.onRecorderDbPeakChanged.listen((value) { print("got update -> $value"); }); }

Future _onStopRecord() async { showToast("_onStopRecord"); print("_onStopRecord "); String localUrl = await soundRecorder.stopRecorder(); if (recorderSubscription != null) { recorderSubscription.cancel(); recorderSubscription = null; } }

@override void dispose() { soundRecorder.release(); soundPlayer.release(); super.dispose(); }

_onStartPlay() async { showToast("_onStartPlay"); soundPlayer.startPlayer(this.result); }

@override Widget build(BuildContext context) { return Container( child: Column( children: [ IconButton( icon: Icon(Icons.record_voice_over), onPressed: () { _onStartRecord(); }, ), Padding( padding: const EdgeInsets.symmetric(vertical: 24), child: RaisedButton( child: Text("OK"), onPressed: () { _onStopRecord(); }, ), ), IconButton( icon: Icon(Icons.play_arrow), onPressed: () { _onStartPlay(); }, ), ], ), ); } }

'''

Larpoux commented 4 years ago

At first seeing your code seems correct. Of course, do not try to hit your 'Play' or 'Record' buttons during a recording.

bsutton commented 4 years ago

I'm working on integrating a recording widget into 5.0. As part that I expect to have a 'controller' which can be used to co-ordinating our recording widgets state with a players state. The controller will not allow a player which is 'attached' to a recorder (via the controller) to playback whilst recording is underway.

You can still have any number of other unattached players.

zhangruiyu commented 4 years ago

At first seeing your code seems correct. Of course, do not try to hit your 'Play' or 'Record' buttons during a recording.

I may not express it accurately. The current method call sequence is as follows 1._onStartRecord () 2._onStopRecord () 3._onStartPlay () 4._onStartRecord () 5._Onstoprecord(), onrecorderstatechanged will return 0 on the second recording and cannot play the second recorded audio

zhangruiyu commented 4 years ago

The ios simulator is fine, but it's available on your phone

Larpoux commented 4 years ago

1._onStartRecord () 2._onStopRecord () 3._onStartPlay () 4._onStartRecord ()

I suspect that your problem is caused by trying to record during a playback. Flutter Sound is supposed to handle that correctly, but this is something which has probably not been tested very intensively.

Please, keep this issue open. I will try to find time for looking to it.

zhangruiyu commented 4 years ago

1._onStartRecord () 2._onStopRecord () 3._onStartPlay () 4._onStartRecord ()

I suspect that your problem is caused by trying to record during a playback. Flutter Sound is supposed to handle that correctly, but this is something which has probably not been tested very intensively.

Please, keep this issue open. I will try to find time for looking to it.

But I didn't do that. If you follow the above steps, the second recording does not succeed, but it only exists on the mobile phone

zhangruiyu commented 4 years ago

can someone help me 0-0

Larpoux commented 4 years ago

Do you try to record a new file, or the file which is currently played back ?

zhangruiyu commented 4 years ago

Do you try to record a new file, or the file which is currently played back ?

It's a new file, and it works on android and ios emulators

Gibsouille commented 4 years ago

Hello there,

Same for me. Let us know if someone find a solution, a workaround, or even just the cause of this problem.

Thanks for what you're doin'!

Larpoux commented 4 years ago

Hi guys/girls,

We really need your logs if you want that we can do something for your problems.

Gibsouille commented 4 years ago

I cannot give you our logs but I've just found how to reproduce the problem with the plugin example project. First, switch "Track player" on. Then :

Larpoux commented 4 years ago

πŸ‘Ž It seems that we have a "little" problem. πŸ‘Ž I am going to fix that, now. Sorry for the inconvenient.

Gibsouille commented 4 years ago

It may not be a definitive solution, but I've found a workaround. Maybe it can help @zhangruiyu and other people in the same situation, and maybe it could help improving this plugin. The workaround is to release and then initialize again the recorder module before calling startRecorder(). In the case of @zhangruiyu, it would be :

void _onStartRecord() async {
  await soundRecorder.release();
  await soundRecorder.initialize();

  showToast("_onStartRecord");
  Directory tempDir = await getTemporaryDirectory();
  File outputFile = File('${tempDir.path}/${DateUtils.currentTimeMillis()}.aac');
  result = outputFile.path;
  String a = await soundRecorder.startRecorder(uri: outputFile.path);

  recorderSubscription = soundRecorder.onRecorderStateChanged.listen((e) {
    DateTime date = new DateTime.fromMillisecondsSinceEpoch(e.currentPosition.toInt());
    String txt = DateFormat('mm:ss:SS', 'en_US').format(date);
  });

  soundRecorder.onRecorderDbPeakChanged.listen((value) {
    print("got update -> $value");
  });
}
Gibsouille commented 4 years ago

πŸ‘Ž It seems that we have a "little" problem. πŸ‘Ž I am going to fix that, now. Sorry for the inconvenient.

Thank you for your job!

Larpoux commented 4 years ago

Hi @Gibsouille ,

could you look to V 4.0.5 and see if better ?

zhangruiyu commented 4 years ago

V4.0.5 has fixed this problem, thumbs up

Larpoux commented 4 years ago

Hi @zhangruiyu , I am glad that the issue is fixed. I am really sorry for the delay : the problem occurred on real devices and not the simulator. It was not easy for us to debug that.

Good luck, using Flutter Sound. πŸ˜„