安卓录像功能的实现

1、简介
2、参数初始化
3、开始录像
4、结束录像

1、简介

本文的编辑工具类CameraUtils,可直接下载使用。

这里写图片描述
如上图所示MediaRecorder的工作流程主要包括以下几步:
第一步:Initial:初始化操作,针对MediaRecorder对象的创建,如果需要预览,则需初始化Surface控件和holder对象;打开相机。Initialized:MediaRecorder参数的设置包括音频和视频参数的设置,由于在录音操作时使用的仍然是MediaRecorder实现,因此如果是对于录像操作,这里的设置如下:

mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

第二步: 完成输入源设置后,录制的视频资源需要将其保存至本地,这里需要设置保存的路径地址

mediaRecorder.setOutputFile()

第三步 DataSourceConfigured:该过程是对视频格式、音频视频编码格式和帧速以及尺寸的设置,这里需要注意对于帧速和尺寸设置时,需要确定该参数系统硬件支持,否则设置后会报“start failed: -19”错误。

    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
    mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    mediaRecorder.setVideoEncodingBitRate(700*1024);
    mediaRecorder.setVideoSize(width,height);
    mediaRecorder.setVideoFrameRate(24);

当然在设置Initialized和DataSourceConfigured之前,需要将相机资源解锁,并将其分配至MediaRecorder对象中。

    camera.unlock();
    mediaRecorder.setCamera(camera);

至此,我们完成了对于MediaRecorder初始化的操作,进入第四步Prepared阶段。

    mediaRecorder.prepare();

调用该参数完成准备阶段。调用以下方法,则由Prepared阶段进入Recording阶段。实现了录像过程。

    mediaRecorder.start();

当我们调用stop()或者reset()后,则完成了本阶段的录制,重新进入准备阶段。
当我们初始化阶段时,调用relsease()进入休眠状态,释放相机资源。

2、参数初始化

① SurfaceView的初始化

// setType必须设置,要不出错.
        surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        surfaceView.setKeepScreenOn(true);
        callback = new SurfaceHolder.Callback() {
            public void surfaceCreated(SurfaceHolder holder) {
                camera = Camera.open();
                getVideoSize();
                mediaRecorder = new MediaRecorder();

            }

            public void surfaceChanged(SurfaceHolder holder, int format,
                                       int width, int height) {
                doChange(holder);
                focus();
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                if (camera != null) {
                    camera.release();
                    camera = null;
                }
            }
        };
        surfaceView.getHolder().addCallback(callback);

② 相机参数设置

 /**
     * 聚焦
     */
    public void focus(){
        Camera.Parameters parameters=camera.getParameters();
        parameters.setPictureSize(widthPhoto,heightPhoto);
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        camera.setParameters(parameters);
        camera.cancelAutoFocus();
    }

③ 获取支持的相机参数

 /***
     * 获取SupportedVideoSizes 控制输出视频width在300到600之间(尽可能小)
     * 获取PictureSize的大小(控制在w:1000-2000之间)
     */
    public void getVideoSize() {
        Camera.Parameters parameters = camera.getParameters();
        List<Camera.Size> videoSize = parameters.getSupportedVideoSizes();
        for (int i = 0; i < videoSize.size(); i++) {
            int width1 = videoSize.get(i).width;
            int height1 = videoSize.get(i).height;
            if (width1 >= 300 && width1 <= 600) {
                if (height1 >= 200 && height1 <= 600) {
                    width = width1;
                    height = height1;
                }
            }
//            Log.d(TAG, "getVideoSize:----w:-- " + videoSize.get(i).width + "---h:--" + videoSize.get(i).height);
        }
        List<Camera.Size> photoSize = parameters.getSupportedPictureSizes();
        for (int i = 0; i < photoSize.size(); i++) {
            int width1 = photoSize.get(i).width;
            int height1 = photoSize.get(i).height;
            if (width1 >= 1000 && width1 <= 2000) {
                if (height1 >= 600 && height1 <=2000) {
                    widthPhoto = width1;
                    heightPhoto = height1;
                }
            }
        }
    }

3、开始录像

 /**
     * @param path 保存的路径
     * @param name 录像视频名称(不包含后缀)
     */
    public void startRecord(String path, String name) {
        //解锁摄像头并将其分配给MediaRecorder
        camera.unlock();
        mediaRecorder.setCamera(camera);

        //指定用于录制的输入源
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        //mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
        //设置配置文件,或者定义输出格式,音频视频编码器,帧速以及输出尺寸
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
        // 设置录制的视频编码h263 h264
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        // 设置录制的视频帧率。必须放在设置编码和格式的后面,否则报错
        mediaRecorder.setVideoEncodingBitRate(700 * 1024);
//        设置视频录制的分辨率。必须放在设置编码和格式的后面,否则报错
        mediaRecorder.setVideoSize(width, height);
//        mediaRecorder.setVideoFrameRate(24);  //容易报错 还有上面的setVideoSize 都是需要底层支持
        //getVideoSize();
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        //指定一个输出文件
        mediaRecorder.setOutputFile(path + File.separator + name + ".mp4");
        File file1 = new File(path + File.separator + name + ".mp4");
        if (file1.exists()) {
            file1.delete();
        }
        //预览视频流,在指定了录制源和输出文件后,在prepare前设置
        mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());

        /***不设置时,录制的视频总是倒着,翻屏导致视频上下翻滚*/
        if(backOrFtont==1){//前置相机
            mediaRecorder.setOrientationHint(180);
        }else if(backOrFtont==0){
            mediaRecorder.setOrientationHint(0);
        }

        try {
            //准备录制
            mediaRecorder.prepare();
            mediaRecorder.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

4、结束录像

    /**
     * 停止录制
     */
    public void stopRecord() {
        mediaRecorder.release();
        camera.release();
        mediaRecorder = null;
        camera = Camera.open();
        mediaRecorder = new MediaRecorder();
        doChange(surfaceView.getHolder());
    }

猜你喜欢

转载自blog.csdn.net/xk7298/article/details/81605992