23

我有两个不同的代码库有同样的问题。

第一个是直接从 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

两者都可以正常使用普通后置摄像头,但是一旦我尝试使用前置摄像头,就会出现错误。

这发生在以下设备上:

  • 连结 S 4.1.2

  • 银河 Nexus 4.1.2

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

我也尝试过看起来像 2.2 时代的相机参数,有些人声称某些三星和 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);

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

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

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

也许是已知可在前置摄像头上使用的媒体记录器手动编码设置?

我不得不说,Android Camera 和 MediaRecorder API 很烂。与 iOS 相比,它有点混乱,更不用说一些看起来很吓人的参数不兼容问题以及碎片化设备环境中的不同分辨率。

假设我可以让它在我的 JB 设备上运行,有没有人从经验中知道 API 15 ICS 是否解决了大多数这些问题?

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

4

6 回答 6

39

我今天也为这个问题苦苦挣扎。

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

<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,具体来说就是前置摄像头。

于 2013-03-04T17:42:15.837 回答
26

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

这个问题似乎肯定与Profile Settings特别是Frame Rate.

在我的主要测试设备 Nexus S 上,如果我探测相机,我会收到以下参数:

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

对于前置摄像头:
7.5 FPS 到 30 FPS,可以。

然后我检查我正在尝试使用的配置文件:

CamcorderProfile.QUALITY_HIGH
CamcorderProfile.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

质量_高:

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 在设置 FPS 方面并没有按照其承诺的方式行事Camera.getParameters().getSupportedPreviewFpsRange()

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

似乎setProfile在 2.x 中修复所有问题的承诺并不完全正确。

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

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

谷歌,你的相机 API 是什么?

有谁知道确定所有API 15+兼容设备的分辨率和帧速率的“最佳实践”?

这甚至可能吗,还是我要在我测试的每台设备上编写自定义代码,然后在其余设备上掷骰子?

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

于 2013-02-06T09:38:18.243 回答
3

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

于 2014-08-26T17:07:36.937 回答
2

几个小时以来,我一直在为 -19 错误而苦苦挣扎。我的答案是 Madhava 的回应,尤其是 mCamera.unlock();

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

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

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

于 2014-08-28T14:21:51.110 回答
1

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

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

我使用了此处代码的第二个示例 如何在 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();
}
于 2013-02-04T08:56:34.447 回答
1

我有同样的问题。在我纠正了原因后,我发现只有 1 个罪魁祸首。,720×480 分辨率,这是相机的默认分辨率。我把它改成了任何东西,是的,我可以很好地记录它

于 2016-10-24T10:20:52.693 回答