录制相机一路踩坑

最近公司在做相机录制功能,这方面正好交给我负责,不得不说太多坑了。特此记录一下,

  • MediaRecorder 配置顺序不对报错

    03-21 14:47:47.279 571-30355/? E/mm-camera: c2d_module_stop_session:365, info: session 3 stopped.
    03-21 14:47:47.279 571-30355/? E/mm-camera-img: cac3_comp_dealloc:1240] ptr 0xb67811a4
    03-21 14:47:47.279 571-30355/? E/cac3:  [cac3_buffer_latency] memfree for 0xae24e000, mem size 4063232 bytes: 0 ms 
    03-21 14:47:47.279 571-30355/? E/cac3:  [cac3_buffer_latency] memfree for 0xaea0e000, mem size 4063232 bytes: 0 ms 
    03-21 14:47:47.279 571-30355/? E/cac3:  [cac3_buffer_latency] memfree for 0xae62e000, mem size 4063232 bytes: 0 ms 
    03-21 14:47:47.279 571-30355/? E/cac3:  [cac3_buffer_latency] memfree for 0xb1841000, mem size 3997696 bytes: 0 ms 
    03-21 14:47:47.289 571-30355/? E/cac3:  [cac3_buffer_latency] memfree for 0xb10a2000, mem size 7991296 bytes: 0 ms 
    03-21 14:47:47.289 571-30355/? E/cac3:  [cac3_buffer_latency] memfree for 0xb0903000, mem size 7991296 bytes: 0 ms 
    03-21 14:47:47.289 571-30355/? E/cac3:  [cac3_buffer_latency] memfree for 0xb00fc000, mem size 8417280 bytes: 0 ms 
    03-21 14:47:47.289 571-30355/? E/cac3:  [cac3_buffer_latency] memfree for 0xafd2c000, mem size 3997696 bytes: 0 ms 
    03-21 14:47:47.289 571-30355/? E/cac3:  [cac3_buffer_latency] memfree for 0xaedee000, mem size 15982592 bytes: 0 ms 
    03-21 14:47:47.289 571-30355/? E/cac3:  [cac3latency] cac3_destroy_buffers: 1 ms 
    03-21 14:47:47.289 571-571/? E/mm-camera: mct_pipeline_stop_session: left modules: 1
    03-21 14:47:47.319 571-571/? E/mm-camera: mct_pipeline_stop_session: left modules: 0
    

    配置错误或者配置顺序不对,录制时统一会退出录制页面。这个坑真心大,有时候配置了属性,都不知道是哪一个出错了,只能一个个排除。

    这里给一个我自己的配置

         private boolean prepareMediaRecorder() {
            try {
                mediaRecorder = new MediaRecorder();
                mCamera.unlock();
                mediaRecorder.setCamera(mCamera);
    
                // Step 2: Set sources
                mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    
                // Step 3: Set a Camera Parameters
                mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
                 /* Fixed video Size: 1280 * 720*/
    
                mediaRecorder.setVideoSize(1280, 720);
    
                /* Encoding bit rate: 2 * 1024 * 1024*/
                //设置视频编码帧率
                mediaRecorder.setVideoEncodingBitRate(2 * 1024 * 1024);
                mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
                mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);//设置音频编码为
    
                mediaRecorder.setOrientationHint(rotationRecord);//改变保存后的视频文件播放时旋转角度
    
                //设置录制路径
                String path = Utils.getVideoPath(RecordingActivity.this);
                File file = new File(path);
                if (!file.exists()) {
                    file.mkdirs();
                }
                Date d = new Date();
                String timestamp = String.valueOf(d.getTime());
                videoPath = path + "/" + timestamp + ".mp4";
                File file1 = new File(videoPath);
                if (file1.exists()) {
                    file1.delete();
                } else {
                    file1.createNewFile();
                }
                mediaRecorder.setOutputFile(videoPath);
                // 准备录制
                mediaRecorder.prepare();
            } catch (IllegalStateException e) {
                e.printStackTrace();
                releaseMediaRecorder();
                return false;
            } catch (IOException e) {
                e.printStackTrace();
                releaseMediaRecorder();
                return false;
            }
            return true;
    
        }
    
  • 录制出来的视频使用videoView进行预览,画面拉伸变形

    当时我配置MediaRecorder时,采用的是setProfile方式,当初为了录制视频尽可能的小,采用的是CamcorderProfile.QUALITY_480P ,当时在网上搜索解决方案,发现都是在说解决预览画面拉伸变形。后来进过多次尝试发现使用CamcorderProfile.QUALITY_720P 及以上的 不会出现拉伸变形问题,这里问题又来了,这样录制的大小完全超出规定。

    最终解决方案就是采用上面的配置方式,录制出来的视频不大,而且不变形,清晰度不也不会有特别大的影响。

  • 视频录制与播放(竖屏)旋转问题


    OrientationEventListener orientationEventListener;
      int rotationRecord = 90;
      int rotationFlag = 90;
    /**
       * 旋转界面UI
       */
      private void rotationUIListener() {
          orientationEventListener = new OrientationEventListener(this) {
              @Override
              public void onOrientationChanged(int rotation) {
                  if (!recording) {
                      if (((rotation >= 0) && (rotation <= 30)) || (rotation >= 330)) {
                          // 竖屏拍摄
                          if (rotationFlag != 0) {
                              //这是竖屏视频需要的角度
                              rotationRecord = 90;
                              //这是记录当前角度的flag
                              rotationFlag = 0;
                          }
                      } else if (((rotation >= 230) && (rotation <= 310))) {
                          // 横屏拍摄
                          if (rotationFlag != 90) {
                              //这是正横屏视频需要的角度
                              rotationRecord = 0;
                              //这是记录当前角度的flag
                              rotationFlag = 90;
                          }
                      } else if (rotation > 30 && rotation < 95) {
                          // 反横屏拍摄
                          if (rotationFlag != 270) {
                              //这是反横屏视频需要的角度
                              rotationRecord = 180;
                              //这是记录当前角度的flag
                              rotationFlag = 270;
                          }
                      }
                  }
              }
          };
          orientationEventListener.enable();
      }

mediaRecorder.start(); 后进行disable() orientationEventListener.disable();mediaRecorder.stop(); 后进行enable() orientationEventListener.enable();

  • java.lang.RuntimeException: Method called after release()
  java.lang.RuntimeException: Method called after release()
  at android.hardware.Camera.setPreviewDisplay(Native Method)
  at android.hardware.Camera.setPreviewDisplay(Camera.java:555)

这个问题在录制视频同时来电了。重新接完电话重新回到相机预览页面,程序奔溃了

网上的解决办法感觉就是一个人写,万人拷贝。全部都是在mcamera.stopPreview() 前进行mCamera.setPreviewCallback(null); ,这样的解决办法在我这里完全无效。最终寻求到的解决办法是

  private void releaseCamera() {
          if (mCamera != null) {
              mCamera.setPreviewCallback(null);
              // TODO: 2017/3/20 不加这个打电话会闪退
              mPreview.getHolder().removeCallback(mPreview);
              mCamera.stopPreview();
              mCamera.release();
              mCamera = null;
          }
      }

添加一个mPreview.getHolder().removeCallback(mPreview); 完美解决

你可能感兴趣的:(录制相机一路踩坑)