Android 오디오 및 비디오 개발 (6) MediaRecorder 녹화 비디오

소개

Android api는 카메라를 제어하여 이미지를 캡처하는 Camera 클래스를 제공합니다. api21 이후 Android도 Camera2를 제공합니다. 비디오 녹화를 위해 Android 공식 API 문서
에서 볼 수 있는 MediaRecorder를 사용할 수 있습니다.

사용

카메라를 사용하여 사진과 비디오를 찍기 전에 먼저 권한을 신청해야 합니다.

<!-- 相机权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 录音权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 相机模块 -->
<uses-feature android:name="android.hardware.camera"/>
<!-- 自动对焦模块 -->
<uses-feature android:name="android.hardware.camera.autofocus"/>

다음으로 카메라 미리보기 프로세스:

  1. Camera.open(int) 카메라 인스턴스 가져오기
  2. setParameters 카메라 매개변수 설정
  3. setDisplayOrientation은 올바른 미리보기 방향을 설정합니다.
  4. 미리보기 화면을 표시하도록 SurfaceView 연결
  5. startPreview는 미리보기를 시작하고 stopPreview는 미리보기를 중지합니다.
  6. 릴리스 릴리스 카메라 리소스

비디오 녹화 과정:

  1. 오디오 및 비디오 녹음을 위한 MediaRecorder 개체 만들기
  2. MediaRecorder와 카메라를 연결하여 카메라에서 이미지 캡처
  3. MediaRecorder 관련 매개변수, 비디오 형식, 인코딩, 크기 등을 설정합니다.
  4. setOrientationHint는 비디오의 최종 회전 각도를 설정할 수 있습니다.
  5. start 녹음 시작, stop 녹음 중지
  6. 릴리스릴리스 리소스

지면이 너무 길어지는 것을 방지하기 위해 여기에 모든 코드를 표시하지는 않겠습니다. 자세한 코드는 github 소스 코드를 참조하십시오.

다음으로 몇 가지 핵심 사항을 나열하겠습니다.

비디오 품질

비디오 품질은 비디오 선명도와 파일 크기에 직접적인 영향을 미치므로 개인의 필요에 따라 조정할 수 있으며 비트 전송률은 너무 작거나 너무 커서는 안 됩니다.

/**
     * 获取适合的视频质量配置
     * 影响视频清晰度和文件大小,根据自身需要调整
     * @param cameraID 摄像头ID
     */
    fun getBestCamcorderProfile(cameraID: Int): CamcorderProfile? {
    
    
        var profile: CamcorderProfile? = null
        when {
    
    
            CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_1080P) -> {
    
     //1080P,优先
                profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_1080P)
            }
            CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_720P) -> {
    
     //720P
                profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_720P)
            }
            CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_480P) -> {
    
     //480P
                profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_480P)
            }
            CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_HIGH) -> {
    
    //高品质
                profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_HIGH)
                profile.videoBitRate /= 8
                return profile
            }
            CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_CIF) -> {
    
    
                profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_CIF)
                return profile
            }
            CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_QVGA) -> {
    
    
                profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_QVGA)
            }
            CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_LOW) -> {
    
    
                profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_LOW)
            }
        }
        if (profile != null) {
    
    
            //视频码率
            profile.videoBitRate = 6000000
        }
        return profile
    }

비디오 미리보기 각도

 /**
     * 根据屏幕方向获取对应预览角度
     * setDisplayOrientation只能改变预览的角度,与视频最终结果角度无关
     * @param cameraID 相机ID
     */
    fun getCameraPreviewOrientation(cameraID: Int, activity: Activity): Int {
    
    
        val info = Camera.CameraInfo();
        Camera.getCameraInfo(cameraID, info);
        //屏幕选择角度
        val rotation = activity.windowManager.defaultDisplay.rotation
        var degrees = 0
        when (rotation) {
    
    
            Surface.ROTATION_0 ->
                degrees = 0
            Surface.ROTATION_90 ->
                degrees = 90
            Surface.ROTATION_180 ->
                degrees = 180
            Surface.ROTATION_270 ->
                degrees = 270
        }
        var result = 90
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
    
    
            result = (info.orientation + degrees) % 360
            result = (360 - result) % 360
        } else {
    
    
            result = (info.orientation - degrees + 360) % 360
        }
        return result;
    }

