正如标题所说,我在使用Camera2 API录制三星Note5的视频时遇到了问题。 我已经从Camera2Video示例中调整了代码,但不同之处在于我使用CamcorderProfile类的配置选项设置MediaRecorder,并且在开始录制视频之前预览时,我同时使用ImageReader捕获和呈现预览到SurfaceTexture(该示例不使用ImageReader)。 这是我的startVideoCapture函数(与示例几乎相同)。
如果我从预览捕获中移除
无论我是否在
有人知道如何解决这个问题吗?
编辑:可能相关的一件事是,在此设备上使用
即使我只调用
private boolean startVideoCapture() {
if (null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) {
debugToast("Can't start video preview");
return false;
}
try {
closePreviewSession();
if(!setUpMediaRecorder())
{
debugToast("setUpMediaRecorder failed");
return false;
}
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
final CaptureRequest.Builder previewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
List<Surface> surfaces = new ArrayList<Surface>();
Surface previewSurface = new Surface(texture);
surfaces.add(previewSurface);
previewRequestBuilder.addTarget(previewSurface);
Surface recorderSurface = mMediaRecorder.getSurface();
surfaces.add(recorderSurface);
previewRequestBuilder.addTarget(recorderSurface);
mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
debugToast("onConfigured callback received");
mCaptureSession = cameraCaptureSession;
updateVideoPreview(previewRequestBuilder);
}
@Override
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
debugToast("onConfigureFailed");
}
}, mCallbacksInterface.getBackgroundHandler());
} catch (CameraAccessException e) {
e.printStackTrace();
debugToast("CameraAccessException");
return false;
} catch (IOException e) {
e.printStackTrace();
debugToast("IOException");
return false;
}
debugToast("startVideoCapture success");
return true;
}
以下是我设置图像阅读器的代码,用于启动预览:
// We set up a CaptureRequest.Builder with the output Surface.
CaptureRequest.Builder previewRequestBuilder = mCameraDevice
.createCaptureRequest(templateType);
previewRequestBuilder.addTarget(mImageReader.getSurface());
previewRequestBuilder.addTarget(surface);
// Here, we create a CameraCaptureSession for camera preview.
// surface),
mCameraDevice.createCaptureSession(
Arrays.asList(mImageReader.getSurface(), surface),
new CameraCaptureSession.StateCallback() {
// etc...
这些都是非常标准的内容,并且在Nexus 5上运行良好:我可以在捕获表面列表中使用ImageReader
开始一个预览捕获会话,然后停止它并在表面列表中使用MediaRecorder
启动新的捕获会话并录制视频。但是,在Note5上无法正常工作。当在startVideoCapture
中使用MediaRecorder
调用createCaptureSession
时会崩溃:
10-14 14:49:25.991: E/CameraCaptureSession(13566): Session 1: Failed to create capture session; configuration failed
10-14 14:49:26.011: W/System.err(13566): android.hardware.camera2.CameraAccessException: Operation timed out in camera service
10-14 14:49:26.011: W/System.err(13566): at android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:118)
10-14 14:49:26.021: W/System.err(13566): at android.hardware.camera2.utils.CameraBinderDecorator$CameraBinderDecoratorListener.onAfterInvocation(CameraBinderDecorator.java:73)
10-14 14:49:26.021: W/System.err(13566): at android.hardware.camera2.utils.Decorator.invoke(Decorator.java:81)
10-14 14:49:26.021: W/System.err(13566): at java.lang.reflect.Proxy.invoke(Proxy.java:393)
10-14 14:49:26.021: W/System.err(13566): at $Proxy1.waitUntilIdle(Unknown Source)
10-14 14:49:26.021: W/System.err(13566): at android.hardware.camera2.impl.CameraDeviceImpl.waitUntilIdle(CameraDeviceImpl.java:950)
10-14 14:49:26.021: W/System.err(13566): at android.hardware.camera2.impl.CameraDeviceImpl.configureStreamsChecked(CameraDeviceImpl.java:399)
10-14 14:49:26.021: W/System.err(13566): at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureSessionInternal(CameraDeviceImpl.java:561)
10-14 14:49:26.021: W/System.err(13566): at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureSession(CameraDeviceImpl.java:476)
10-14 14:49:26.021: W/System.err(13566): at com.example.Camera2Object.startVideoCapture(Camera2Object.java:2262)
如果我从预览捕获中移除
ImageReader
,那么它就可以正常工作。无论我是否在
closePreviewSession
中关闭ImageReader
都没有任何区别(我已经在预览CaptureSession
上调用了abortCaptures
和close
)。有人知道如何解决这个问题吗?
编辑:可能相关的一件事是,在此设备上使用
ImageReader
时,在onPause
中关闭CameraDevice
需要非常长的时间(长达6秒)。我已经通过在单独的线程中执行它来将其大部分隐藏在用户视野之外,但是如果在onPause
后的6秒内调用onResume
,则会出现延迟,因为我必须等待它完成关闭才能再次打开它。显然,当开始录制视频时,我无法承受6秒的延迟。即使我只调用
acquireLatestImage()
,关闭它并立即在ImageReader
的onImageAvailable
回调中返回,问题仍然存在。当ImageReader
的捕获分辨率非常小时,也会发生这种情况。因此,似乎不是由于处理ImageReader
数据过载引起的。
这里是从应用程序启动到录制视频(以及应用程序关闭)期间涵盖的系统日志。