Android MediaRecorder保存空文件和奇怪的相机行为

时间:2016-12-19 10:16:06

标签: android video camera mediarecorder recording

我对于Android的Camera API 1感到头疼。阅读完所有互联网内容后,我制作了一些可行的示例应用程序。它会创建一个服务,然后用于在后台运行相机,因此无法启用预览或活动。为此,我使用了一个虚拟SurfaceHolder,如下所示:

protected class MySurfaceHolder implements SurfaceHolder {
        private final Surface surface;
        private final SurfaceTexture surfaceTexture;

        public MySurfaceHolder () {
            int[] textures = new int[1];
            GLES20.glGenTextures(1, textures, 0);

            if (textures.length > 0) {
                this.surfaceTexture = new SurfaceTexture(textures[0]);
                this.surface = new Surface(this.surfaceTexture);
            } else {
                this.surface = null;
                this.surfaceTexture = null;
            }
        }

        [...]
}

然后我像这样使用它

    // simplified version of my code
    try {
        initializeCamera(); // open camera and set Camera.Parameters

        camera.setPreviewDisplay(new MySurfaceHolder());
        camera.startPreview();
        camera.unlock();

        initializeMediaRecorder(); // create MediaRecorder, set video/audio parameters

        mediaRecorder.prepare();
        mediaRecorder.start();
        // wait until recording finish and exit
    } finally {
        stopRecording();
    }

Camera和MediaRecorder初始化方法就像它们应该的文档状态(并且它们可以工作)。

一切都按照预期运作和运作。几乎所有事情 - 有时,在未知的情况下,MediaRecorder会创建空文件,例如32kB只包含标题和视频信息 - 没有帧。我记录的时间越长,文件就越大(每隔几秒几毫卢比)。 1分钟后,文件重量约为80kB。有趣的是我知道相机正在工作并捕捉帧(我调试了一点显示预览帧),但帧没有写入输出文件。

当它发生时我无法以FHD(1920x1080)录制 - 我得到了#34;开始失败"消息 - 此时相机未捕获帧。当我使用错误(不支持)的视频大小时,可能会发生同样的事情。我想在这种情况下,消息将被引入mediaRecorder.start(); line,和stopRecording();被调用,但我不确定。

经过一段时间或不明行动之后,问题突然消失了(我不知道什么时候,我不知道怎么回事)。它肯定会在Android 5.1上发生,但也可能在其他版本上发生。

  1. 这个错误可能与我的自定义表面代码有关吗?
  2. 什么可能导致MediaRecorder不将帧写入文件?
  3. 为什么我无法录制FHD,但同时我能录制高清(1280x720)?
  4. MediaRecorder是否有其他选择,所以我可以避免这些错误?
  5. 当另一个应用程序试图获取Camera对象时会发生这种情况,从而破坏当前的录制吗?如果是这样,如何重新获得对Camera对象的访问权限(我显然现在无法在某些设备上执行此操作)。
  6. 修改

    我想我可能有一个线索。我在打电话

    camera.setOneShotPreviewCallback(new Camera.PreviewCallback() {
        // ... get current frame
    }
    camera.startPreview();
    

    获取当前录制的预览帧。当我使用此方法获取预览帧(随机时间)时,似乎会出现错误。它似乎有缺陷,因为并非所有设备都能正确地对此事做出反应(有时候没有预览框......)。是否还有其他更好的方法来处理当前预览框架而没有真实表面?

0 个答案:

没有答案