카메라 미리보기

 /**
     * 初始化相机设置并开启预览
     */
    private fun startPreview() {
    
    
        try {
    
    
            //开启后置摄像头
            camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK)
              //设置预览角度
            val rotation = CameraUtil.getCameraPreviewOrientation(Camera.CameraInfo.CAMERA_FACING_BACK,this)
            camera?.setDisplayOrientation(rotation)
            // 在SurfaceView上预览
            camera?.setPreviewDisplay(sv_camera.holder)
            val parameters = camera?.getParameters()
              //获取支持的预览大小,注意这里获取的宽高是根据横屏的
            val sizes = parameters?.supportedPreviewSizes
            //宽高建议根据横竖屏切换
            val previewSize =
                CameraUtil.findFitPreviewSize(sv_camera.height,sv_camera.width,sizes)
            if (previewSize != null) {
    
    
                //设置预览大小
                parameters?.setPreviewSize(previewSize.width, previewSize.height)
            }
            //设置自动对焦模式
            CameraUtil.setAutoFocusMode(parameters)
            camera?.setParameters(parameters)
            //开始预览
            camera?.startPreview()
        } catch (e: Exception) {
    
    
            Log.e("Test", "出错了", e)
        }
    }

녹화

    /**
     * 开始录制
     * 注意方法调用的先后顺序
     */
    private fun startRecorder() {
    
    
        if (camera == null) {
    
    
            return
        }
        if (recorder != null) {
    
    
            stopRecord()
        }
        try {
    
    
            val videoSize = CameraUtil.findFitVideoSize(camera!!.parameters,
                sv_camera.height / sv_camera.width.toFloat()
            )
            //先停止camera预览,释放camera
            camera?.stopPreview()
            camera?.unlock()
            //创建MediaRecorder对象
            recorder = MediaRecorder()
            //关联camera
            recorder?.setCamera(camera)
            //设置视频角度;
            val rotation =
                CameraUtil.getCameraPreviewOrientation(Camera.CameraInfo.CAMERA_FACING_BACK, this)
            recorder?.setOrientationHint(rotation)
            //设置预览区域
            recorder?.setPreviewDisplay(sv_camera.holder.surface)
            //设置音频来源
            recorder?.setAudioSource(MediaRecorder.AudioSource.MIC)
            //设置视频来源,来自摄像头
            recorder?.setVideoSource(MediaRecorder.VideoSource.CAMERA)

            //设置输出格式
//            recorder?.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
            val profile = CameraUtil.getBestCamcorderProfile(Camera.CameraInfo.CAMERA_FACING_BACK)
            if (profile != null) {
    
    
                //设置视频码率
                recorder?.setProfile(profile)
            }
            //设置视频帧率,注意设备支持
            recorder?.setVideoFrameRate(30)
            //设置视频宽高
            recorder?.setVideoSize(videoSize.width, videoSize.height)
            val file =
                File(getExternalFilesDir(Environment.DIRECTORY_MOVIES)?.absolutePath, "test.mp4")
            //设置音频文件的存储位置 {
    
    
            recorder?.setOutputFile(file.absolutePath)
            //准备
            recorder?.prepare()
            //开始录制
            recorder?.start()
            ct_time.start()
        } catch (e: Exception) {
    
    
            Log.e("Test", e.message, e)
        }
    }

위는 Camera+MediaRecord로 영상을 녹화하는 방법입니다! 을 그만하기로하다! 질문이 있으시면 토론을 위해 질문을 제기하십시오.

추천

출처blog.csdn.net/gs12software/article/details/105214944