Android 简单的视频录制

224 阅读1分钟

Android 视频录制

预览

Camera和SurfaceView组合实现预览

 public CameraHepler{
   /*
    *打开默认的摄像头
    */
    public static Camera getDefaultCameraInstance(){
        return Camera.open();
    }
    /*
    *获取前置摄像头
    */
    public static Camera getDefaultFrontFacingCameraInstance()          
    {
      return getDefaultCamera(Camera.Info.CAMERA_FACING_FRONT);
    }
   
    /*
    *获取后置摄像头
    */
    public static Camera getDefaultFrontBackCameraInstance()          
    {
      return getDefaultCamera(Camera.Info.CAMERA_FACING_FRONT);
    }
    /*
    *获取后置摄像头 返回null表示 没有可用的摄像头
    */
    public static Camera getDefaultCamera(int position){
      int numberOfCameras = Camera.getNumberOfCameras();
      Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
      for(int i = 0; i < numberOfCameras; i++){
        Camera.getCameraInfo(i, cameraInfo);
        if(cameraInfo.facing == position){
           return Camera.open(i);
        }
      }
       return null;
    }
    /*
    *获取最合适的预览尺寸
    */
   public static Camera.Size getOptimalPreviewSize(List<Camera.size> sizes, int w, int h){
      //取很小的值
     final double ASPECT_TOLERANCE = 0.1;
     double targetRadio = (double)w/h;
     if(w==0 && h==0){
       return null;
     }
     int targetHeight = h ;
     Camera.size optimalSize = null;
     double minDiff = Double.Max_VALUE;
     for(Camera.size size: sizes){
       double radio = (double)w/h;
       if(Math.abs(radio - targetRadio) > ASPECT_TOLERANCE){
          continue;
       }
       if(Math.abs(size.height - targetHeight) < minDiff){
           minDiff = Math.abs(size.height - targetHeight);
           optimalSize = size;
       }
     }
     if(optimalSize == null){
       for(Camera.size size : sizes){
          minDiff = Double.Max_VALUE;
          if(Math.abs(size.height - targetHeight)<minDiff){
             minDiff = Math.abs(size.height - targetHeight);
             optimalSize = size;
          }
       }
     }
     return optimalSize;
   }
 }

获取到可用的摄像头之后,配置预览数据,注意⚠️,这个得等待SurfaceView加载完成后调用

private boolean prepareCamera(SurfaceHoler holder){
     //获取摄像头
     Camera mCamera = CameraHepler.getDefaultFrontFacingCameraInstance();
     if(mCamera == null){
       return false;
     }
     Camera.Parameters parameters = mCamera.getParameters();
     //获取该Camera预览支持的尺寸大小
     List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
     //从支持的尺寸中找到最合适的预览尺寸
     Camera.Size previewSize = CameraHelper.getOptimalPreviewSize(sizes, surfaceView.getWidth, surfaceView.getHeight);
    mCamera.setDisplayOrientation(90);
    parameters.setPreviewSize(previewSize.width, previewSize.height);
    mCamera.setParameters(parameters)
    
    try{
      //最好在 surfaceCread(SurfaceHolder holer)调用,以确保holer可用
      //Camera展示数据的容器
      mCamera.setPreviewDisplay(holder);
      mCamera.setPreviewCallback(null);
      //开始预览
      mCamera.startPreview();
    }catch(Exception e){
      e.printStackTrace();
      return false;
    }
    return true;
}



​ Camera配置必须在SurfaceHolder加载成功后才能设置mCamera.setPreviewDisplay(holder),然而这么确保已经加载出SurfaceHolder呢?

 SurfaceHolder surfaceHolder = surfaceView.getHolder();
 //如果要在预览界面展示其他View,需要做以下设置
 surfaceView.setZOrderOnTop(false);
 surfaceHoler.addCallBack(new SurfaceHoler.Callback{
   @override
   public void surfaceCreated(SurfaceHolder holder){
     prepareCamera(holder);
   }
   @override
   public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){
     
   }
   @override
   public void surfaceDestory(SurfaceHolder holder){
     //todo 释放资源
   }
 });
 

MeidaRecorder 录制视频

 //录制视频之前,需要调用Camera的unlock函数
 mCamera.unlock();
 //设置存储视频的路径
 String path = "";
 File videoFile = new File(path);
 if(!videoFile.exists()){
    video.getPartentFile().mikrs();
 }
 //创建MediaRecorder实例
 MediaRecorder mediaRecorder = new MediaRecorder();
//设置音频来源 
 mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//设置视频来源
 mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
 
 mediaRecorder.setOrientation(270);
 mediaRecorder.setOutputFile(videoFile.getAbsolutePath());
 //设置要保存的视频质量
 CamCorderProfile camcorderProfile =      
    CamCorderProfile.get(Camera.CameraInfo.CAMERA_FACING_FRONT, CamcorderProfile.QUALITY_LOW);
  mediaRecorder.setProfile(camcorderProfile);
  mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
  //开始之前必须调用
  mediaRecorder.prepare();
  //最好在工作线程开始
  mediaRecorder.start();