【问题标题】:Android can't record video with Front Facing Camera, MediaRecorder start failed: -19Android 无法使用前置摄像头录制视频,MediaRecorder 启动失败:-19
【发布时间】:2013-01-18 20:31:33
【问题描述】:

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

第一个是直接从 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 时代的相机参数,有些人声称某些三星和 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 太难支持,我会考虑不支持它。

【问题讨论】:

    标签: android video camera android-camera mediarecorder


    【解决方案1】:

    我今天也遇到了这个问题。

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

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

    【讨论】:

    【解决方案2】:

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

    这个问题似乎肯定与Profile Settings,尤其是Frame Rate有关。

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

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

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

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

    CamcorderProfile.QUALITY_HIGH
    CamcorderProfile.QUALITY_LOW

    QUALITY_LOW:

    音频比特率:12200
    音频频道:1
    音频编解码器:AMR_NB 音频采样率:8000
    持续时间:30
    文件格式:THREE_GPP
    质量:0
    视频比特率:256000
    视频编解码器:H264
    视频帧率:30
    视频帧宽度:176
    视频帧高度:144

    QUALITY_HIGH:

    音频比特率:24000
    音频频道:1
    音频编解码器:AAC
    音频采样率:16000
    持续时间:60
    文件格式:MPEG_4
    质量:1
    视频比特率:3000000
    视频编解码器:H264
    视频帧率:30
    视频帧宽度:720
    视频帧高度: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 摄像头是用于视频会议的,不是吗?????

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

    在按照Camera.getParameters().getSupportedPreviewFpsRange() 设置 FPS 方面,Nexus S 似乎没有按照它承诺的方式行事

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

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

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

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

    Google,你的相机 API 是什么?

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

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

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

    【讨论】:

    • 您使用哪个调用来检索前置摄像头的摄像机配置文件?您应该使用 developer.android.com/reference/android/media/…, int),它将相机 ID 作为参数。单参数函数只为您提供主摄像头的定义。
    • 另外,您只能将developer.android.com/reference/android/hardware/… 的帧速率设置为developer.android.com/reference/android/hardware/… 中列出的值之一。如果使用范围设置方法 (setPreviewFpsRange),则必须使用 getSupportedPreviewFpsRange 中的值。
    • 带有相机 ID 的 Camera.Parameters 是有意义的,我试一试。 setPreviewFpsRange() 实际上与 MediaRecorder setVideoFrameRate() 有什么关系吗?还知道为什么 Nexus 7 上不存在配置文件吗?
    • 我遇到了一些像您描述的问题,只是想警告您,如果您尝试录制视频,询问相机的最佳 fps 或分辨率是不够的。相机可能能够报告它的内容,但媒体记录器可能更愚蠢。我看到 30 fps 不适用于相机报告的大多数情况(在索尼 xperia 平板电脑、google nexus 上试用)
    • @MadhavaJay 很棒的帖子,但是看看这个简单的解决方案stackoverflow.com/a/18477029/624109
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      我已经为 -19 错误苦苦挣扎了几个小时。我的答案是 Madhava 的回应,尤其是 mCamera.unlock();

      即结合关于set profile的第一个答案,这段代码

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

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

      【讨论】:

        【解决方案5】:

        你应该看看这里 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();
        }
        

        【讨论】:

        • 如果没有帮助,请尝试将质量更改为低 mrec.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
        • 不,这不起作用。您是否实际测试过该代码: mCamera = Camera.open(1);如果有人可以通过前置摄像头确认一组适用于他们的代码,那就太好了。我认为这与 Media Recorder 语句的顺序无关的原因是正常的后置摄像头每次都能正常工作。此外,前置摄像头在所有这些设备上的普通摄像头应用程序中都能正常工作,因此不会损坏。这真的没有意义。
        • E/MediaRecorder(24557):启动失败:-19
        【解决方案6】:

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

        【讨论】:

          猜你喜欢
          • 2016-10-25
          • 2016-01-19
          • 2015-07-30
          • 2016-12-30
          • 2012-06-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多