我有一个媒体记录器挂在一个按钮上,按下按钮时进行记录,释放按钮时停止记录。代码运行良好:
mediaRecorder = new MediaRecorder();
mediaRecorder.Reset();
mediaRecorder.SetAudioSource(AudioSource.Mic);
mediaRecorder.SetOutputFormat(OutputFormat.AacAdts);
mediaRecorder.SetAudioEncoder(AudioEncoder.Aac);
mediaRecorder.SetAudioSamplingRate(16000);
mediaRecorder.SetOutputFile(storagePath);
mediaRecorder.Prepare();
mediaRecorder.Start();
然而,我发现用户不知道按钮需要保持按下状态,因此他们只是点击按钮,这导致 mediaRecorder.Stop() 执行得相对较快。这引发了异常:
Java.Lang.RuntimeException: stop failed.
at Java.Interop.JniEnvironment.InstanceMethods.CallVoidMethod(JniObjectReference instance, JniMethodInfo method, JniArgumentValue* args) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/obj/Release/net7.0/JniEnvironment.g.cs:line 20370
at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualVoidMethod(String encodedMember, IJavaPeerable self, JniArgumentValue* parameters) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs:line 66
at Android.Media.MediaRecorder.Stop() in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-34/mcw/Android.Media.MediaRecorder.cs:line 2477
我还可以通过同步执行prepare、start和stop来模拟这个错误。但是,我很困惑为什么会抛出异常,因为准备、开始和停止要在每一行执行后依次执行 - 所以理论上,准备和开始在停止到达之前就已经完成了。
mediaRecorder.Prepare(); mediaRecorder.Start(); mediaRecorder.Stop();
MediaPlayer 有一个 OnPrepared 事件,我可以挂钩该事件以确保准备完成。不幸的是,MediaRecorder 没有这样的事件。
如何通过停止抛出异常来避免此问题?
为了避免此问题,您可以使用最短录制时间阈值。我的应用程序中遇到同样的问题,然后我使用了下面的代码来帮助我解决我的问题。也许对你有用。
谢谢你
private long startTime;
private const long MINIMUM_RECORDING_DURATION = 1000; // 1 second
// When starting the recording
startTime = SystemClock.ElapsedRealtime();
mediaRecorder.Prepare();
mediaRecorder.Start();
// When stopping the recording
long elapsed = SystemClock.ElapsedRealtime() - startTime;
if (elapsed < MINIMUM_RECORDING_DURATION) {
// Delay stop to ensure the minimum duration
new Handler().PostDelayed(() => StopRecording(), MINIMUM_RECORDING_DURATION - elapsed);
} else {
StopRecording();
}
// StopRecording method
private void StopRecording() {
try {
mediaRecorder.Stop();
} catch (Java.Lang.RuntimeException ex) {
// Handle the stop failed exception
} finally {
mediaRecorder.Release();
}
}