安卓api提供了Camera类控制相机捕获图像,在api21以后,安卓也提供了Camera2,Camera变得过时了,但为了兼容性,这里还是使用Camera。
对于录制视频,可以使用MediaRecorder,这个可看安卓官方api文档
使用Camera进行拍照摄像前,你得先申请权限:
接着,是相机预览流程:
Camera.open(int)获取Camera实例
setParameters设置相机参数
setDisplayOrientation设置正确预览方向
关联SurfaceView,用于展示预览画面
startPreview开始预览,stopPreview停止预览
release释放相机资源
录像流程:
创建MediaRecorder对象,用于录制音频视频
关联MediaRecorder和Camera,捕获从Camera传来的画面
设置MediaRecorder相关参数,视频格式、编码、大小等等
setOrientationHint可设置视频最终旋转角度
start开始录制,stop停止录制
release释放资源
为了防止篇幅过长,我这里就不展示全部代码了,详细代码请可以留言
接下来我会就其中一些关键点列举出来:
本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓
视频质量直接影响视频清晰度和文件大小,这个可以根据个人需求调整,码率不宜过小也不宜过大。
/**
* 获取适合的视频质量配置
* 影响视频清晰度和文件大小,根据自身需要调整
* @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录制视频的方法!有问题大家提出来讨论一下。
如果你对音视频开发感兴趣,觉得文章对您有帮助,别忘了点赞、收藏哦!或者对本文的一些阐述有自己的看法,有任何问题,欢迎在下方评论区讨论!
本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