Android 视频录制 - mediaRecorder.start 上的 IllegalStateException

Posted

技术标签:

【中文标题】Android 视频录制 - mediaRecorder.start 上的 IllegalStateException【英文标题】:Android video recording - IllegalStateException on mediaRecorder.start 【发布时间】:2015-12-18 03:05:39 【问题描述】:

我正在关注https://developer.android.com/guide/topics/media/camera.html#capture-video上的教程

因此,我在尝试启动相机时遵循以下顺序:

    Camera.open camera.unlock mediaRecorder.setCamera mediaRecorder.setAudiosource mediaRecorder.setVideoSource mediaRecorder.setProfile mediaRecorder.setOutputFile mediaRecorder.prepare mediaRecorder.start

由于我按照指南运行 5.0.2,因此我可以弄清楚可能出了什么问题

private Camera mCamera;
private MediaRecorder mMediaRecorder;

public CameraActivity() 
    mCamera = getCameraInstance();
    mMediaRecorder = new MediaRecorder();


public static Camera getCameraInstance()
    Camera c = null;
    try 
        c = Camera.open();
    
    catch (Exception e)  ... 
    return c;


public void startRecording() 

    mCamera.unlock();
    mMediaRecorder.setCamera(mCamera);

    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
    mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());

    try 
        mMediaRecorder.prepare();
    
    catch (IOException e)  ... 
    catch (IllegalStateException e)  ... 

    try 
        mMediaRecorder.start();
    
    catch (Exception e) 
        Log.d(TAG, "exception on mediaRecorder.start" + e.toString()); // This is the exception that gets thrown on .start
    

我的清单包含所有必要的权限

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.microphone" />

我也尝试过手动设置格式而不是使用 .setProfile,结果相同

    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);

更新

该文件确实已创建,尽管它当然无法播放,所以我知道它一直在工作。对 prepare 的调用不会引发异常,并且发生在 start 之前。在 start() 上抛出相同的异常

【问题讨论】:

我只是看了一下我的代码,我配置的东西比你多。但我认为主要区别是mediaRecorder.setVideoSize(int width, int height)mediaRecorder.setPreviewDisplay(SurfaceHolder surfaceHolder)。也许设置其中之一可能有助于使其正常工作。顺便说一句,你能粘贴你的堆栈跟踪吗? @EdsonMenegatti 感谢您的回复...我没有使用预览窗口,所以我认为我不需要这些调用,但我会尝试添加 setVideoSize 以查看是否可以解决问题。我将在今天晚些时候发布完整的堆栈跟踪 这是否意味着您根本没有显示任何相机预览? @EdsonMenegatti 这是正确的。出于我的目的,我想录制视频但不显示预览窗口。我现在正在处理的基本部分只是一个开始/停止录制按钮并将视频文件保存在某个地方......仍然很惊讶它证明这很麻烦! 不幸的是你不能这样做。在 Android 中,如果您想录制,则必须提供相机预览。它以这种方式实现以防止隐藏的相机应用程序。 SO中有很多相关的问题,但是看看这个链接***.com/questions/2386025/… 【参考方案1】:

比较我的代码,您似乎缺少两个调用:

mediaRecorder.setVideoSize(int width, int height)
mediaRecorder.setPreviewDisplay(SurfaceHolder surfaceHolder)

后者最有可能导致崩溃,因为 Android 需要有效的预览界面才能开始录制。这样做是为了防止隐藏的摄像头应用。

有几十个与没有预览表面的录制相关的问题,但这个one 似乎总结了你需要做什么来绕过这个限制。 基本思想是将您的表面调整为 1x1 并将其传递给您的 mediaRecorder 实例。请记住,这可能不适用于所有设备。

【讨论】:

谢谢@Edson 原来我没有包括导致失败的预览。按照我的问题中链接的指南,我添加了预览类并附加了表面视图,解决了我的问题。【参考方案2】:

如果您多次访问麦克风硬件,例如,一次使用 MediaRecorder 和 AudioRecord 类也会出现此异常。

【讨论】:

以上是关于Android 视频录制 - mediaRecorder.start 上的 IllegalStateException的主要内容,如果未能解决你的问题,请参考以下文章

android实时视频网络传输方案总结(一共有五套)

使用表面视图android录制视频

Android:视频录制输出方向翻转

在android中使用OpenCV录制视频

Android - 录制视频时预览调整大小

如何在我的 Android 应用中录制视频?