De acordo com este fluxograma, é fácil de entender com o código
package com.example.camera2;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
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.StreamConfigurationMap;
import android.os.Bundle;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
import android.view.TextureView;
import java.util.Arrays;
public class MainActivity extends AppCompatActivity {
public String TAG = "ManiActivity";
public String mCameraId;
public TextureView mTextureView;
public CameraDevice mCameraDevice;
public CaptureRequest.Builder mPreviewBuilder;
public Surface mPreviewSurface;
public CameraCaptureSession mCameraCaptureSession;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextureView = findViewById(R.id.textureView);
mTextureView.setSurfaceTextureListener(SurfaceListener);
getPermission();
}
//1.获取权限
protected void getPermission(){
if(ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CAMERA},1);
}
}
@Override
public void onRequestPermissionsResult(int requestCode,String[] mPermission,int[] grantResults){
super.onRequestPermissionsResult(requestCode,mPermission,grantResults);
if(requestCode == 1){
if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
//授权成功
openCamera();
}else{
getPermission();
}
}
}
//设置Surface回调
TextureView.SurfaceTextureListener SurfaceListener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int i, int i1) {
Log.d(TAG, "onSurfaceTextureAvailable: success!!");
setupCamera();
openCamera();
}
@Override
public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surfaceTexture, int i, int i1) {
}
@Override
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surfaceTexture) {
return false;
}
@Override
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surfaceTexture) {
}
};
// 3. 设置相机
protected void setupCamera(){
Log.d(TAG, "setupCamera: success");
//需要强转不然报错
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
//getCameraIdList()需要抛异常
try {
for (String cameraId : manager.getCameraIdList()) {
CameraCharacteristics characteristic = manager.getCameraCharacteristics(cameraId);
if (cameraId == "1") {
continue;
}
//获取所支持的所有分辨率 没用上因为我把分辨率写死了
//StreamConfigurationMap map = characteristic.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
//Size[] outputSizes = map.getOutputSizes(ImageFormat.JPEG);
mCameraId = cameraId;
break;
}
}catch (CameraAccessException e){
e.printStackTrace();
}
}
//4.打开相机
protected void openCamera(){
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
if(ActivityCompat.checkSelfPermission(this,Manifest.permission.CAMERA)!=PackageManager.PERMISSION_GRANTED){
getPermission();
}else {
try {
manager.openCamera(mCameraId,CameraStateCallback,null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}
//5.CameraDevice.StateCallback 中获取CameraDevice
CameraDevice.StateCallback CameraStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice cameraDevice) {
mCameraDevice = cameraDevice;
//创建预览
createPreview();
}
@Override
public void onDisconnected(@NonNull CameraDevice cameraDevice) {
}
@Override
public void onError(@NonNull CameraDevice cameraDevice, int i) {
}
};
protected void closeCamera(){
}
protected void createPreview(){
//创建预览的Builder
try {
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
} catch (CameraAccessException e) {
e.printStackTrace();
}
//addTarget需要一个Surface 下面就是获取Surface
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
//设置SurfaceView的缓冲区分辨率 防止预览拉伸 960 720 是m7机子的分辨率
surfaceTexture.setDefaultBufferSize(960,720);
mPreviewSurface = new Surface(surfaceTexture);
mPreviewBuilder.addTarget(mPreviewSurface);
//可以通过previewBuilder.set 设置AE/AF模式 这里不写
//发起预览请求 asList 也可以加ImageReader.getSurface
try {
mCameraDevice.createCaptureSession(Arrays.asList(mPreviewSurface), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
mCameraCaptureSession = cameraCaptureSession;
//设置重复预览 第二个是CaptureCallback回调 只预览不用
try {
mCameraCaptureSession.setRepeatingRequest(mPreviewBuilder.build(),null,null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
}
},null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}
Adicionado o código completo para gravação de vídeo
package com.example.camera2;
import android.Manifest;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
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.TotalCaptureResult;
import android.media.Image;
import android.media.ImageReader;
import android.media.MediaMetadataRetriever;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.util.SparseIntArray;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
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.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
public String TAG = "ManiActivity";
public String[] mPermission = {Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO,
Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE};
public ArrayList<String> permissionList = new ArrayList<>();
//预览
public String mCameraId;
public TextureView mTextureView;
public CameraDevice mCameraDevice;
public CaptureRequest.Builder mPreviewBuilder;
//CaptureRequest 就是CaptureRequest.Builder.build 对象
//public CaptureRequest PreviewRequest;
public Surface mPreviewSurface;
public CameraCaptureSession mCameraCaptureSession;
//拍照
public ImageReader mImageReader;
public CaptureRequest.Builder mCaptureBuilder;
//拍照的照片默认是横屏保存 所以竖屏状态下照片需要顺指针旋转90
//手机顺时针旋转
protected static final SparseIntArray ORIENTATION = new SparseIntArray();
static {
ORIENTATION.append(Surface.ROTATION_0, 90);
//90 270 还没处理
// ORIENTATION.append(Surface.ROTATION_90,0);
//前置用到
ORIENTATION.append(Surface.ROTATION_180, 270);
// ORIENTATION.append(Surface.ROTATION_270,180);
}
//缩略图
public ImageView mImageView;
ArrayList<String> imageList = new ArrayList<>();
//录制视频
public MediaRecorder mMediaRecorder;
public CaptureRequest.Builder mRecordBuilder;
public boolean isClick = false;
//切换
public TextView mRecordMode,mCaptureMode;
ImageButton mRecording;
ImageButton mTakePicture;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextureView = findViewById(R.id.textureView);
mTextureView.setSurfaceTextureListener(SurfaceListener);
mTakePicture = findViewById(R.id.takePicture);
mTakePicture.setOnClickListener(this);
ImageButton change = findViewById(R.id.change);
change.setOnClickListener(this);
mImageView = findViewById(R.id.image_show);
mImageView.setOnClickListener(this);
mRecording= findViewById(R.id.recording);
mRecording.setOnClickListener(this);
mRecording.setVisibility(View.INVISIBLE);
mCaptureMode = findViewById(R.id.captureMode);
mCaptureMode.setOnClickListener(this);
mCaptureMode.setTextSize(20);
mRecordMode = findViewById(R.id.recordMode);
mRecordMode.setOnClickListener(this);
View decorView=getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_FULLSCREEN//隐藏状态栏
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION//隐藏导航栏
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;//沉浸模式且状态栏和导航栏出现片刻后会自动隐藏
decorView.setSystemUiVisibility(option);
getPermission();
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy: ----------");
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onStop() {
super.onStop();
mCameraDevice.close();
}
@Override
protected void onRestart() {
super.onRestart();
openCamera();
}
//监听按钮
public void onClick(View view) {
switch (view.getId()) {
case R.id.takePicture:
takePicture();
break;
case R.id.change:
changeCamera();
break;
case R.id.image_show:
gotoGallery();
break;
case R.id.recording:
if (isClick) {
stopRecorder();
isClick = false;
} else {
isClick = true;
configSession();
startRecorder();
}
break;
case R.id.captureMode:
mTakePicture.setVisibility(View.VISIBLE);
mCaptureMode.setTextSize(20);
mRecordMode.setTextSize(15);
mRecording.setVisibility(View.INVISIBLE);
break;
case R.id.recordMode:
mRecording.setVisibility(View.VISIBLE);
mTakePicture.setVisibility(View.INVISIBLE);
mRecordMode.setTextSize(20);
mCaptureMode.setTextSize(15);
break;
}
}
//1.获取权限
protected void getPermission() {
for (String permission : mPermission) {
if (ContextCompat.checkSelfPermission(this,permission) != PackageManager.PERMISSION_GRANTED) {
permissionList.add(permission);
}
}
if (!permissionList.isEmpty()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(permissionList.toArray(new String[permissionList.size()]), 1);
}
} else {
//显示最后一张图片 最新
showThumbnail();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] mPermission, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, mPermission, grantResults);
if (requestCode == 1) {
//权限请求失败
if (grantResults.length > 0) {
//存放没授权的权限
List<String> deniedPermissions = new ArrayList<>();
for (int i = 0; i < grantResults.length; i++) {
int grantResult = grantResults[i];
String permission = mPermission[grantResult];
if (grantResult != PackageManager.PERMISSION_GRANTED) {
deniedPermissions.add(permission);
}
}
if (deniedPermissions.isEmpty()) {
//说明都授权了 打开相机
openCamera();
//显示最新的一张图片或者视频的第一帧
showThumbnail();
} else {
// 继续申请权限
getPermission();
}
}
}
}
//设置Surface回调
TextureView.SurfaceTextureListener SurfaceListener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int i, int i1) {
Log.d(TAG, "onSurfaceTextureAvailable: success!!");
setupCamera();
openCamera();
}
@Override
public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surfaceTexture, int i, int i1) {
}
@Override
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surfaceTexture) {
return false;
}
@Override
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surfaceTexture) {
}
};
// 3. 设置相机
protected void setupCamera() {
Log.d(TAG, "setupCamera: success");
//需要强转不然报错
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
//getCameraIdList()需要抛异常
try {
for (String cameraId : manager.getCameraIdList()) {
CameraCharacteristics characteristic = manager.getCameraCharacteristics(cameraId);
if (cameraId == "1") {
continue;
}
//获取所支持的所有分辨率 没用上因为我把分辨率写死了
//StreamConfigurationMap map = characteristic.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
//Size[] outputSizes = map.getOutputSizes(ImageFormat.JPEG);
mCameraId = cameraId;
break;
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
//4.打开相机
protected void openCamera() {
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
getPermission();
} else {
try {
manager.openCamera(mCameraId, CameraStateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}
//5.CameraDevice.StateCallback 中获取CameraDevice
CameraDevice.StateCallback CameraStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice cameraDevice) {
mCameraDevice = cameraDevice;
//创建预览
createPreview();
}
@Override
public void onDisconnected(@NonNull CameraDevice cameraDevice) {
}
@Override
public void onError(@NonNull CameraDevice cameraDevice, int i) {
}
};
protected void closeCamera() {
mCameraDevice = null;
}
//6.创建预览
protected void createPreview() {
//拍照需要设置ImageReader 只预览可以注释掉 因为拍照时需要一个ImageReader的surface
initImageReader();
//创建预览的Builder
try {
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
} catch (CameraAccessException e) {
e.printStackTrace();
}
//addTarget需要一个Surface 下面就是获取Surface
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
//设置SurfaceView的缓冲区分辨率 防止预览拉伸 960 720 是m7机子的分辨率
surfaceTexture.setDefaultBufferSize(960, 720);
mPreviewSurface = new Surface(surfaceTexture);
mPreviewBuilder.addTarget(mPreviewSurface);
//可以通过previewBuilder.set 设置AE/AF模式 这里不写
//发起预览请求 asList 拍照时必须需要添加 mImageReader.getSurface()
try {
mCameraDevice.createCaptureSession(Arrays.asList(mPreviewSurface, mImageReader.getSurface()), preViewStateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
CameraCaptureSession.StateCallback preViewStateCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
mCameraCaptureSession = session;
//设置重复预览 第二个是CaptureCallback回调 只预览不用
try {
//第一个参数就是CaptureRequest 对象
mCameraCaptureSession.setRepeatingRequest(mPreviewBuilder.build(), null, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
}
};
//预览已经完成
//广播通知相册刷新
protected void broadcast(){
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/";
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(new File(path));
intent.setData(uri);
MainActivity.this.sendBroadcast(intent);
}
//7.拍照 拍照之前先在申请权限里加上文件读写权限
//拍照 拍照开始之前初始化ImageReader
protected void initImageReader(){
//四个参数分别是照片的分辨率 格式 最多获取几帧
mImageReader = ImageReader.newInstance(1920,1080, ImageFormat.JPEG,1);
//设置ImageReader监听,当有图像流数据可用时会回调onImageAvailable
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader imageReader) {
Toast.makeText(MainActivity.this, "图片已保存", Toast.LENGTH_SHORT).show();
//获得Image 数据
Image image = imageReader.acquireNextImage();
//可以开启线程保存图片
new Thread(new Runnable() {
@Override
public void run() {
//字节缓冲
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
String path = Environment.getExternalStorageDirectory()+"/DCIM/camera/myPicture"
+System.currentTimeMillis()+".jpg";
File imageFile = new File(path);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(imageFile);
fos.write(data,0,data.length);
} catch (IOException e) {
e.printStackTrace();
}finally {
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
broadcast();
showThumbnail();
image.close(); // 必须关闭 不然拍第二章会报错
}
}
}).start();
}
},null);
}
//拍照
protected void takePicture(){
// 从新创建拍照的Builder
try {
mCaptureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
} catch (CameraAccessException e) {
e.printStackTrace();
}
// 获取屏幕方向
int rotation = getWindowManager().getDefaultDisplay().getRotation();
//如果是前置
if(mCameraId.equals("1")){
rotation = 2;
}
mCaptureBuilder.addTarget(mImageReader.getSurface());
//配置照片方向
mCaptureBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATION.get(rotation));
//停止预览
try {
mCameraCaptureSession.stopRepeating();
} catch (CameraAccessException e) {
e.printStackTrace();
}
try {
//第一个参数就是CaptureRequest 对象
mCameraCaptureSession.capture(mCaptureBuilder.build(),captureCallback,null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
//拍照时用到的CaptureCallback
CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
//完成之后继续预览
super.onCaptureCompleted(session, request, result);
try {
session.setRepeatingRequest(mPreviewBuilder.build(),null,null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
};
// 前后置切换
protected void changeCamera(){
if(mCameraId.equals("0")){
//后置转前置
mCameraId = "1";
}else {
//前置转后置
mCameraId = "0";
}
mCameraDevice.close();
openCamera();
}
//设置缩略图
protected void showThumbnail(){
// 获取相册路径集合
imageList = GetFilePath.getFilePath();
String path = imageList.get(imageList.size()-1);
if(path.contains("jpg")){
Bitmap bitmap = (Bitmap) BitmapFactory.decodeFile(path);
//又是bitmap 为空 忘记给mImageView finViewById
mImageView.setImageBitmap(bitmap);
}else {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(path);
//取第一帧
Bitmap bitmap = retriever.getFrameAtTime(1);
mImageView.setImageBitmap(bitmap);
}
}
//跳转相册 (画廊)
protected void gotoGallery(){
ArrayList<String> temp = GetFilePath.getFilePath();
String lastPath = temp.get(temp.size()-1);
Uri uri = getMediaUriFromPath(this,lastPath);
Intent intent = new Intent("com.android.camera.action.REVIEW",uri);
intent.setData(uri);
startActivity(intent);
}
public Uri getMediaUriFromPath(Context context, String path) {
Uri uri = null;
if(path.contains("jpg")){
Uri picUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = context.getContentResolver().query(picUri,
null,
MediaStore.Images.Media.DISPLAY_NAME + "= ?",
new String[] {path.substring(path.lastIndexOf("/") + 1)},
null);
if(cursor.moveToFirst()) {
uri = ContentUris.withAppendedId(picUri,
cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media._ID)));
}
cursor.close();
}else if(path.contains("mp4")){
Uri mediaUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = context.getContentResolver().query(mediaUri,
null,
MediaStore.Video.Media.DISPLAY_NAME + "= ?",
new String[] {path.substring(path.lastIndexOf("/") + 1)},
null);
if(cursor.moveToFirst()) {
uri = ContentUris.withAppendedId(mediaUri,
cursor.getLong(cursor.getColumnIndex(MediaStore.Video.Media._ID)));
}
cursor.close();
}
return uri;
}
//8.录像视频 开始之前添加音频权限
//录制开始之前配置MediaReader
protected void initMediaRecorder(){
if(mMediaRecorder==null){
mMediaRecorder = new MediaRecorder();
}
//设置音频来源 MIC
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//设置视频来源 SURFACE
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
//设置输出格式 MPEG_4
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
//设置音频编码格式, 兼容问题实际开发中用AAC
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
//设置视频编格式, 兼容问题 选择H264
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
//设置比特率 一般是1*分辨率 到10*分辨率之间波动 比特率越大视频越清晰但视频文件越大
mMediaRecorder.setVideoEncodingBitRate(10 * 1080 * 1920);
//设置帧数
mMediaRecorder.setVideoFrameRate(60);
//设置视频的高度宽度
mMediaRecorder.setVideoSize(960,720);
//设置保存的方向 默认是横屏所以旋转90
mMediaRecorder.setOrientationHint(90);
//如果是前置 旋转270
if(mCameraId.equals("1")){
mMediaRecorder.setOrientationHint(270);
}
//设置视频预览画面
Surface surface = new Surface(mTextureView.getSurfaceTexture());
mMediaRecorder.setPreviewDisplay(surface);
//输出到文件 保存
File file = new File(Environment.getExternalStorageDirectory()+"/DCIM/Camera/");
mMediaRecorder.setOutputFile(file.getAbsolutePath()+"/MyVideo"+System.currentTimeMillis()+".mp4");
try {
mMediaRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
//配置录像消息
protected void configSession(){
initMediaRecorder();
//重新创建一个录像的Builder
try {
//RECORD PREVIEW CAPTURE 都能达到效果
mRecordBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
} catch (CameraAccessException e) {
e.printStackTrace();
}
//设置AE AF 模式 可以不要
//mRecordBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
mRecordBuilder.addTarget(mMediaRecorder.getSurface());
mRecordBuilder.addTarget(mPreviewSurface);
try {
mCameraDevice.createCaptureSession(Arrays.asList(mPreviewSurface, mMediaRecorder.getSurface()),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
try {
session.setRepeatingRequest(mRecordBuilder.build(), null, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
//开始录制视频
protected void startRecorder(){
mMediaRecorder.start();
}
//停止
protected void stopRecorder(){
if (mMediaRecorder != null) {
mMediaRecorder.stop();
mMediaRecorder.reset();
}
broadcast();
showThumbnail();
try {
//发起预览
mCameraDevice.createCaptureSession(Arrays.asList(mPreviewSurface, mImageReader.getSurface()), preViewStateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}