Android无法使用前置摄像头录制视频,MediaRecorder启动失败:-19

时间:2013-02-04 06:53:06

标签: android video camera android-camera mediarecorder

我有两个不同的代码库,但问题相同。

第一个是直接从developer.android.com复制的代码: http://developer.android.com/guide/topics/media/camera.html#custom-camera

第二个是此代码:

http://android-er.blogspot.com.au/2011/10/simple-exercise-of-video-capture-using.html

普通后置摄像头都可以正常工作,但是一旦我尝试使用前置摄像头,我就会收到错误。

这在以下设备上发生:

  • Nexus S 4.1.2

  • Galaxy Nexus 4.1.2

  • Nexus 7 4.2.1(它只有前置摄像头)

我已经尝试过看起来像2.2时代的Camera Params,有些人认为需要一些三星和HTC设备,尽管有多篇不同的文章引用了不同的字符串键:

c = Camera.open(frontFacingCameraID); // attempt to get a Camera instance
Camera.Parameters params = c.getParameters();
params.set("cam-mode", 1);
params.set("cam_mode", 1);
params.set("camera-id", 1);
c.setParameters(params);

这些都不起作用,请注意我正在检测Nexus 7上正确的前置摄像头ID:0。但是所有设备的结果都是一样的。

我尝试使用低质量的配置文件,我尝试过多种方式手动设置视频分辨率,编码器,输出格式,比特率,帧速率和视频大小,但没有一种方法有效。

让我觉得大多数代码没有错的事情是普通相机工作正常。所以我的猜测是它与设置媒体记录器的prepareVideoRecorder()/ prepareMediaRecorder()方法有关。

也许Media Recorder手动编码已知可在前置摄像头上工作的设置?

我不得不说,Android相机和MediaRecorder API很糟糕。与iOS相比,它有点混乱,更不用说一些可怕的外观参数不兼容问题以及分散的设备环境中的不同分辨率。

假设我可以在我的JB设备上运行,有没有人从经验中知道大部分问题是否已通过API 15 ICS解决?

如果它太难以支持,我会考虑不支持API 10 Gingerbread。

6 个答案:

答案 0 :(得分:37)

我今天也在解决这个问题。

首先,确保您的权限设置正确。具体来说,要录制视频,您需要:

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

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

其次,这是一个棘手的部分,本教程中的这一行不适用于前置摄像头!

mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

CamcorderProfile.get()的签名默认为后置摄像头的配置文件:

  

以给定的质量级别返回设备上第一台后置摄像头的摄像机配置文件。如果    设备没有后置摄像头,返回null。

相反,请使用http://developer.android.com/reference/android/media/CamcorderProfile.html#get(int,%20int)。第一个参数是您打开的摄像机的ID,特别是前置摄像头。

答案 1 :(得分:24)

好的,所以我终于让它工作了。

这个问题似乎肯定与个人资料设置有关,尤其是帧速率。

在Nexus S上,如果我探测Camera.Parameters,我的主要测试设备:

后置摄像头:
15 FPS到30 FPS,足够公平。

前置摄像头:
7.5 FPS到30 FPS,好的。

然后我查看我尝试使用的配置文件:

CamcorderProfile.QUALITY_HIGH
CamcorderProfile.QUALITY_LOW

<强> QUALITY_LOW:
audioBitRate:12200
audioChannels:1
audioCodec:AMR_NB audioSampleRate:8000
持续时间:30
fileFormat:THREE_GPP
质量:0
videoBitRate:256000
videoCodec:H264
videoFrameRate:30
videoFrameWidth:176
videoFrameHeight:144

<强> QUALITY_HIGH:
audioBitRate:24000
audioChannels:1
audioCodec:AAC
audioSampleRate:16000
持续时间:60
fileFormat:MPEG_4
质量:1
videoBitRate:3000000
videoCodec:H264
videoFrameRate:30
videoFrameWidth:720
videoFrameHeight:480

显然,高质量配置文件适用于后置摄像头,前视镜面只有640x480。 但他们都表示30 FPS。

现在...

这是一种奇怪的现象。

如果我为后置摄像头设置任意帧速率,无论什么配置文件,它都会与可怕的:-19错误崩溃

mediaRecorder.setVideoFrameRate(fpsInt);

