我正在构建一个应用程序,我需要在显示视频时无需预览即可录制相机。
我正在使用已弃用的类android.hardware.camera
,因为它符合我的需要。我一直遇到MediaRecorder课程的问题。
我设置了所有myMediaRecorder所需的参数,如下面的代码所示:
if (myMediaRecorder == null) {
myMediaRecorder = new MediaRecorder();
}
try {
if (myCamera == null) {
myCamera = Camera.open(Integer.parseInt(getFrontFacingCameraId()));
}
myCamera.unlock();
myMediaRecorder.setCamera(myCamera);
//myCamera.lock();
myMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
myMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
myMediaRecorder.setVideoSize(myVideoView.getWidth(),myVideoView.getHeight());
myMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); myMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT); myMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
myMediaRecorder.setOutputFile(new FileOutputStream(outputFile.getAbsolutePath()).getFD());
myMediaRecorder.setVideoFrameRate(30);
myMediaRecorder.prepare();
} catch (Exception ex) {
ex.printStackTrace();
}
然后我添加了Listeners来处理与我播放视频和录制内容相关的触发器,如您所见。
playButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
myVideoView.requestFocus();
myVideoView.start();
myMediaRecorder.start();
playButton.setText("isRecording");
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
myVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
myMediaRecorder.stop();
myMediaRecorder.release();
myMediaRecorder=null;
myCamera.release();
myCamera=null;
playButton.setText("stopped Recording");
}
});
我的目标是SDK版本25,其中minSdkVersion设置为23.我在清单和编码中都明确声明了以下权限:
相机,录制音频,写入&阅读外部存储。
加上我的清单中的那些:
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.front" />
我的主要问题是我无法访问MediaRecorder当前状态,这会在调用start和stop方法时导致非法状态。
您可以在此处阅读我的堆栈跟踪:
E/ExtendedMediaRecorder: start called in an invalid state: 2 mIsPaused = 0
W/System.err: java.lang.IllegalStateException
W/System.err: at android.media.MediaRecorder.start(Native Method)
W/System.err: at com.reacteam.reactoplayer.PlayerActivity$1.onClick(PlayerActivity.java:125)
W/System.err: at android.view.View.performClick(View.java:5205)
W/System.err: at android.view.View$PerformClick.run(View.java:21164)
W/System.err: at android.os.Handler.handleCallback(Handler.java:739)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err: at android.os.Looper.loop(Looper.java:167)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5514)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
W/MediaPlayer: info/warning (3, 0)
E/ExtendedMediaRecorder: stop called in an invalid state: 2
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.reacteam.reactoplayer, PID: 19210
java.lang.IllegalStateException
at android.media.MediaRecorder.stop(Native Method)
at com.reacteam.reactoplayer.PlayerActivity$2.onCompletion(PlayerActivity.java:135)
at android.widget.VideoView$3.onCompletion(VideoView.java:483)
at android.media.MediaPlayer$EventHandler.handleMessage(MediaPlayer.java:2821)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:167)
at android.app.ActivityThread.main(ActivityThread.java:5514)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
我已经为我的MediaRecorder声明尝试了很多不同的架构,无可救药。
我可能错过了一些至关重要但我主要的失望是无法以这种方式访问MediaRecord
if (myMediaRecord.getState() == "PREPARED") {
myMediaRecord.start();
}
请注意,我在prepare()语句之后添加了我的侦听器。
我的问题是,我做错了什么吗?我是否被迫使用Camera2 Api,我发现它很复杂,没什么优势?有没有办法在没有MediaRecorder Api的情况下录制相机输入?