<com.android.CameraSurfaceView
android:id="@+id/textureView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:layout_marginLeft="11dp"
android:layout_marginBottom="8dp"
android:layout_toLeftOf="@+id/submit_list_btn"/>
这个一看就是我自己定义的自定义布局,命名的布局文件,去查看我的布局文件。
#####2、自定义文件的编写
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Camera.AutoFocusCallback, View.OnClickListener {
private final static String TAG = CameraSurfaceView.class.getSimpleName();
protected static final int[] VIDEO_320 = {320, 240};
protected static final int[] VIDEO_480 = {640, 480};
protected static final int[] VIDEO_720 = {1280, 720};
protected static final int[] VIDEO_1080 = {1920, 1080};
private int screenOritation = Configuration.ORIENTATION_PORTRAIT;
private boolean mOpenBackCamera = true;
private SurfaceHolder mSurfaceHolder;
private SurfaceTexture mSurfaceTexture;
private boolean mRunInBackground = false;
boolean isAttachedWindow = false;
private Camera mCamera;
private Camera.Parameters mParam;
private byte[] previewBuffer;
private int mCameraId;
protected int previewformat = ImageFormat.NV21;
Context context;
public CameraSurfaceView(Context context) {
super(context);
init(context);
}
public CameraSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CameraSurfaceView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
this.context = context;
cameraState = CameraState.START;
if (cameraStateListener != null) {
cameraStateListener.onCameraStateChange(cameraState);
}
openCamera();
if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
screenOritation = Configuration.ORIENTATION_LANDSCAPE;
}
mSurfaceHolder = getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceTexture = new SurfaceTexture(10);
setOnClickListener(this);
post(new Runnable() {
@Override
public void run() {
if(!isAttachedWindow){
mRunInBackground = true;
startPreview();
}
}
});
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
isAttachedWindow = true;
}
private void openCamera() {
if (mOpenBackCamera) {
mCameraId = findCamera(false);
} else {
mCameraId = findCamera(true);
}
if (mCameraId == -1) {
mCameraId = 0;
}
try {
mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
// mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
} catch (Exception ee) {
mCamera = null;
cameraState = CameraState.ERROR;
if (cameraStateListener != null) {
cameraStateListener.onCameraStateChange(cameraState);
}
}
if (mCamera == null) {
Toast.makeText(context, "打开摄像头失败", Toast.LENGTH_SHORT).show();
return;
}
}
private int findCamera(boolean front) {
int cameraCount;
try {
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
Camera.getCameraInfo(camIdx, cameraInfo);
int facing = front ? 1 : 0;
if (cameraInfo.facing == facing) {
return camIdx;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
public boolean setDefaultCamera(boolean backCamera) {
if (mOpenBackCamera == backCamera) return false;
if (isRecording) {
Toast.makeText(context, "请先结束录像", Toast.LENGTH_SHORT).show();
return false;
}
mOpenBackCamera = backCamera;
if (mCamera != null) {
closeCamera();
openCamera();
startPreview();
}
return true;
}
public void closeCamera() {
stopRecord();
stopPreview();
releaseCamera();
}
private void releaseCamera() {
try {
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCamera.setPreviewCallbackWithBuffer(null);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
} catch (Exception ee) {
}
}
private boolean isSupportCameraLight() {
boolean mIsSupportCameraLight = false;
try {
if (mCamera != null) {
Camera.Parameters parameter = mCamera.getParameters();
Object a = parameter.getSupportedFlashModes();
if (a == null) {
mIsSupportCameraLight = false;
} else {
mIsSupportCameraLight = true;
}
}
} catch (Exception e) {
mIsSupportCameraLight = false;
e.printStackTrace();
}
return mIsSupportCameraLight;
}
private Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
public synchronized void onPreviewFrame(byte[] data, Camera camera) {
if (data == null) {
releaseCamera();
return;
}
//you can code media here
if (cameraState != CameraState.PREVIEW) {
cameraState = CameraState.PREVIEW;
if (cameraStateListener != null) {
cameraStateListener.onCameraStateChange(cameraState);
}
}
mCamera.addCallbackBuffer(previewBuffer);
}
};
//设置Camera各项参数
private void startPreview() {
if (mCamera == null) return;
try {
mParam = mCamera.getParameters();
mParam.setPreviewFormat(previewformat);
mParam.setRotation(0);
Camera.Size previewSize = CamParaUtil.getSize(mParam.getSupportedPreviewSizes(), 1000,
mCamera.new Size(VIDEO_720[0], VIDEO_720[1]));
mParam.setPreviewSize(previewSize.width, previewSize.height);
int yuv_buffersize = previewSize.width * previewSize.height * ImageFormat.getBitsPerPixel(previewformat) / 8;
previewBuffer = new byte[yuv_buffersize];
Camera.Size pictureSize = CamParaUtil.getSize(mParam.getSupportedPictureSizes(), 1500,
mCamera.new Size(VIDEO_1080[0], VIDEO_1080[1]));
mParam.setPictureSize(pictureSize.width, pictureSize.height);
if (CamParaUtil.isSupportedFormats(mParam.getSupportedPictureFormats(), ImageFormat.JPEG)) {
mParam.setPictureFormat(ImageFormat.JPEG);
mParam.setJpegQuality(100);
}
if (CamParaUtil.isSupportedFocusMode(mParam.getSupportedFocusModes(), FOCUS_MODE_AUTO)) {
mParam.setFocusMode(FOCUS_MODE_AUTO);
}
//这里是预览的设置
if (screenOritation != Configuration.ORIENTATION_LANDSCAPE) {
mParam.set("orientation", "portrait");
mCamera.setDisplayOrientation(90);
Log.d("mcamera","mCamera.setDisplayOrientation(90) 1111");
} else {
mParam.set("orientation", "landscape");
mCamera.setDisplayOrientation(180);
Log.d("mcamera","mCamera.setDisplayOrientation(90) 222222");
}
if (mRunInBackground) {
mCamera.setPreviewTexture(mSurfaceTexture);
mCamera.addCallbackBuffer(previewBuffer);
// mCamera.setPreviewCallbackWithBuffer(previewCallback);//设置摄像头预览帧回调
} else {
mCamera.setPreviewDisplay(mSurfaceHolder);
// mCamera.setPreviewCallback(previewCallback);//设置摄像头预览帧回调
}
mCamera.setParameters(mParam);
mCamera.startPreview();
if (cameraState != CameraState.START) {
cameraState = CameraState.START;
if (cameraStateListener != null) {
cameraStateListener.onCameraStateChange(cameraState);
}
}
} catch (Exception e) {
releaseCamera();
return;
}
try {
String mode = mCamera.getParameters().getFocusMode();
if (("auto".equals(mode)) || ("macro".equals(mode))) {
mCamera.autoFocus(null);
}
} catch (Exception e) {
}
}
private void stopPreview() {
if (mCamera == null) return;
try {
if (mRunInBackground) {
mCamera.setPreviewCallbackWithBuffer(null);
mCamera.stopPreview();
} else {
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
}
if (cameraState != CameraState.STOP) {
cameraState = CameraState.STOP;
if (cameraStateListener != null) {
cameraStateListener.onCameraStateChange(cameraState);
}
}
} catch (Exception ee) {
}
}
@Override
public void onClick(View v) {
if (mCamera != null) {
mCamera.autoFocus(null);
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
stopPreview();
startPreview();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
stopPreview();
if (mRunInBackground)
startPreview();
}
protected CameraState cameraState;
private CameraStateListener cameraStateListener;
public enum CameraState {
START, PREVIEW, STOP, ERROR
}
public void setOnCameraStateListener(CameraStateListener listener) {
this.cameraStateListener = listener;
}
public interface CameraStateListener {
void onCameraStateChange(CameraState paramCameraState);
}
/**
* ___________________________________前/后台运行______________________________________
**/
public void setRunBack(boolean b) {
if (mCamera == null) return;
if (b == mRunInBackground) return;
if(!b && !isAttachedWindow){
Toast.makeText(context, "Vew未依附在Window,无法显示", Toast.LENGTH_SHORT).show();
return;
}
mRunInBackground = b;
if (b)
setVisibility(View.GONE);
else
setVisibility(View.VISIBLE);
}
/**
* ___________________________________开关闪光灯______________________________________
**/
public void switchLight(boolean open) {
if (mCamera == null) return;
try {
if (mCamera != null) {
if (open) {
Camera.Parameters parameter = mCamera.getParameters();
if (parameter.getFlashMode().equals("off")) {
parameter.setFlashMode("torch");
mCamera.setParameters(parameter);
} else {
parameter.setFlashMode("off");
mCamera.setParameters(parameter);
}
} else {
Camera.Parameters parameter = mCamera.getParameters();
if ((parameter.getFlashMode() != null) &&
(parameter.getFlashMode().equals("torch"))) {
parameter.setFlashMode("off");
mCamera.setParameters(parameter);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* ___________________________________以下为拍照模块______________________________________
**/
public void capture() {
if (mCamera == null) return;
if (!FileUtil.isExternalStorageWritable()) {
Toast.makeText(context, "请插入存储卡", Toast.LENGTH_SHORT).show();
return;
}
mCamera.autoFocus(this);
}
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
try {
mCamera.takePicture(null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Matrix matrix = new Matrix();
if (mOpenBackCamera) {
matrix.setRotate(90);
} else {
matrix.setRotate(270);
matrix.postScale(-1, 1);
}
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
FileUtil.saveBitmap(bitmap);
Toast.makeText(context, "拍照成功", Toast.LENGTH_SHORT).show();
startPreview();
}
});
} catch (Exception e) {
if (isRecording) {
Toast.makeText(context, "请先结束录像", Toast.LENGTH_SHORT).show();
}
}
}
}
/**
* ___________________________________以下为视频录制模块______________________________________
**/
MediaRecorder mediaRecorder = new MediaRecorder();
private boolean isRecording = false;
public boolean isRecording() {
return isRecording;
}
public boolean startRecord(String path) {
return startRecord(-1, path,null);
}
public boolean startRecord(int maxDurationMs, String path,MediaRecorder.OnInfoListener onInfoListener) {
if (mCamera == null) return false;
if (!FileUtil.isExternalStorageWritable()) {
Toast.makeText(context, "请插入存储卡", Toast.LENGTH_SHORT).show();
return false;
}
mParam.set("orientation", "landscape");
// mCamera.setDisplayOrientation(180);
// mCamera.setDisplayOrientation(90);
// mediaRecorder.setOrientationHint(270);
mCamera.unlock();
mediaRecorder.reset();
mediaRecorder.setCamera(mCamera);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置音频来源(MIC表示麦克风)
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// 设置音频输出格式
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);// 设置音频编码
Camera.Size videoSize = CamParaUtil.getSize(mParam.getSupportedVideoSizes(), 1200,
mCamera.new Size(VIDEO_1080[0], VIDEO_1080[1]));
mediaRecorder.setVideoSize(videoSize.width, videoSize.height);
mediaRecorder.setVideoFrameRate(30); //这个是30帧
mediaRecorder.setVideoEncodingBitRate(3 * 1024 * 1024);
// mediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());//设置录制预览surface
if (mOpenBackCamera) {
mediaRecorder.setOrientationHint(0);
Log.d("mediaRecorder","setOrientationHint 111111");
} else {
if (screenOritation == Configuration.ORIENTATION_LANDSCAPE){
mediaRecorder.setOrientationHint(0);
Log.d("mediaRecorder","setOrientationHint 222222");
}else{
mediaRecorder.setOrientationHint(0);
Log.d("mediaRecorder","setOrientationHint 3333333");
}
}
if (maxDurationMs != -1) {
mediaRecorder.setMaxDuration(maxDurationMs);
mediaRecorder.setOnInfoListener(onInfoListener);
}
mediaRecorder.setOutputFile(path);
try {
mediaRecorder.prepare();
mediaRecorder.start();
isRecording = true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
public void stopRecord() {
if (!isRecording) return;
mediaRecorder.setPreviewDisplay(null);
try {
mediaRecorder.stop();
isRecording = false;
// Toast.makeText(context, "视频已保存", Toast.LENGTH_SHORT).show();
} catch (IllegalStateException e) {
Log.d("error", "stopRecord: "+e);
e.printStackTrace();
}
}
}
在这个文件中就可以看见操作,可以进行拍照片,去录制视频,根据代码中的 mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
来去调整开启那个摄像头以及 mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA)
调整录制的大小、声音的采集信息。
#####Activity中的使用
首先要去声明一个变量是否在录制视频 private boolean ISREcording =false; //false没有录制 true是正在录制
现在就是开始去使用
先声明我们的自定义布局的类
private CameraSurfaceView cameraSurfaceView;
然后直接 cameraSurfaceView.startRecord(videopath);
就可以开始录制了,后面的变量是要保存到那个路径下。就可以完成此功能了·。