这不是什么大问题因为我不关心后置摄像头但它很奇怪,考虑到配置文件默认为30而Params说他们接受15-30。但是没有尝试过的int值有效。如果我省略了setVideoFrameRate就好了。

无论如何,转移到前置摄像头。

因此,如果我使用QUALITY_LOW配置文件并将帧速率设置为15或更低,它就会神奇地起作用。

mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
mediaRecorder.setVideoFrameRate(15);

事实上任何值,1 - 15都有效。这看起来很奇怪。

所以继续讨论这个问题,我可能会探测分辨率并为大多数相机选择合适的分辨率,尽管我对几乎所有前置摄像头都相当自信,最低VGA 640x480。

但是,帧率怎么样? 在Nexus S的情况下,我认为没有任何方法可以确定15或更低的值而不仅仅是猜测? 我是否应该始终使用相机返回的最低帧速率?

我看了一下Galaxy Nexus,它有3个帧速率范围,第一个是15 - 15,第二个是15 - 30。 其低质量的配置文件类似于更高的分辨率。 如果我在Galaxy Nexus上使用低调,它似乎工作正常。

使用Nexus 7,我无法探测CamcorderProfile,我一直得到空指针,这很奇怪。 它说它支持4 FPS - 60 FPS。 如果我选择你认为应该工作的QUALITY_LOW,它会崩溃,我无法找到它可以使用的帧速率。 虽然错误与setProfile有关,但我认为问题在于内置的配置文件。 当然,Android API的一点就是它的一致性,这是一款旗舰设备而且FF摄像机在那里用于视频会议不是吗?????

因此,虽然我使用手动自定义设置为两个设备工作,但我看不到通过代码在多个设备上使用它的明确方法。

似乎Nexus S的行为与它根据其Camera.getParameters()设置FPS的方式不同.getSupportedPreviewFpsRange()

我很高兴它使用自动FPS设置,但显然它不会使用FF相机,所以我该怎么办?我必须在Nexus S上明确设置FPS,在这种情况下可以设置1到15 FPS的任何值,尽管相机告诉我它可以处理7.5 - 30 FPS。

似乎setProfile的承诺解决了2.x中的所有问题并非完全正确。

我可以理解,如果您为特定ROM编写相机应用程序,您只需将其自定义为特定硬件,这可能解释了为什么人们似乎总是在自定义ROM上有错误的相机应用程序。但是......可下载的视频录制应用程序如何工作? 它们是针对每个设备定制的吗?

这就是为什么Android上还没有Facebook Poke和Twitter Vine ???? :P

Shit Google,wtf与你的Camera API有关吗?

是否有人知道确定所有API 15+兼容设备的分辨率和帧速率的最佳做法?

这是否可能,或者我是否会在我测试的每台设备上编写自定义代码,然后在其余设备上掷骰子?

或者Nexus S和Nexus 7只是发生了意外事故?

答案 2 :(得分:2)

尝试使用QUALITY_LOW,因为前置摄像头不支持QUALITY_HIGH。

答案 3 :(得分:1)

我现在几个小时一直在努力解决-19错误。对我来说,答案是Madhava的回应,尤其是mCamera.unlock();

即。结合有关设置配置文件的第一个答案,此代码

        Camera cam = Camera.open(frontCamID);
        cam.unlock();
        recorder.setCamera(cam);

允许我从前置摄像头中选择和录制。

答案 4 :(得分:0)

你应该看看这里 http://developer.android.com/guide/topics/media/camera.html#capture-video

那里列出的命令的顺序非常重要。

我使用了这里代码的第二个例子 How can I capture a video recording on Android?

并修改了开始录制功能

protected void startRecording() throws IOException 
{
    mrec = new MediaRecorder();  // Works well

    mCamera.setPreviewDisplay(surfaceHolder);
    mCamera.startPreview();

    mCamera.unlock();
    mrec.setCamera(mCamera);

    mrec.setPreviewDisplay(surfaceHolder.getSurface());
    mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    mrec.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); 

    mrec.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

    mrec.setOutputFile("/sdcard/zzzz.3gp");
    mrec.setPreviewDisplay(surfaceHolder.getSurface());

    mrec.prepare();
    mrec.start();
}

答案 5 :(得分:0)

我遇到了同样的问题。在我纠正了原因之后,我发现只有1个罪魁祸首。,720×480分辨率,这是相机中的默认值。我把它改成了什么,是的,我可以记录好