Camera1

作者: 故江 | 来源:发表于2019-06-05 17:30 被阅读0次
    https://blog.csdn.net/qq_38907791/article/details/87984378
    源码
    https://www.cnblogs.com/zhujiabin/p/4218209.htmls
    //布局
    <RelativeLayout
            android:id="@+id/layout_gesture"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#000"
            android:gravity="center_horizontal">
        <SurfaceView
            android:id="@+id/record_surfaceView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        </RelativeLayout>
    
        <ImageView
            android:id="@+id/changing"
            android:background="@drawable/rotate"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:layout_width="30dp"
            android:layout_height="30dp" />
    
        <ImageView
            android:id="@+id/change"
            android:background="@drawable/rotate"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dp"
            android:layout_marginTop="10dp"
            android:layout_width="30dp"
            android:layout_height="30dp" />
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:background="#80ffffff"
            android:padding="10dp">
    
            <!-- 开始/结束 录制按钮 -->
            <ImageView
                android:id="@+id/record_control"
                android:layout_width="60dp"
                android:layout_height="60dp"
                android:layout_centerInParent="true"
                android:onClick="startRecord"
                android:src="@drawable/recordvideo_start" />
    
            <ImageView
                android:id="@+id/record_pause"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_centerVertical="true"
                android:onClick="stopRecord"
                android:src="@drawable/control_pause"
                android:visibility="gone" />
    
            <Chronometer
                android:id="@+id/record_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_alignParentRight="true"
                android:format="%s" />
        </RelativeLayout>
    
    import android.Manifest;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.content.res.Configuration;
    import android.hardware.Camera;
    import android.media.CamcorderProfile;
    import android.media.MediaRecorder;
    import android.os.Build;
    import android.os.Bundle;
    import android.os.Environment;
    import android.os.Handler;
    import android.os.SystemClock;
    import android.support.annotation.Nullable;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.content.ContextCompat;
    import android.support.v7.app.AlertDialog;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Chronometer;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.PopupWindow;
    import android.widget.Toast;
    
    import java.io.File;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.concurrent.Executor;
    import java.util.concurrent.Executors;
    
    import camera1video.android.example.com.android_camera1video_master.util.VideoUtils;
    
    public class CustomRecordActivity extends AppCompatActivity implements View.OnClickListener {
    
        private static final String TAG = "CustomRecordActivity";
    
        private Executor executor = Executors.newFixedThreadPool(1);
    
        private ImageView mRecordControl;
        private ImageView mPauseRecord;
        private ImageView mChange;
        private ImageView mChanging;
        private SurfaceView surfaceView;
        private SurfaceHolder mSurfaceHolder;
        private Chronometer mRecordTime;
    
        //录像机状态标识
        private int mRecorderState;
        public static final int STATE_INIT = 0;
        public static final int STATE_RECORDING = 1;
        public static final int STATE_PAUSE = 2;
        public static final int CAMERA_OK = 1;
        private long mPauseTime = 0; //录制暂停时间间隔
        int cameraType = 0;
        int cameraFlag = 1; //1为后置
        int flashType;
    
        // 存储文件
        private Camera mCamera;
        private MediaRecorder mediaRecorder;
        private String currentVideoFilePath;
        private String saveVideoPath = "";
        private String str = null;
    
        private MediaRecorder.OnErrorListener OnErrorListener = new MediaRecorder.OnErrorListener() {
            @Override
            public void onError(MediaRecorder mediaRecorder, int what, int extra) {
                try {
                    if (mediaRecorder != null) {
                        mediaRecorder.reset();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_camera);
            if (Build.VERSION.SDK_INT > 22) {
                if (ContextCompat.checkSelfPermission(CustomRecordActivity.this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                    //先判断有没有权限 ,没有就在这里进行权限的申请
                    ActivityCompat.requestPermissions(CustomRecordActivity.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, CAMERA_OK);
                    initView();
                } else {
                    //说明已经获取到摄像头权限了
                    Log.i("CustomRecordActivity", "已经获取了权限");
                    initView();
                }
            }
        }
    
        private void initView() {
            surfaceView = (SurfaceView) findViewById(R.id.record_surfaceView);
            mRecordControl = (ImageView) findViewById(R.id.record_control);
            mRecordTime = (Chronometer) findViewById(R.id.record_time);
            mPauseRecord = (ImageView) findViewById(R.id.record_pause);
            mChange = (ImageView) findViewById(R.id.change);
            mChanging = (ImageView) findViewById(R.id.changing);
            mRecordControl.setOnClickListener(this);
            mPauseRecord.setOnClickListener(this);
            mChange.setOnClickListener(this);
            mChanging.setOnClickListener(this);
            mPauseRecord.setEnabled(false);
    
            /*ViewGroup.LayoutParams lp = surfaceView.getLayoutParams();
            lp.width = 720;
            lp.height =1280;
            surfaceView.setLayoutParams(lp);*/
    
            //配置SurfaceHolder
            mSurfaceHolder = surfaceView.getHolder();
            // 设置Surface不需要维护自己的缓冲区
            mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            // 设置分辨率
            mSurfaceHolder.setFixedSize(720, 1280);
            // 设置该组件不会让屏幕自动关闭
            mSurfaceHolder.setKeepScreenOn(true);
            //回调接口
            mSurfaceHolder.addCallback(mSurfaceCallBack);
        }
    
        private SurfaceHolder.Callback mSurfaceCallBack = new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {
                initCamera();
            }
    
            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
                if (mSurfaceHolder.getSurface() == null) {
                    return;
                }
            }
    
            @Override
            public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
                releaseCamera();
            }
        };
    
        /**
         * 设置摄像头为竖屏
         */
        private void configCameraParams() {
            Camera.Parameters params = mCamera.getParameters();
           /* str = params.get("video-rotation-supported");
            if (str != null ) {
                if (str.equals("true")) {
                    Log.e("video-rotation-111","str支持旋转");
                    Show();
                } else {
                    Log.e("video-rotation-333","str不支持旋转");
                    Show();
                }
            }else {
                Log.e("video-rotation-222","不支持旋转");
                NoShow();
            }*/
            params.setPreviewSize(720,1280);
            //设置相机的横竖屏(竖屏需要旋转90°)
            if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
                //params.set("orientation", "portrait");
                params.set("video-rotation","90");
                //设置预览图像的旋转方向video-rotation=90
                //mCamera.setDisplayOrientation(0);
            } else {
                //params.set("orientation", "landscape");
                params.set("video-rotation","0");
                //设置预览图像的旋转方向
                //mCamera.setDisplayOrientation(90);
            }
            //设置聚焦模式
            params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
            //缩短Recording启动时间
            params.setRecordingHint(true);
            //影像稳定能力
            if (params.isVideoStabilizationSupported())
                params.setVideoStabilization(true);
            mCamera.setParameters(params);
            //mCamera.setDisplayOrientation(90);
        }
    
        private void Show() {
            AlertDialog.Builder builder = new AlertDialog.Builder(this).setIcon(R.mipmap.ic_launcher).setTitle("支持旋转")
                    .setCancelable(false)
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.dismiss();
                        }
                    })
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.dismiss();
                        }
                    });
            builder.create().show();
        }
    
        private void NoShow() {
            AlertDialog.Builder builder = new AlertDialog.Builder(this).setIcon(R.mipmap.ic_launcher).setTitle("不支持旋转")
                    .setCancelable(false)
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.dismiss();
                        }
                    })
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.dismiss();
                        }
                    });
            builder.create().show();
        }
    
        /**
         * 释放摄像头资源
         */
        private void releaseCamera() {
            if (mCamera != null) {
                mCamera.setPreviewCallback(null);
                mCamera.stopPreview();
                mCamera.release();
                mCamera = null;
            }
        }
    
        /**
         * 开始录制视频
         */
        public boolean startRecord() {
            initCamera();
            //录制视频前必须先解锁Camera
            mCamera.unlock();
            configMediaRecorder();
            try {
                //开始录制
                mediaRecorder.prepare();
                mediaRecorder.start();
            } catch (IOException e) {
                return false;
            }
            return true;
        }
    
        /**
         * 停止录制视频
         */
        public void stopRecord() {
            // 设置后不会崩
            mediaRecorder.setOnErrorListener(null);
            mediaRecorder.setPreviewDisplay(null);
            //停止录制
            mediaRecorder.stop();
            mediaRecorder.reset();
            //释放资源
            mediaRecorder.release();
            mediaRecorder = null;
        }
    
        /**
         * 合并录像视频方法
         */
        private void mergeRecordVideoFile() {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        String[] str = new String[]{saveVideoPath, currentVideoFilePath};
                        //将2个视频文件合并到 append.mp4文件下
                        VideoUtils.appendVideo(CustomRecordActivity.this, getVideoFilePath(CustomRecordActivity.this) + "append.mp4", str);
                        File reName = new File(saveVideoPath);
                        File f = new File(getVideoFilePath(CustomRecordActivity.this) + "append.mp4");
                        //再将合成的append.mp4视频文件 移动到 saveVideoPath 路径下
                        f.renameTo(reName);
                        if (reName.exists()) {
                            f.delete();
                            new File(currentVideoFilePath).delete();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    
        /**
         * 点击中间按钮,执行的UI更新操作
         */
        private void refreshControlUI() {
            if (mRecorderState == STATE_INIT) {
                //录像时间计时
                mRecordTime.setBase(SystemClock.elapsedRealtime());
                mRecordTime.start();
                mRecordControl.setImageResource(R.drawable.recordvideo_stop);
                //1s后才能按停止录制按钮
                mRecordControl.setEnabled(false);
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mRecordControl.setEnabled(true);
                    }
                }, 1000);
                mPauseRecord.setVisibility(View.VISIBLE);
                mPauseRecord.setEnabled(true);
            } else if (mRecorderState == STATE_RECORDING) {
                mPauseTime = 0;
                mRecordTime.stop();
                mRecordControl.setImageResource(R.drawable.recordvideo_start);
                mPauseRecord.setVisibility(View.GONE);
                mPauseRecord.setEnabled(false);
            }
        }
    
        /**
         * 点击暂停继续按钮,执行的UI更新操作
         */
        private void refreshPauseUI() {
            if (mRecorderState == STATE_RECORDING) {
                mPauseRecord.setImageResource(R.drawable.control_play);
                mPauseTime = SystemClock.elapsedRealtime();
                mRecordTime.stop();
            } else if (mRecorderState == STATE_PAUSE) {
                mPauseRecord.setImageResource(R.drawable.control_pause);
                if (mPauseTime == 0) {
                    mRecordTime.setBase(SystemClock.elapsedRealtime());
                } else {
                    mRecordTime.setBase(SystemClock.elapsedRealtime() - (mPauseTime - mRecordTime.getBase()));
                }
                mRecordTime.start();
            }
        }
    
        @Override
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.record_control: {
                    if (mRecorderState == STATE_INIT) {
                        if (getVideoFilePath(getApplicationContext()) == null)
                            return;
                        //视频文件保存路径,configMediaRecorder方法中会设置
                        currentVideoFilePath = getVideoFilePath(getApplicationContext()) + getVideoName();
                        //开始录制视频
                        if (!startRecord())
                            return;
                        refreshControlUI();
                        mRecorderState = STATE_RECORDING;
                    } else if (mRecorderState == STATE_RECORDING) {
                        //停止视频录制
                        stopRecord();
                        //先给Camera加锁后再释放相机
                        mCamera.lock();
                        releaseCamera();
                        refreshControlUI();
                        //判断是否进行视频合并
                        if ("".equals(saveVideoPath)) {
                            saveVideoPath = currentVideoFilePath;
                        } else {
                            mergeRecordVideoFile();
                        }
                        mRecorderState = STATE_INIT;
                        //延迟一秒跳转到播放器,(确保视频合并完成后跳转) TODO 具体的逻辑可根据自己的使用场景跳转
                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                Intent intent = new Intent(CustomRecordActivity.this, PlayVideoActivity.class);
                                Bundle bundle = new Bundle();
                                bundle.putString("videoPath", saveVideoPath);
                                intent.putExtras(bundle);
                                startActivity(intent);
                                finish();
                            }
                        }, 1000);
                    } else if (mRecorderState == STATE_PAUSE) {
                        //代表视频暂停录制时,点击中心按钮
                        Intent intent = new Intent(CustomRecordActivity.this, PlayVideoActivity.class);
                        Bundle bundle = new Bundle();
                        bundle.putString("videoPath", saveVideoPath);
                        intent.putExtras(bundle);
                        startActivity(intent);
                        finish();
                    }
                    break;
                }
    
                case R.id.record_pause: {
                    if (mRecorderState == STATE_RECORDING) {
                        //正在录制的视频,点击后暂停
                        //取消自动对焦
                        mCamera.autoFocus(new Camera.AutoFocusCallback() {
                            @Override
                            public void onAutoFocus(boolean success, Camera camera) {
                                if (success)
                                    CustomRecordActivity.this.mCamera.cancelAutoFocus();
                            }
                        });
                        stopRecord();
                        refreshPauseUI();
                        //判断是否进行视频合并
                        if ("".equals(saveVideoPath)) {
                            saveVideoPath = currentVideoFilePath;
                        } else {
                            mergeRecordVideoFile();
                        }
                        mRecorderState = STATE_PAUSE;
                    } else if (mRecorderState == STATE_PAUSE) {
                        if (getVideoFilePath(getApplicationContext()) == null)
                            return;
                        //视频文件保存路径,configMediaRecorder方法中会设置
                        currentVideoFilePath = getVideoFilePath(getApplicationContext()) + getVideoName();
                        //继续视频录制
                        if (!startRecord()) {
                            return;
                        }
                        refreshPauseUI();
                        mRecorderState = STATE_RECORDING;
                    }
                }
    
                case R.id.change:
                    switchCamera();
                    break;
    
                case R.id.changing:
                    // 一个自定义的布局,作为显示的内容
                    View contentView = LayoutInflater.from(this).inflate(
                            R.layout.popu, null);
                    final PopupWindow popupWindow = new PopupWindow(contentView,
                            ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
    
                    contentView.findViewById(R.id.num1).setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            popupWindow.dismiss();
                            View content = LayoutInflater.from(CustomRecordActivity.this).inflate(
                                    R.layout.popuwindow, null);
                            final PopupWindow popup = new PopupWindow(content,
                                    ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
    
                            content.findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    popup.dismiss();
                                    ViewGroup.LayoutParams lp = surfaceView.getLayoutParams();
                                    lp.width = 120;
                                    lp.height =160;
                                    surfaceView.setLayoutParams(lp);
                                }
                            });
    
                            content.findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    popup.dismiss();
                                    ViewGroup.LayoutParams lp = surfaceView.getLayoutParams();
                                    lp.width = 420;
                                    lp.height =640;
                                    surfaceView.setLayoutParams(lp);
                                }
                            });
    
                            content.findViewById(R.id.btn3).setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    popup.dismiss();
                                    ViewGroup.LayoutParams lp = surfaceView.getLayoutParams();
                                    lp.width = 720;
                                    lp.height =1280;
                                    surfaceView.setLayoutParams(lp);
                                }
                            });
    
                            content.findViewById(R.id.btn4).setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    popup.dismiss();
                                    ViewGroup.LayoutParams lp = surfaceView.getLayoutParams();
                                    lp.width = 1280;
                                    lp.height =1920;
                                    surfaceView.setLayoutParams(lp);
                                }
                            });
    
                            popup.setTouchable(true);
    
                            popup.setTouchInterceptor(new View.OnTouchListener() {
    
                                @Override
                                public boolean onTouch(View v, MotionEvent event) {
    
                                    Log.i("mengdd", "onTouch : ");
    
                                    return false;
                                    // 这里如果返回true的话,touch事件将被拦截
                                    // 拦截后 PopupWindow的onTouchEvent不被调用,这样点击外部区域无法dismiss
                                }
                            });
    
                            // 如果不设置PopupWindow的背景,无论是点击外部区域还是Back键都无法dismiss弹框
                            // 我觉得这里是API的一个bug
                            popup.setBackgroundDrawable(getResources().getDrawable(
                                    R.drawable.ic_launcher_background));
    
                            // 设置好参数之后再show
                            popup.showAsDropDown(view);
                        }
                    });
    
                    contentView.findViewById(R.id.num2).setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            Toast.makeText(CustomRecordActivity.this,"旋转",Toast.LENGTH_SHORT);
                            Camera.Parameters params = mCamera.getParameters();
                            str = params.get("video-rotation-supported");
                            if (str != null ) {
                                if (str.equals("true")) {
                                    Log.e("video-rotation-111","str支持旋转");
                                    Show();
                                    popupWindow.dismiss();
                                } else {
                                    Log.e("video-rotation-333","str不支持旋转");
                                    NoShow();
                                    popupWindow.dismiss();
                                }
                            }else {
                                Log.e("video-rotation-222","不支持旋转");
                                NoShow();
                                popupWindow.dismiss();
                            }
                            params.setPreviewSize(720,1280);
                            //设置相机的横竖屏(竖屏需要旋转90°)
                            if (getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
                                //params.set("orientation", "portrait");
                                params.set("video-rotation","90");
                                //设置预览图像的旋转方向video-rotation=90
                                //mCamera.setDisplayOrientation(0);
                            } else {
                                //params.set("orientation", "landscape");
                                params.set("video-rotation","0");
                                //设置预览图像的旋转方向
                                //mCamera.setDisplayOrientation(90);
                            }
                            //设置聚焦模式
                            params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
                            //缩短Recording启动时间
                            params.setRecordingHint(true);
                            //影像稳定能力
                            if (params.isVideoStabilizationSupported())
                                params.setVideoStabilization(true);
                            mCamera.setParameters(params);
                            //mCamera.setDisplayOrientation(90);
                        }
                    });
    
                    popupWindow.setTouchable(true);
    
                    popupWindow.setTouchInterceptor(new View.OnTouchListener() {
    
                        @Override
                        public boolean onTouch(View v, MotionEvent event) {
    
                            Log.i("mengdd", "onTouch : ");
    
                            return false;
                            // 这里如果返回true的话,touch事件将被拦截
                            // 拦截后 PopupWindow的onTouchEvent不被调用,这样点击外部区域无法dismiss
                        }
                    });
    
                    // 如果不设置PopupWindow的背景,无论是点击外部区域还是Back键都无法dismiss弹框
                    // 我觉得这里是API的一个bug
                    popupWindow.setBackgroundDrawable(getResources().getDrawable(
                            R.drawable.ic_launcher_background));
    
                    // 设置好参数之后再show
                    popupWindow.showAsDropDown(view);
                    break;
            }
    
        }
    
        /**
         * 初始化摄像头
         *
         * @throws IOException
         */
        private void initCamera() {
            if (mCamera != null) {
                releaseCamera();
            }
                mCamera = Camera.open(0);
            if (mCamera == null) {
                Toast.makeText(this, "未能获取到相机!", Toast.LENGTH_SHORT).show();
                return;
            }
            try {
                //将相机与SurfaceHolder绑定
                mCamera.setPreviewDisplay(mSurfaceHolder);
                //配置CameraParams
                configCameraParams();
                //启动相机预览
                mCamera.startPreview();
            } catch (IOException e) {
                //有的手机会因为兼容问题报错,这就需要开发者针对特定机型去做适配了
                Log.e(TAG, "Error starting camera preview: " + e.getMessage());
            }
        }
    
        /**
         * 切换摄像头
         */
        public void switchCamera() {
            Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
            int cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数0或者1;
            try {
                for (int i = 0; i < cameraCount; i++) {
                    Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息
                    if (cameraFlag == 1) {
                        //后置到前置
                        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表摄像头的方位,CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置
                            //frontCameraRotate();//前置旋转摄像头度数
                            switchCameraLogic(i, 0, 90);
                            break;
                        }
                    } else {
                        //前置到后置
                        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表摄像头的方位,CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置
                            switchCameraLogic(i, 1, 90);
                            break;
                        }
                    }
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }
    
        /***
         * 处理摄像头切换逻辑
         *
         * @param i           哪一个,前置还是后置
         * @param flag        切换后的标志
         * @param orientation 旋转的角度
         */
        private void switchCameraLogic(int i, int flag, int orientation) {
            if (mCamera != null) {
                mCamera.lock();
            }
            releaseCamera();
            mCamera = Camera.open(i);//打开当前选中的摄像头
            try {
                mCamera.setDisplayOrientation(orientation);
                mCamera.setPreviewDisplay(mSurfaceHolder);
            } catch (IOException e) {
                e.printStackTrace();
            }
            cameraFlag = flag;
            FlashLogic(mCamera.getParameters(), 0, false);
            mCamera.startPreview();
            cameraType = i;
            mCamera.unlock();
        }
    
        /**
         * 闪光灯逻辑
         *
         * @param p    相机参数
         * @param type 打开还是关闭
         * @param isOn 是否启动
         */
        private void FlashLogic(Camera.Parameters p, int type, boolean isOn) {
            flashType = type;
            if (type == 0) {
                if (isOn) {
                    p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                    mCamera.setParameters(p);
                }
            } else {
                if (isOn) {
                    p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                    mCamera.setParameters(p);
                }
            }
        }
    
        /**
         * 配置MediaRecorder()
         */
        private void configMediaRecorder() {
            mediaRecorder = new MediaRecorder();
            mediaRecorder.reset();
            mediaRecorder.setCamera(mCamera);
            mediaRecorder.setOnErrorListener(OnErrorListener);
            //使用SurfaceView预览
            mediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
            //1.设置采集声音
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            //设置采集图像
            mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
            //2.设置视频,音频的输出格式 mp4
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
            //3.设置音频的编码格式
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            //设置图像的编码格式
            mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
            //音频一秒钟包含多少数据位
            CamcorderProfile mProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_480P);
            mediaRecorder.setAudioEncodingBitRate(44100);
            if (mProfile.videoBitRate > 2 * 1024 * 1024) {
                mediaRecorder.setVideoEncodingBitRate(2 * 1024 * 1024);
                Log.e("aaa","1024*1024");
            }
            else {
                mediaRecorder.setVideoEncodingBitRate(1024 * 1024);
                Log.e("bbb","1024*1024");
            }
            mediaRecorder.setVideoFrameRate(mProfile.videoFrameRate);
            //设置选择角度,顺时针方向,因为默认是逆向90度的,这样图像就是正常显示了,这里设置的是观看保存后的视频的角度
            mediaRecorder.setOrientationHint(90);
            //设置录像的分辨率
            mediaRecorder.setVideoSize(720, 1280);
            //设置录像视频输出地址
            mediaRecorder.setOutputFile(currentVideoFilePath);
        }
    
        /**
         * 创建视频文件保存路径
         */
        private String getVideoFilePath(Context context) {
            final File dir = context.getExternalFilesDir(null);
            return (dir == null ? "" : (dir.getAbsolutePath() + "/"))
                    + System.currentTimeMillis() + ".mp4";
        }
        public static String getSDPath(Context context) {
            if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
                Toast.makeText(context, "请查看您的SD卡是否存在!", Toast.LENGTH_SHORT).show();
                return null;
            }
            File sdDir = Environment.getExternalStorageDirectory();
            File eis = new File(sdDir.toString() + "/RecordVideo/");
            if (!eis.exists()) {
                eis.mkdir();
            }
            return sdDir.toString() + "/RecordVideo/";
        }
    
        private String getVideoName() {
            return "VID_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".mp4";
        }
    
        //activity监听屏幕旋转
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
                // Nothing need to be done here
                Log.e("TAG", "横屏");
                Toast.makeText(this, "1", Toast.LENGTH_SHORT);
                //处理代码
                // 设置分辨率
                ViewGroup.LayoutParams lp = surfaceView.getLayoutParams();
                lp.width = 720;
                lp.height =1280;
                surfaceView.setLayoutParams(lp);
            } else {
                // Nothing need to be done here
                Log.e("TAG", "竖屏");
                Toast.makeText(this, "1", Toast.LENGTH_SHORT);
                //处理代码
                // 设置分辨率
                ViewGroup.LayoutParams lp = surfaceView.getLayoutParams();
                lp.width = 720;
                lp.height =1280;
                surfaceView.setLayoutParams(lp);
            }
        }
    }
    
    //权限
    <uses-permission android:name="android.permission.FLASHLIGHT" />
        <!--相机必须权限-->
        <uses-permission android:name="android.permission.CAMERA" />
        <!--相机录像权限-->
        <uses-permission android:name="android.permission.RECORD_AUDIO" />
        <!--存储读写权限-->
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <!--如果需要用GPS位置信息标记图像,则必须请求设置此权限-->
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <!-- 下面这个特性声明针对Android 5(API级别21)或更高才需要添加-->
        <uses-feature android:name="android.hardware.location.gps" />
        <uses-feature android:name="android.hardware.camera" />
        <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
        <uses-permission android:name="android.hardware.camera.autofocus" />
        <uses-feature android:name="android.hardware.autofocus"/>
    
    <SurfaceView
            android:id="@+id/record_surfaceView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:background="#80ffffff"
            android:padding="10dp">
    
            <!-- 开始/结束 录制按钮 -->
            <ImageView
                android:id="@+id/record_control"
                android:layout_width="60dp"
                android:layout_height="60dp"
                android:layout_centerInParent="true"
                android:onClick="startRecord"
                android:src="@drawable/recordvideo_start" />
    
            <ImageView
                android:id="@+id/record_pause"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_centerVertical="true"
                android:onClick="stopRecord"
                android:src="@drawable/control_pause"
                android:visibility="gone" />
    
            <Chronometer
                android:id="@+id/record_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_alignParentRight="true"
                android:format="%s" />
    
        </RelativeLayout>
    
    control_pause.png control_play.png record_camera_switch_normal.png recordvideo_start.png recordvideo_stop.png seek_bkg.png seekbar_thumb_normal.png seekbar_thumb_pressed.png

    相关文章

      网友评论

          本文标题:Camera1

          本文链接:https://www.haomeiwen.com/subject/vuusxctx.html