Android使用CameraSurfaceView

Android使用CameraSurfaceView

1、布局文件的编写
<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);就可以开始录制了,后面的变量是要保存到那个路径下。就可以完成此功能了·。

猜你喜欢

转载自blog.csdn.net/wzx311/article/details/126084579
今日推荐