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自定义录像(一)之录像功能实现(附demo源码)

引言最近在做一个项目,是有关用手机摄像头做图像实时识别的。所以里面需要自定义一个录像功能。该demo实现了录像和录像后文件的保存查看,录像会实时自动对焦(AutoFocus)。根据功能分两篇讲述。这第...
  • alanjet
  • alanjet
  • 2016年08月06日 16:54
  • 11571

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

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

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

适配android 7的自定义相机的预览及拍照

import android.Manifest; import android.app.Activity; import android.content.Context; import android...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Android自定义照相机实现 拍照 录像

文档中的Camera 要使用Camera,首先我们先看一下文档(http://androiddoc.qiniudn.com/reference/android/hardware/Camera.h...

Android自定义照相机实现 拍照 录像

文档中的Camera 要使用Camera,首先我们先看一下文档(http://androiddoc.qiniudn.com/reference/android/hardware/Camera.h...

android 自定义拍照录像

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

Android 自定义相机拍照和录像

  • 2015年11月03日 17:59
  • 226KB
  • 下载

Android 自定义相机(录像) 解决预览 照片方向问题

Android 自定义相机(录像) 解决预览 照片方向问题以下是自定义相机遇到的问题: 1. 相机预览的方向 2. 相机预览时图像变形 3. 照片保存到本地的方向最近刚好公司的业务需要开发遥控拍...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android自定义相机(三) —— 录像
举报原因:
原因补充:

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