Android音视频开发:MediaRecorder录制视频
Posted 音视频开发老舅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android音视频开发:MediaRecorder录制视频相关的知识,希望对你有一定的参考价值。
简介
安卓api提供了Camera类控制相机捕获图像,在api21以后,安卓也提供了Camera2,Camera变得过时了,但为了兼容性,这里还是使用Camera。
对于录制视频,可以使用MediaRecorder,这个可看安卓官方api文档
使用
使用Camera进行拍照摄像前,你得先申请权限:
<!-- 相机权限 -->
<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)获取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)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓
Android:将音频转换为浮点数[]
【中文标题】Android:将音频转换为浮点数[]【英文标题】:Android: Convert Audio into float[] 【发布时间】:2012-11-07 16:18:06 【问题描述】:我正在 Android 中开发一个应用程序,它必须记录声音并在屏幕上显示一些代表声音频率或强度的值。
为了记录,我使用这段代码:
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOutputFile(name);
mRecorder.prepare();
mRecorder.start();
然后我最初尝试将存储的文件转换为这样的字节:
DataInputStream dis1 = new DataInputStream ( new FileInputStream (name));
byte[] datainBytes1 = new byte[dis1.available()];
dis1.readFully(datainBytes1);
dis1.close();
但我想将该字节值转换为短或浮点数以使用绘图方法显示它们:
canvas.drawLine(xini,yini,xfinal,yfinal,paint)
您能否推荐我另一种将音频文件转换为我可以绘制的短值的方法?
非常感谢您的帮助!!
【问题讨论】:
【参考方案1】:我认为您尝试显示录制声音的方式不正确。作为起点,您需要学习音频编码格式并查看以下 android 类:http://developer.android.com/reference/android/media/AudioTrack.html
【讨论】:
【参考方案2】:Here 您会发现一个库类,用于在考虑有符号/无符号、大/小端和样本大小的情况下在浮点数和字节之间进行转换。
https://java.net/projects/gervill/sources/Mercurial/content/src/com/sun/media/sound/AudioFloatConverter.java
【讨论】:
以上是关于Android音视频开发:MediaRecorder录制视频的主要内容,如果未能解决你的问题,请参考以下文章