• Android音视频开发:MediaRecorder录制视频


    简介

    安卓api提供了Camera类控制相机捕获图像,在api21以后,安卓也提供了Camera2,Camera变得过时了,但为了兼容性,这里还是使用Camera。

    对于录制视频,可以使用MediaRecorder,这个可看安卓官方api文档

    使用

    使用Camera进行拍照摄像前,你得先申请权限:

    1. <uses-permission android:name="android.permission.CAMERA" />
    2. <uses-permission android:name="android.permission.RECORD_AUDIO" />
    3. <uses-feature android:name="android.hardware.camera"/>
    4. <uses-feature android:name="android.hardware.camera.autofocus"/>

    接着,是相机预览流程:

    1. Camera.open(int)获取Camera实例

    2. setParameters设置相机参数

    3. setDisplayOrientation设置正确预览方向

    4. 关联SurfaceView,用于展示预览画面

    5. startPreview开始预览,stopPreview停止预览

    6. release释放相机资源

    录像流程:

    1. 创建MediaRecorder对象,用于录制音频视频

    2. 关联MediaRecorder和Camera,捕获从Camera传来的画面

    3. 设置MediaRecorder相关参数,视频格式、编码、大小等等

    4. setOrientationHint可设置视频最终旋转角度

    5. start开始录制,stop停止录制

    6. release释放资源

    为了防止篇幅过长,我这里就不展示全部代码了,详细代码请可以留言

    接下来我会就其中一些关键点列举出来:

    本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

    视频质量

    视频质量直接影响视频清晰度和文件大小,这个可以根据个人需求调整,码率不宜过小也不宜过大。

    1. /**
    2. * 获取适合的视频质量配置
    3. * 影响视频清晰度和文件大小,根据自身需要调整
    4. * @param cameraID 摄像头ID
    5. */
    6. fun getBestCamcorderProfile(cameraID: Int): CamcorderProfile? {
    7. var profile: CamcorderProfile? = null
    8. when {
    9. CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_1080P) -> { //1080P,优先
    10. profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_1080P)
    11. }
    12. CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_720P) -> { //720P
    13. profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_720P)
    14. }
    15. CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_480P) -> { //480P
    16. profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_480P)
    17. }
    18. CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_HIGH) -> {//高品质
    19. profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_HIGH)
    20. profile.videoBitRate /= 8
    21. return profile
    22. }
    23. CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_CIF) -> {
    24. profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_CIF)
    25. return profile
    26. }
    27. CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_QVGA) -> {
    28. profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_QVGA)
    29. }
    30. CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_LOW) -> {
    31. profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_LOW)
    32. }
    33. }
    34. if (profile != null) {
    35. //视频码率
    36. profile.videoBitRate = 6000000
    37. }
    38. return profile
    39. }

    视频预览角度 

    1. /**
    2. * 根据屏幕方向获取对应预览角度
    3. * setDisplayOrientation只能改变预览的角度,与视频最终结果角度无关
    4. * @param cameraID 相机ID
    5. */
    6. fun getCameraPreviewOrientation(cameraID: Int, activity: Activity): Int {
    7. val info = Camera.CameraInfo();
    8. Camera.getCameraInfo(cameraID, info);
    9. //屏幕选择角度
    10. val rotation = activity.windowManager.defaultDisplay.rotation
    11. var degrees = 0
    12. when (rotation) {
    13. Surface.ROTATION_0 ->
    14. degrees = 0
    15. Surface.ROTATION_90 ->
    16. degrees = 90
    17. Surface.ROTATION_180 ->
    18. degrees = 180
    19. Surface.ROTATION_270 ->
    20. degrees = 270
    21. }
    22. var result = 90
    23. if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
    24. result = (info.orientation + degrees) % 360
    25. result = (360 - result) % 360
    26. } else {
    27. result = (info.orientation - degrees + 360) % 360
    28. }
    29. return result;
    30. }

    相机预览 

    1. /**
    2. * 初始化相机设置并开启预览
    3. */
    4. private fun startPreview() {
    5. try {
    6. //开启后置摄像头
    7. camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK)
    8. //设置预览角度
    9. val rotation = CameraUtil.getCameraPreviewOrientation(Camera.CameraInfo.CAMERA_FACING_BACK,this)
    10. camera?.setDisplayOrientation(rotation)
    11. // 在SurfaceView上预览
    12. camera?.setPreviewDisplay(sv_camera.holder)
    13. val parameters = camera?.getParameters()
    14. //获取支持的预览大小,注意这里获取的宽高是根据横屏的
    15. val sizes = parameters?.supportedPreviewSizes
    16. //宽高建议根据横竖屏切换
    17. val previewSize =
    18. CameraUtil.findFitPreviewSize(sv_camera.height,sv_camera.width,sizes)
    19. if (previewSize != null) {
    20. //设置预览大小
    21. parameters?.setPreviewSize(previewSize.width, previewSize.height)
    22. }
    23. //设置自动对焦模式
    24. CameraUtil.setAutoFocusMode(parameters)
    25. camera?.setParameters(parameters)
    26. //开始预览
    27. camera?.startPreview()
    28. } catch (e: Exception) {
    29. Log.e("Test", "出错了", e)
    30. }
    31. }

    视频录制 

    1. /**
    2. * 开始录制
    3. * 注意方法调用的先后顺序
    4. */
    5. private fun startRecorder() {
    6. if (camera == null) {
    7. return
    8. }
    9. if (recorder != null) {
    10. stopRecord()
    11. }
    12. try {
    13. val videoSize = CameraUtil.findFitVideoSize(camera!!.parameters,
    14. sv_camera.height / sv_camera.width.toFloat()
    15. )
    16. //先停止camera预览,释放camera
    17. camera?.stopPreview()
    18. camera?.unlock()
    19. //创建MediaRecorder对象
    20. recorder = MediaRecorder()
    21. //关联camera
    22. recorder?.setCamera(camera)
    23. //设置视频角度;
    24. val rotation =
    25. CameraUtil.getCameraPreviewOrientation(Camera.CameraInfo.CAMERA_FACING_BACK, this)
    26. recorder?.setOrientationHint(rotation)
    27. //设置预览区域
    28. recorder?.setPreviewDisplay(sv_camera.holder.surface)
    29. //设置音频来源
    30. recorder?.setAudioSource(MediaRecorder.AudioSource.MIC)
    31. //设置视频来源,来自摄像头
    32. recorder?.setVideoSource(MediaRecorder.VideoSource.CAMERA)
    33. //设置输出格式
    34. // recorder?.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
    35. val profile = CameraUtil.getBestCamcorderProfile(Camera.CameraInfo.CAMERA_FACING_BACK)
    36. if (profile != null) {
    37. //设置视频码率
    38. recorder?.setProfile(profile)
    39. }
    40. //设置视频帧率,注意设备支持
    41. recorder?.setVideoFrameRate(30)
    42. //设置视频宽高
    43. recorder?.setVideoSize(videoSize.width, videoSize.height)
    44. val file =
    45. File(getExternalFilesDir(Environment.DIRECTORY_MOVIES)?.absolutePath, "test.mp4")
    46. //设置音频文件的存储位置 {
    47. recorder?.setOutputFile(file.absolutePath)
    48. //准备
    49. recorder?.prepare()
    50. //开始录制
    51. recorder?.start()
    52. ct_time.start()
    53. } catch (e: Exception) {
    54. Log.e("Test", e.message, e)
    55. }
    56. }

    以上就是Camera+MediaRecord录制视频的方法!有问题大家提出来讨论一下。

     如果你对音视频开发感兴趣,觉得文章对您有帮助,别忘了点赞、收藏哦!或者对本文的一些阐述有自己的看法,有任何问题,欢迎在下方评论区讨论!

    本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

  • 相关阅读:
    光鉴科技:以3D视觉变革重新定义驾乘体验
    java基础面试
    ubuntu20.04安装cmake
    让代码变美的第二天 - 策略模式
    Typecho博客搭建+cpolar内网穿透实现公网访问内网站点
    图数据库Neo4J 中文分词查询及全文检索(建立全文索引)
    Tranalyzer2安装及简单使用教程
    web前端框架设计第七课-事件处理
    Android12版本闹钟服务崩溃问题
    【Flink】flink简介
  • 原文地址:https://blog.csdn.net/m0_60259116/article/details/127429654