使用 camera2接口,版本号为28 。
package com.example.camera01;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executor;
public class rtsp extends AppCompatActivity implements MediaRecorder.OnInfoListener, View.OnClickListener {
private CameraManager mCameraManager;
private static final int REQUEST_CAMERA_PERMISSION = 1;
public static final String TAG = "LoginActivity";
CameraDevice mCameraDevice;
CameraCaptureSession mCaptureSession;
private MediaRecorder mMediaRecorder;
private HandlerThread mHandlerThread;
private Handler mHandler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void onResume() {
super.onResume();
if (!checkCameraPermission())
return;
setContentView(R.layout.main);
this.findViewById(R.id.stop).setOnClickListener(this);
startStreaming(this);
}
@Override
protected void onPause() {
super.onPause();
if (mCameraDevice != null) {
mCameraDevice.close();
}
}
private boolean checkCameraPermission() {
int cameraPermission1 = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
int cameraPermission2 = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
int cameraPermission3 = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO);
int cameraPermission4 = ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET);
if (cameraPermission1 != PackageManager.PERMISSION_GRANTED || cameraPermission2 != PackageManager.PERMISSION_GRANTED
|| cameraPermission3 != PackageManager.PERMISSION_GRANTED|| cameraPermission4 != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.INTERNET,Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, REQUEST_CAMERA_PERMISSION);
return false;
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CAMERA_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.e(TAG, "权限授予成功,可以进行拍照操作 PERMISSION_GRANTED");
// 权限授予成功,可以进行拍照操作
} else {
Log.e(TAG, "权限授予失败,无法进行拍照操作");
//
}
}
}
public void startStreaming(Context context) {
try {
// 创建 HandlerThread,用于在单独的线程上运行摄像头操作
mHandlerThread = new HandlerThread("Camera2 Thread");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
// 获取摄像头管理器
mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
// 获取可以用于录制视频的摄像头列表
String[] cameraIds = mCameraManager.getCameraIdList();
for (String cameraId : cameraIds) {
CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(cameraId);
Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
if (facing != null && facing == CameraCharacteristics.LENS_FACING_BACK) {
// 如果后置摄像头可用,使用它来录制视频
StreamConfigurationMap map = characteristics.get(
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] sizes = map.getOutputSizes(MediaRecorder.class);
Log.e(TAG,"sizes"+sizes.length);
for(Size a: sizes){
Log.e(TAG,"a "+ a.toString());
}
Size size = sizes[3]; // 使用的输出尺寸 : 640 480
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
mCameraManager.openCamera(cameraId, new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
try {
mCameraDevice = camera;
startRecording(camera, size);
} catch (CameraAccessException | IOException e) {
e.printStackTrace();
}
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
stopStreaming();
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
stopStreaming();
}
}, mHandler);
break;
}
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void startRecording(CameraDevice camera, Size size) throws CameraAccessException, IOException {
// 设置输出文件和其他 MediaRecorder 属性
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setVideoSize(size.getWidth(), size.getHeight());
mMediaRecorder.setVideoFrameRate(60);
mMediaRecorder.setVideoEncodingBitRate(1024 * 1024);
mMediaRecorder.setOnInfoListener(this);
String a = Environment.getExternalStorageDirectory().toString()+"/test1.mp4";
Log.e(TAG, "setOutputFile : "+ a);
mMediaRecorder.setOutputFile(new File(a));
mMediaRecorder.prepare();
// 创建 CaptureSession,将Surface作为输出目标
Surface surface = mMediaRecorder.getSurface();
try {
List<OutputConfiguration> outputs = Arrays.asList(
new OutputConfiguration(surface));
SessionConfiguration config = new SessionConfiguration(SessionConfiguration.SESSION_REGULAR,outputs,new Executor() {
@Override
public void execute(Runnable command) {
Log.e(TAG, "Executor execute ");
command.run();
}
} ,mCaptureSessionListener);
camera.createCaptureSession(config);
} catch (CameraAccessException ex) {
Log.e(TAG, "Failed to create a capture session", ex);
}
}
final CameraCaptureSession.StateCallback mCaptureSessionListener =
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
Log.e(TAG, "Finished configuring camera outputs");
mCaptureSession = session;
if (mMediaRecorder.getSurface() != null) {
try {
// Build a request for preview footage
CaptureRequest.Builder requestBuilder =
mCameraDevice.createCaptureRequest(mCameraDevice.TEMPLATE_RECORD);
requestBuilder.addTarget(mMediaRecorder.getSurface());
CaptureRequest previewRequest = requestBuilder.build();
// Start displaying preview images
try {
session.setRepeatingRequest(previewRequest, /*listener*/null,
/*handler*/null);
mMediaRecorder.start();
} catch (CameraAccessException ex) {
Log.e(TAG, "Failed to make repeating preview request", ex);
}
} catch (CameraAccessException ex) {
Log.e(TAG, "Failed to build preview request", ex);
}
}
else {
Log.e(TAG, "Holder didn't exist when trying to formulate preview request");
}
}
@Override
public void onClosed(CameraCaptureSession session) {
Log.e(TAG, "CameraCaptureSession onClosed");
mCaptureSession = null;
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
Log.e(TAG, "Configuration error on device '" + mCameraDevice.getId());
}};
public void stopStreaming() {
try {
if (mMediaRecorder != null) {
mMediaRecorder.stop();
mMediaRecorder.release();
mMediaRecorder = null;
}
} catch (Exception e) {
Log.e(TAG, "stopStreaming: ", e);
}
mHandlerThread.quitSafely();
}
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
Log.e(TAG, "OnInfoListener: what: "+what);
}
@Override
public void onClick(View v) {
mMediaRecorder.stop();
mCaptureSession.close();
}
}