소개
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"/>
다음으로 카메라 미리보기 프로세스:
- Camera.open(int) 카메라 인스턴스 가져오기
- setParameters 카메라 매개변수 설정
- setDisplayOrientation은 올바른 미리보기 방향을 설정합니다.
- 미리보기 화면을 표시하도록 SurfaceView 연결
- startPreview는 미리보기를 시작하고 stopPreview는 미리보기를 중지합니다.
- 릴리스 릴리스 카메라 리소스
비디오 녹화 과정:
- 오디오 및 비디오 녹음을 위한 MediaRecorder 개체 만들기
- MediaRecorder와 카메라를 연결하여 카메라에서 이미지 캡처
- MediaRecorder 관련 매개변수, 비디오 형식, 인코딩, 크기 등을 설정합니다.
- setOrientationHint는 비디오의 최종 회전 각도를 설정할 수 있습니다.
- start 녹음 시작, stop 녹음 중지
- 릴리스릴리스 리소스
지면이 너무 길어지는 것을 방지하기 위해 여기에 모든 코드를 표시하지는 않겠습니다. 자세한 코드는 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로 영상을 녹화하는 방법입니다! 을 그만하기로하다! 질문이 있으시면 토론을 위해 질문을 제기하십시오.