Android自定义相机(三) —— 录像

原创 2016年08月30日 10:30:20

前面我们已经大致完成了自定义相机的拍照功能,接下来,我们来实现一下录像的功能。

1、录像功能简介

录像功能的是相对比较简单,因为步骤是很固定的,google给我们提供的api文档中说的也比较详细,这里我们主要用到 MediaRecorder 这个类。

MediaRecorder的状态图

这里写图片描述

同时还给我们提供了示例用法

这里写图片描述

2、代码实现

接下来我们就照着api中的示例做就可以了

(一)开始录像

private MediaRecorder mMediaRecorder;
    private boolean isRecord = false;
    //开始录像
    public void startRecord(){
        mCamera.unlock();
        isRecord = true;
        mMediaRecorder = new MediaRecorder();
        mMediaRecorder.reset();
        mMediaRecorder.setCamera(mCamera);
        //录制的视频的角度,要自行旋转,否则与预览角度不同 
        mMediaRecorder.setOrientationHint(90);
        if(cameraId == CameraInfo.CAMERA_FACING_FRONT){
            mMediaRecorder.setOrientationHint(270);
        }
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        // 设置录像的质量(分辨率,帧数)
        /**
        * 下面两行代码的设置也可以具体写:
        * mMediaRecorder.setVideoSize(320, 240);//分辨率
        * mMediaRecorder.setVideoFrameRate(5);//帧数
        * 用别人的demo是没有问题的,但是我自己写的过程中总是出蜜汁BUG,
        * 而且各种方法都试了也无法解决,只能放弃了
        */
        CamcorderProfile mCamcorderProfile = CamcorderProfile.get(cameraId,
                CamcorderProfile.QUALITY_720P);
        mMediaRecorder.setProfile(mCamcorderProfile);
        // 设置视频文件输出的路径  
        mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
        // 设置捕获视频图像的预览界面  
        mMediaRecorder.setPreviewDisplay(holder.getSurface());

        try {
            mMediaRecorder.prepare();
        } catch (Exception e) {
            isRecord = false;
            e.printStackTrace();
            mCamera.lock();
        }
        mMediaRecorder.start();
    }

    //------------------------ 分割线 --------------------------

    private static final int MEDIA_TYPE_IMAGE = 1;//图片类型
    private static final int MEDIA_TYPE_VIDEO = 2;//视频类型

    //获取文件保存的位置,目录不存在就创建
    private File getOutputMediaFile(int type) {
        File mediaFile = null;
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            String filePath = "/sdcard/WaterCamera";
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
            if (type == MEDIA_TYPE_IMAGE){
                mediaFile = new File(filePath + File.separator +
                        "IMG_"+ timeStamp + ".jpg");
            } else if(type == MEDIA_TYPE_VIDEO) {
                mediaFile = new File(filePath + File.separator +
                        "VID_"+ timeStamp + ".mp4");
            }
            if(!mediaFile.exists()){
                if(!mediaFile.getParentFile().exists()){
                    mediaFile.getParentFile().mkdirs();
                }
                try {
                    mediaFile.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return mediaFile;
    }

(二)结束录像

//停止录像
public void stopRecord(){
    if(mMediaRecorder !=null){
           if(isRecord){
               mMediaRecorder.stop();
               mMediaRecorder.reset();
               mMediaRecorder.release();
               mMediaRecorder =null;
               isRecord = false;
           }
       }
    //重新设置预览,否则会出现连续拍照崩溃的问题
    mCamera.stopPreview();//停掉原来摄像头的预览
       mCamera.release();//释放资源
       mCamera = null;
    //重新预览
    mCamera = Camera.open(cameraId);
    setCameraParams(this.getWidth(),this.getHeight());
    try {
        mCamera.setPreviewDisplay(holder);
    } catch (IOException e) {
        e.printStackTrace();
    }
    mCamera.startPreview();
}

3、遇到的问题

虽然步骤很简单,但是也有一些坑,最常见的就是 start failed: -19 这个错误了:

这里写图片描述

这个问题真是困扰了我一段时间,肯定是start之前设置有问题,主要问题还是出在这两行代码:

mMediaRecorder.setVideoSize(320, 240);//分辨率
mMediaRecorder.setVideoFrameRate(5);//帧数

用这种方式写,无论是想根据摄像头支持的分辨率列表里面找合适的尺寸我这里都会出现bug,网上也有说注释掉这两句,或者添加camera.lock()和camera.unlock()之类的都不管用,不过在别人的demo里面这么写是完全正常的,后来还是看别人的写法,采用这种写法,才没报错:

CamcorderProfile mCamcorderProfile = CamcorderProfile.get(cameraId,
CamcorderProfile.QUALITY_720P);
mMediaRecorder.setProfile(mCamcorderProfile);

在上面代码的参数CamcorderProfile.QUALITY_720P是可以自己调节的,一半是CamcorderProfile.QUALITY_HIGH,但是我设置成这个参数会导致预览界面图像被压缩,所以就找了个看着比较正常的填了进去。

小结

录像功能基本算是完成了,虽然很粗糙,下面贴一下我的自定义的surfaceview吧,用法比较简单,在layout中引用,Activity中用 CameraSurfaceView.getInstance() 获取对象然后点出方法就可以。
链接:
CameraSurfaceView.java
MatrixUtils.java

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

android 自定义拍照录像

自定义拍照和录像功能。拍完照或录完视频后,弹出另一界面,显示拍的照片或录制的视频: 拍照界面: 界面中的按钮,点击是拍照,长按是摄像,摄像时,按钮周围有圆形进度条显示进度 TakePicActivit...

Fragment使用姿势之NoFragment

NoFragment支持传统Fragment用法,支持startFragmentForResult,支持一个Fragment启动多个实例,自持自动维护Back Stack,顺序不会错乱,支持Fragm...

Android 自定义视频录制终极解决方案(翻转问题)

Android 自定义视频录制翻转问题终极解决方案 自定义视频录制 使用系统可用播放器 前后摄像和视频反转问题 总结 自定义视频录制mediarecorder = new MediaRecorder(...

android下自定义Camera进行录像和拍照

android自定义相机进行拍照和录像保存

Android自定义相机(二) —— 前置摄像头

前言前面我们已经实现了基本的相机拍照的功能,今天我们来实现一下前后相机切换的功能

Android自定义相机(一)

前言关于Android相机,或者图像处理的内容,如果只是预览图像,拍摄照片的话,那么谷歌给我们提供了很多api可以让我们轻松完成这些简单的功能,但是如果想要深入研究的话,图像处理又是非常复杂的一块内容...

Camera进阶,自定义拍照录像界面

Camera 官方指南,英语不太好,翻译有可能不准确,见谅 o(^▽^)o 自定义拍照,录像项目 下载地址 上一篇:初识Camera,调用系统拍照录像程序 在项目中创建一个自定...
  • krubo1
  • krubo1
  • 2016-01-08 09:18
  • 1431
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)