视频录制 - 无法启动相机预览

发布于 2024-12-09 00:50:06 字数 1805 浏览 5 评论 0原文

我正在开发一个自定义视频录制类,并且在活动首次出现时显示相机预览时遇到一些问题。我在 surfaceCreated 回调中调用此函数:

private void initRecorder(Surface surface) throws IOException {
// It is very important to unlock the camera before doing setCamera
// or it will results in a black preview
if(camera == null) {
    camera = Camera.open();
    camera.unlock();
}

if(recorder == null)
    recorder = new MediaRecorder();

recorder.setPreviewDisplay(surface);
recorder.setCamera(camera);

camera.startPreview();

recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setOutputFile("/sdcard/test.mp4");
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
recorder.setVideoEncodingBitRate(15000000);
recorder.setMaxDuration(10000); // length of video in MS
recorder.setVideoSize(720, 480);
recorder.setVideoFrameRate(30);


try {
    recorder.prepare();
} catch (IllegalStateException e) {
    // This is thrown if the previous calls are not called with the 
    // proper order
    e.printStackTrace();
}
}

当 Activity 启动时,我的应用程序崩溃并显示:

java.lang.RuntimeException: startPreview failed

在该错误之上,我注意到一个行说:

尝试使用来自不同进程的锁定相机(旧 pid 4894,新 pid 6405)

当我单步执行代码时,该错误发生在camera.startPreview() 行。如果我从代码中删除该行,则在调用 recorder.start() 后,预览会正常显示,而在此之前,我的录制按钮只是黑屏。一旦我停止录制,预览将继续显示良好(我在停止录制后调用 camera.startPreview())。

由于我在开始预览之前仅调用了几行 camera.unlock() ,并且这两个调用发生在同一个函数中,所以我怎么会出现此错误?

编辑:我在 Droid X2 和 Droid 1 上测试了相同的代码,减去对 startPreview() 的调用,并且运行良好。看来 EVO 4G 是问题所在。我将继续调查。

I'm working on a custom video recording class, and I'm having some issues getting the camera preview to display when the Activity first appears. I'm calling this function inside the surfaceCreated callback:

private void initRecorder(Surface surface) throws IOException {
// It is very important to unlock the camera before doing setCamera
// or it will results in a black preview
if(camera == null) {
    camera = Camera.open();
    camera.unlock();
}

if(recorder == null)
    recorder = new MediaRecorder();

recorder.setPreviewDisplay(surface);
recorder.setCamera(camera);

camera.startPreview();

recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setOutputFile("/sdcard/test.mp4");
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
recorder.setVideoEncodingBitRate(15000000);
recorder.setMaxDuration(10000); // length of video in MS
recorder.setVideoSize(720, 480);
recorder.setVideoFrameRate(30);


try {
    recorder.prepare();
} catch (IllegalStateException e) {
    // This is thrown if the previous calls are not called with the 
    // proper order
    e.printStackTrace();
}
}

When the Activity starts, my app crashes saying:

java.lang.RuntimeException: startPreview failed

Above that error, I noticed a line saying:

attempt to use a locked camera from a different process (old pid 4894, new pid 6405)

When I step through the code, that error is occurring on the camera.startPreview() line. If I remove that line from my code, the preview shows up fine after I call recorder.start(), and prior to that I just have a black screen with my record button. Once I stop recording, the preview continues to show fine (I am calling camera.startPreview() after I stop recording).

Since I'm calling camera.unlock() only a few lines prior to starting the preview, and the two calls occur in the same function, how can I be having this error?

Edit: I tested the same code minus the call to startPreview() on a Droid X2 and a Droid 1, and it works fine. It looks like the EVO 4G is the problem. I will continue to investigate.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

黯然 2024-12-16 00:50:07

我在这里回答了一个非常类似的问题:在android媒体记录器中预览显示

看看它是否对您有帮助,它有一个完整的活动,可用于预览并录制视频。

I answered a very similar question here: preview display in android media recorder

See if it helps you, it has a whole Activity that works with a preview and records a video.

魂归处 2024-12-16 00:50:07

camera.unlock() 必须从之前锁定相机的同一线程调用。检查日志中是否有消息,例如 Unlock call from pid 19322;当前锁定到 pid 17652

请注意,可以通过调用 Camera.lock()MediaRecorder.start() 设置锁定

自 API 级别 14 起,相机会自动锁定以下应用程序
MediaRecorder.start()。应用程序可以使用相机(例如:变焦)
录音开始后。录音后无需再调用
开始或停止。

camera.unlock() must be called from the same thread where camera was locked before. Check your logs for messages like Unlock call from pid 19322; currently locked to pid 17652.

Note that lock can be set by calling Camera.lock() or MediaRecorder.start()

Since API level 14, camera is automatically locked for applications in
MediaRecorder.start(). Applications can use the camera (ex: zoom)
after recording starts. There is no need to call this after recording
starts or stops.

不及他 2024-12-16 00:50:07

这样排列代码,降低视频编码率。对于您的视频大小而言,它非常高。这可能不会在您的设备上造成问题,因为在某些设备上它会在内部被剪辑。

private void initRecorder(Surface surface) throws IOException {
    // It is very important to unlock the camera before doing setCamera
    // or it will results in a black preview
    if (camera == null) {
        camera = Camera.open();
        camera.unlock();
    }

    if (recorder == null)
        recorder = new MediaRecorder();

    recorder.setCamera(camera);

    camera.startPreview();

    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
    recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    recorder.setVideoEncodingBitRate(2048000);
    recorder.setMaxDuration(10000); // length of video in MS
    recorder.setVideoSize(720, 480);
    recorder.setVideoFrameRate(30);
    recorder.setOutputFile("/sdcard/test.mp4");
    recorder.setPreviewDisplay(surface);
    try {
        recorder.prepare();
    } catch (IllegalStateException e) {
        // This is thrown if the previous calls are not called with the
        // proper order
        e.printStackTrace();
    }
}

Arrange code like this and decrease video encoding rate. It is very high for your video size. This may not be creating a problem on your device because on some devices it is clipped internally.

private void initRecorder(Surface surface) throws IOException {
    // It is very important to unlock the camera before doing setCamera
    // or it will results in a black preview
    if (camera == null) {
        camera = Camera.open();
        camera.unlock();
    }

    if (recorder == null)
        recorder = new MediaRecorder();

    recorder.setCamera(camera);

    camera.startPreview();

    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
    recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    recorder.setVideoEncodingBitRate(2048000);
    recorder.setMaxDuration(10000); // length of video in MS
    recorder.setVideoSize(720, 480);
    recorder.setVideoFrameRate(30);
    recorder.setOutputFile("/sdcard/test.mp4");
    recorder.setPreviewDisplay(surface);
    try {
        recorder.prepare();
    } catch (IllegalStateException e) {
        // This is thrown if the previous calls are not called with the
        // proper order
        e.printStackTrace();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文