Захват и запись на TextureView с камерой2?
Я пытаюсь создать простое приложение, в котором вы можете снимать изображения и записывать видео с новой камеры Android2 на поверхности TextureView, которая показывает предварительный просмотр камеры. Я создал кнопку для захвата изображения, но мне хотелось бы знать, возможно ли на одной поверхности записывать видео. Я бы не знал, как обращаться с функцией SurfaceTexture.OnFrameAvailableListener, на самом деле, я хотел бы знать, правильно ли обрабатывать запись видео таким образом.
Я попытался увидеть два примера camera2basic и camera2video, но мне не удалось запустить их в моем приложении. Наконец, я хотел спросить: возможно ли сделать снимок во время видеозаписи?
Эти два метода:
protected void takePicture() {
if (cameraDevice == null) {
Log.e(TAG, "cameraDevice is null");
return;
}
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraDevice.getId());
Size[] jpegSizes = null;
if (cameraCharacteristics != null)
{
jpegSizes = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
}
int width = 640;
int height = 480;
if (jpegSizes != null && jpegSizes.length > 0) {
width = jpegSizes[0].getWidth();
height = jpegSizes[0].getHeight();
}
ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
List<Surface> outputSurfaces = new ArrayList<>(2);
outputSurfaces.add(reader.getSurface());
outputSurfaces.add(new Surface(textureView.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE );
captureBuilder.addTarget(reader.getSurface());
//captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// Orientation
int rotation = getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
//final File file = new File(Environment. + "/picture.jpg");
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
Date today = Calendar.getInstance().getTime();
String logDate = dateFormat.format(today);
final File file = new File(getApplication().getExternalFilesDir(null), "pic.jpg");
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
try {
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (image != null) {
image.close();
}
}
}
private void save(byte[] bytes) throws IOException {
OutputStream output = null;
try
{
output = new FileOutputStream(file);
output.write(bytes);
}
finally
{
if (null != output) {
output.close();
}
}
}
};
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
Toast.makeText(MainActivity.this, "Salvato il file:" + file, Toast.LENGTH_SHORT).show();
createCameraPreview();
}
};
cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
try {
session.capture(captureBuilder.build(), captureListener, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
protected void takeVideo() {
if (cameraDevice == null) {
Log.e(TAG, "cameraDevice is null");
return;
}
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
String cameraId = cameraManager.getCameraIdList()[0];
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
StreamConfigurationMap scm = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if (scm == null) {
throw new RuntimeException("Cannot get available preview/video sizes");
}
scm.getOutputSizes(SurfaceTexture.class);
SurfaceTexture texture = textureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(640, 480);
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD );
Surface previewSurface = new Surface(texture);
captureBuilder.addTarget(previewSurface);
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
Date today = Calendar.getInstance().getTime();
String logDate = dateFormat.format(today);
final File file = new File(getApplication().getExternalFilesDir(null), "video.mp4");
SurfaceTexture.OnFrameAvailableListener readerListener = new SurfaceTexture.OnFrameAvailableListener() {
@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
}
private void save(byte[] bytes) throws IOException {
OutputStream output = null;
try
{
output = new FileOutputStream(file);
output.write(bytes);
}
finally
{
if (null != output) {
output.close();
}
}
}
};
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
Toast.makeText(MainActivity.this, "Salvato il video:" + file, Toast.LENGTH_SHORT).show();
createCameraPreview();
}
};
}
catch (CameraAccessException e) {
e.printStackTrace();
}
}