Camera2录像

  1. 用于录制音频和视频的一个类:MediaRecorder
  • Initial:初始状态,当使用new()方法创建一个MediaRecorder对象或者调用了reset()方法时,该MediaRecorder对象处于Initial状态。在设定视频源或者音频源之后将转换为Initialized状态。另外,在除Released状态外的其它状态通过调用reset()方法都可以使MediaRecorder进入该状态。

  • Initialized:已初始化状态,可以通过在Initial状态调用setAudioSource()或setVideoSource()方法进入该状态。在这个状态可以通过setOutputFormat()方法设置输出格式,此时MediaRecorder转换为DataSourceConfigured状态,数据源配置状态。

  • DataSourceConfigured:数据源配置状态,这期间可以设定编码方式、输出文件、屏幕旋转、预览显示等等。可以在Initialized状态通过setOutputFormat()方法进入该状态。可以通过reset()方法回到Initial状态,或者通过prepare()方法到达Prepared状态。

  • Prepared:就绪状态,在DataSourceConfigured状态通过prepare()方法进入该状态。在这个状态可以通过start()进入录制状态。
    另外,可以通过reset()方法回到Initialized状态。

  • Recording: 录制状态,可以在Prepared状态通过调用start()方法进入该状态。另外,它可以通过stop()方法或reset()方法回到Initial状态

  • Released: 释放状态(空闲状态),可以通过调用release()方法来进入这个状态,这时将会释放所有和MediaRecorder对象绑定的资源。

  • Error:错误状态,当错误发生的时候进入这个状态,它可以通过reset()方法进入Initial状态。

  1. 动态申请以下权限
    Manifest.permission.CAMERA,
    Manifest.permission.WRITE_EXTERNAL_STORAGE,
    Manifest.permission.READ_EXTERNAL_STORAGE,
    Manifest.permission.RECORD_AUDIO

  2. 初始化mediaRecord

 
//初始化MediaRecorder
    private void initMediaRecorder() {
        try {
            //进入Initial状态
            if (mediaRecorder == null) {
                mediaRecorder = new MediaRecorder();
            } else {
                //通过reset()方法
                mediaRecorder.reset();
            }
            if (cameraCaptureSession != null) {
                cameraCaptureSession.close();
                cameraCaptureSession = null;
            }
            //前后置摄像头的录制角度,前270,后90
            if (cameraId.equals(String.valueOf(CameraCharacteristics.LENS_FACING_BACK))) {
                mediaRecorder.setOrientationHint(270);
            }else {
                mediaRecorder.setOrientationHint(90);
            }
            //配置mediaRecorder
            setConfig();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  1. //自定义MediaRecorder的录制参数
private void setConfig() {
    //采集声音来源,mic是麦克风,进入initialized状态
    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    //设置视频源,从Surface里面读取画面去录制
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
    //设置封装格式 默认是MP4,进入DataSourceConfigured状态
    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    //音频编码,AAC:高级音频编码
    mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
    //图像编码,H263 多用于视频传输,其优点是压缩后体积小,占用带宽少;
    mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    //设置最大录像时间 单位:毫秒
    //mediaRecorder.setMaxDuration(60 * 1000);
    //设置最大录制的大小60M 单位,字节
    mediaRecorder.setMaxFileSize(60 * 1024 * 1024);
    //设置帧率(帧/秒),该帧率必须是硬件支持的,可以通过Camera.CameraParameter.getSupportedPreviewFpsRange()方法获取相机支持的帧率
    //设置要捕获的视频的帧速率。每秒要捕捉的视频帧数.必须在setVideoSource()后调用。在setOutputFormat()之后,在prepare()之前调用它
    mediaRecorder.setVideoFrameRate(30);
    //setVideoFrameRate在正常记录情况下使用,在延时情况下添加设置要捕获的视频的帧速率 ,setCaptureRate()。
    //相对于VideoRate的值,大于则放慢,小于加快
    if (delayflage) {mediaRecorder.setCaptureRate(10);}
    //设置视频比特率:指每秒传输速率(比特数(bit)。单位为bps(Bit Per Second),比特率越高,每秒传送数据就越多,画质就越清晰。
    //mediaRecorder.setVideoEncodingBitRate(500 * 1024 * 24);
    mediaRecorder.setVideoEncodingBitRate(previewSize.getWidth() * previewSize.getHeight() * 24);
    //设置视频尺寸,通常搭配码率一起使用,可调整视频清晰度
    mediaRecorder.setVideoSize(previewSize.getWidth(), previewSize.getHeight());
    //设置文件的输出路径
    String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera";
    File file = new File(path);
    if (!file.exists()) {
        file.mkdirs();
    }
    recordFile = new File(path + "/" + System.currentTimeMillis() + ".MP4");
    String savedpath = recordFile.getAbsolutePath();
    //设置录制的音频文件的保存位置。
    mediaRecorder.setOutputFile(savedpath);
    //在DataSourceConfigured状态通过prepare()方法进入就绪状态,在这个状态可以通过start()进入录制状态。
    try {
        //通过prepare()方法到达Prepared状态
        mediaRecorder.prepare();
    } catch (IOException e) {
        e.printStackTrace();
    }
    imageList.add(savedpath);
}
 //配置录像
    private void setVideoBuilder() {
        try {
            //创建录像请求 CaptureRequest.Builder对象
            recordRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
            // CaptureRequest.Builder添加两个surface1
            recordRequestBuilder.addTarget(previewsurface);
            //预览输出
            //设置MediaRecorder的surface
            Surface recorderSurface = mediaRecorder.getSurface();
            // CaptureRequest.Builder添加两个surface2
            recordRequestBuilder.addTarget(recorderSurface);
            //创建录像会话
            cameraDevice.createCaptureSession(Arrays.asList(previewsurface, recorderSurface), videoSessionStateCallback, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }
//创建videoSession回调
    //创建videoSession回调
    private CameraCaptureSession.StateCallback videoSessionStateCallback = new CameraCaptureSession.StateCallback() {
        @Override
        public void onConfigured(@NonNull CameraCaptureSession session) {
            try {
                cameraCaptureSession = session;
                cameraCaptureSession.setRepeatingRequest(recordRequestBuilder.build(), null, null);
                //通过调用start()方法进入Recording: 录制状态
                mediaRecorder.start();//开始录像
                startTime();//开始计时
                timer.setVisibility(View.VISIBLE);//出现
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onConfigureFailed(@NonNull CameraCaptureSession session) {
            session.close();
            cameraCaptureSession = null;
            cameraDevice.close();
            cameraDevice = null;
        }
    };
//开始计时
private void startTime() {
    timer.setBase(SystemClock.elapsedRealtime());//计时器清零
    timer.start();
}
  1. 停止录像:释放MediaRecorder(stop()->reset->release->null),开启预览
    private void stopRecord() {
        timer.stop();
        releaseMediaRecorder();
        broadcastUpdate();
        setPhotos_show(imageList.get(imageList.size() - 1));//显示最新的一张图
        startPreview();
        isRecording = false;
    }

    //释放MediaRecorder:stop()->reset->release->null
    private void releaseMediaRecorder() {
        if (mediaRecorder != null) {
            if (isRecording) {
                mediaRecorder.stop();
                mediaRecorder.reset();
                mediaRecorder.release();
                mediaRecorder = null;
                isRecording = false;
            }
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值