audio_recorder
audio_recorder copied to clipboard
`RuntimeException` on stop
If you quickly start and stop a recording, a RuntimeException is thrown from Java, resulting in a PlatformException in Flutter:
D/AudioRecorder(12194): Start
D/AudioRecorder(12194): /data/user/0/dev.hugopassos.buster/cache/af313050-56be-4ec8-b821-2cad871a9cc7.m4a
D/AudioRecorder(12194): Stop
E/MediaRecorder(12194): stop failed: -1007
E/MethodChannel#audio_recorder(12194): Failed to handle method call
E/MethodChannel#audio_recorder(12194): java.lang.RuntimeException: stop failed.
E/MethodChannel#audio_recorder(12194): at android.media.MediaRecorder.stop(Native Method)
E/MethodChannel#audio_recorder(12194): at com.jordanalcaraz.audiorecorder.audiorecorder.AudioRecorderPlugin.stopNormalRecording(AudioRecorderPlugin.java:134)
E/MethodChannel#audio_recorder(12194): at com.jordanalcaraz.audiorecorder.audiorecorder.AudioRecorderPlugin.stopRecording(AudioRecorderPlugin.java:128)
E/MethodChannel#audio_recorder(12194): at com.jordanalcaraz.audiorecorder.audiorecorder.AudioRecorderPlugin.onMethodCall(AudioRecorderPlugin.java:66)
E/MethodChannel#audio_recorder(12194): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:222)
E/MethodChannel#audio_recorder(12194): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:96)
E/MethodChannel#audio_recorder(12194): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:643)
E/MethodChannel#audio_recorder(12194): at android.os.MessageQueue.nativePollOnce(Native Method)
E/MethodChannel#audio_recorder(12194): at android.os.MessageQueue.next(MessageQueue.java:325)
E/MethodChannel#audio_recorder(12194): at android.os.Looper.loop(Looper.java:142)
E/MethodChannel#audio_recorder(12194): at android.app.ActivityThread.main(ActivityThread.java:6494)
E/MethodChannel#audio_recorder(12194): at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#audio_recorder(12194): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
E/MethodChannel#audio_recorder(12194): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
E/flutter (12194): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: PlatformException(error, stop failed., null)
E/flutter (12194): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:564:7)
E/flutter (12194): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:316:33)
E/flutter (12194): <asynchronous suspension>
E/flutter (12194): #2 AudioRecorder.stop (package:audio_recorder/audio_recorder.dart:49:33)
E/flutter (12194): <asynchronous suspension>
E/flutter (12194): #3 new Future.delayed.<anonymous closure> (dart:async/future.dart:316:39)
E/flutter (12194): #4 _rootRun (dart:async/zone.dart:1120:38)
E/flutter (12194): #5 _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter (12194): #6 _CustomZone.runGuarded (dart:async/zone.dart:923:7)
E/flutter (12194): #7 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:963:23)
E/flutter (12194): #8 _rootRun (dart:async/zone.dart:1124:13)
E/flutter (12194): #9 _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter (12194): #10 _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:947:23)
E/flutter (12194): #11 Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:21:15)
E/flutter (12194): #12 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:382:19)
E/flutter (12194): #13 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:416:5)
E/flutter (12194): #14 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)
You should be able to reproduce this issue with the following snippet:
import 'package:audio_recorder/audio_recorder.dart';
import 'package:flutter/material.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:uuid/uuid.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Foo(),
);
}
}
class Foo extends StatelessWidget {
static final _uuid = Uuid();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
child: Text('Quickly start and stop recording'),
onPressed: quicklyStartAndStopRecording,
),
),
);
}
Future<void> quicklyStartAndStopRecording() async {
await PermissionHandler().requestPermissions([PermissionGroup.microphone]);
final directory = await getTemporaryDirectory();
final path = join(directory.path, '${_uuid.v4()}.m4a');
await AudioRecorder.start(
path: path,
audioOutputFormat: AudioOutputFormat.AAC,
);
await Future.delayed(
const Duration(milliseconds: 100),
AudioRecorder.stop,
);
}
}
Pubspec dependencies:
dependencies:
flutter:
sdk: flutter
path_provider: ^1.3.0
path: ^1.6.2
uuid: ^2.0.2
permission_handler: ^3.2.2
audio_recorder: ^1.0.1
@ZaraclaJ
To make matters worse, you cannot stop the recording after is error was thrown. Also, await AudioRecorder.isRecording stays returning true.
If you try to call AudioRecorder.stop() again:
D/AudioRecorder(13610): Stop
E/MediaRecorder(13610): stop called in an invalid state: 0
E/MethodChannel#audio_recorder(13610): Failed to handle method call
E/MethodChannel#audio_recorder(13610): java.lang.IllegalStateException
E/MethodChannel#audio_recorder(13610): at android.media.MediaRecorder.stop(Native Method)
E/MethodChannel#audio_recorder(13610): at com.jordanalcaraz.audiorecorder.audiorecorder.AudioRecorderPlugin.stopNormalRecording(AudioRecorderPlugin.java:134)
E/MethodChannel#audio_recorder(13610): at com.jordanalcaraz.audiorecorder.audiorecorder.AudioRecorderPlugin.stopRecording(AudioRecorderPlugin.java:128)
E/MethodChannel#audio_recorder(13610): at com.jordanalcaraz.audiorecorder.audiorecorder.AudioRecorderPlugin.onMethodCall(AudioRecorderPlugin.java:66)
E/MethodChannel#audio_recorder(13610): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:222)
E/MethodChannel#audio_recorder(13610): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:96)
E/MethodChannel#audio_recorder(13610): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:643)
E/MethodChannel#audio_recorder(13610): at android.os.MessageQueue.nativePollOnce(Native Method)
E/MethodChannel#audio_recorder(13610): at android.os.MessageQueue.next(MessageQueue.java:325)
E/MethodChannel#audio_recorder(13610): at android.os.Looper.loop(Looper.java:142)
E/MethodChannel#audio_recorder(13610): at android.app.ActivityThread.main(ActivityThread.java:6494)
E/MethodChannel#audio_recorder(13610): at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#audio_recorder(13610): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
E/MethodChannel#audio_recorder(13610): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
E/flutter (13610): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: PlatformException(error, null, null)
E/flutter (13610): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:564:7)
E/flutter (13610): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:316:33)
E/flutter (13610): <asynchronous suspension>
E/flutter (13610): #2 AudioRecorder.stop (package:audio_recorder/audio_recorder.dart:49:33)
E/flutter (13610): <asynchronous suspension>
E/flutter (13610): #3 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:635:14)
E/flutter (13610): #4 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:711:32)
E/flutter (13610): #5 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
E/flutter (13610): #6 TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:365:11)
E/flutter (13610): #7 TapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:275:7)
E/flutter (13610): #8 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:455:9)
E/flutter (13610): #9 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:75:13)
E/flutter (13610): #10 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:102:11)
E/flutter (13610): #11 _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19)
E/flutter (13610): #12 _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
E/flutter (13610): #13 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
E/flutter (13610): #14 _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
E/flutter (13610): #15 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
E/flutter (13610): #16 _rootRunUnary (dart:async/zone.dart:1136:13)
E/flutter (13610): #17 _CustomZone.runUnary (dart:async/zone.dart:1029:19)
E/flutter (13610): #18 _CustomZone.runUnaryGuarded (dart:async/zone.dart:931:7)
E/flutter (13610): #19 _invoke1 (dart:ui/hooks.dart:250:10)
E/flutter (13610): #20 _dispatchPointerDataPacket (dart:ui/hooks.dart:159:5)
it seems it is a bug. here facing with the same issue!
may cause by stop() is called immediately after start()... i tried `` try { mRecorder.stop(); mRecorder.reset(); mRecorder.release(); mRecorder = null; }catch (RuntimeException e){
}` ``
Is there a better way?