aac mediarecorder录制_Android音视频录制之MediaRecorder+camera

前言

本篇介绍使用Android 中视频录制,录制工具是:

MediaRecorder : 视频编码封装

camera : 视频画面原始数据采集

TextureView : 提供预览画面

MediaRecorder基本api介绍

MediaRecorder是android中面向应用层的封装,用于提供便捷的音视频编码封装操作,在使用的过程中要严格按照官方指定的生命周期调用顺序,即下图所示的使用步骤

460265be4e19?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image.png

从图中可以看出,MediaRecorder的生命周期有以下几个阶段,并且必须按顺序执行

initial : 在MediaRecorder被创建(刚new 出来)或者滴啊用reset()方法后,会处于该状态

initialized : 当调用setAudioSource()或者setVideoSource()后,处于该状态。这两个方法主要用于设置音视频的源配置,通常音频是麦克风,视频是摄像头。该状态可以通过调用reset()方法回到initial状态

DataSourceConfigured : 当调用setOutputFormat()方法后,会处于该状态。该方法主要用于设置输出的文件格式,可以是音视频如MP4,也可以是单独的音频如mp3。当处于该状态之后,可以进一步设置音频和视频的配置参数,例如音频封装格式,采样率,视频码率,帧率等等该状态可以通过调用reset()方法回到initial状态

Prepared : 在上面几个步骤都配置好之后,可以通过调用prepare()方法进入该状态,只有处于该状态,才能调用start()

Recording : 通过调用start()方法进入该状态,该状态就是真正开始进行视频录制编码的阶段,通过调用stop()或者reset()可以回到initial状态

error状态 : 当录制过程中发生次错误时,会进入该状态,调用reset()方法回到initial状态。

release : 只有在initial状态才可以通过调用release()方法进入该状态,释放所占用的系统资源

编码的步骤

在开始编码之前,应该先规划一下编码的步骤,因为录制视频需要预览画面,所以我们肯定需要构建一个预览的界面,通过camera+TextureView可以实现,音频不需要预览。构建好预览画面之后,就是开始配置MediaRecorder开始录制了。

配置Camera

demo只演示后置摄像头的捕捉,因为使用MediaRecorder进行录制无法处理帧数据,在切换前置摄像头之后,视频会出现左右翻转的问题,无法通过单纯的旋转解决,暂时还没找到方法。

camera的配置重点

预览尺寸,预览尺寸的宽高比应该尽量和TextureView的宽高比一致,这样可以保证画面不变形;

对焦模式,对焦模式一般首选FOCUS_MODE_CONTINUOUS_VIDEO,如果机型不包含,则选择FOCUS_MODE_CONTINUOUS_PICTURE,如果还不包含,则选择FOCUS_MODE_AUTO,然后通过手指点击重新对焦(手指点击TextureView,调用mCamera.autoFocus(null););

预览界面旋转,由于传感器方向和手机自然方向不一致,所以需要调整预览界面进行一定的旋转,旋转的角度大小可以通过google官方提供的方法计算,查看mCamera.setDisplayOrientation(mRotationDegree);方法源码查看注释里有这段代码(shift/command+鼠标左键点击方法)

示例代码

/**

* 初始化相机

*/

private void initCamera() {

if (mSurfaceTexture == null) return;

if (mCamera != null) {

releaseCamera();

}

mCamera = Camera.open(mCameraId);

if (mCamera == null) {

Toast.makeText(this, "没有可用相机", Toast.LENGTH_SHORT).show();

return;

}

try {

mCamera.setPreviewTexture(mSurfaceTexture);

mRotationDegree = CameraUtil.getCameraDisplayOrientation(this, mCameraId);

mCamera.setDisplayOrientation(mRotationDegree);

setCameraParameter(mCamera);

mCamera.startPreview();

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 设置相机的参数

*

* @param camera

*/

private void setCameraParameter(Camera camera) {

if (camera == null) return;

Camera.Parameters parameters = camera.getParameters();

//获取相机支持的>=20fps的帧率,用于设置给MediaRecorder

//因为获取的数值是*1000的,所以要除以1000

List previewFpsRange = parameters.getSupportedPreviewFpsRange();

for (int[] ints : previewFpsRange) {

if (ints[0] >= 20000) {

mFps = ints[0] / 1000;

break;

}

}

//设置聚焦模式

List focusModes = parameters.getSupportedFocusModes();

if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {

parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);

} else if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {

parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);

} else {

parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

}

//设置预览尺寸,因为预览的尺寸和最终是录制视频的尺寸无关,所以我们选取最大的数值

//通常最大的是手机的分辨率,这样可以让预览画面尽可能清晰并且尺寸不变形,前提是TextureView的尺寸是全屏或者接近全屏

List supportedPreviewSizes = parameters.getSupportedPreviewSizes();

parameters.setPreviewSize(supportedPreviewSizes.get(0).width, supportedPreviewSizes.get(0).height);

//缩短Recording启动时间

parameters.setRecordingHint(true);

//是否支持影像稳定能力,支持则开启

if (parameters.isVideoStabilizationSupported())

parameters.setVideoStabilization(true);

camera.setParameters(parameters);

}

配置MediaRecorder

按照生命周期进行每一步的配置,重点关注

编码参数,配置MediaRecorder的编码参数有两种方式;

通过系统提供的CamcorderProfile类,搭配mMediaRecorder.setProfile(profile);方法进行设置,CamcorderProfile对象包含了输出封装格式,视频编码格式,帧率,码率,分辨率,音频采样率,声道数,码率等参数。

示例代码

/**

* 通过系统的CamcorderProfile设置MediaRecorder的录制参数

* 首先查看系统是否包含对应质量的封装参数,然后再设置,根据具体需要的视频质量进行判断和设置

*/

private void setProfile() {

CamcorderProfile profile = null;

if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P)) {

profile = CamcorderProfile.get(CamcorderProfile.QUALITY_1080P);

} else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)) {

profile = CamcorderProfile.get(CamcorderProfile.QUALITY_720P);

} else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P)) {

profile = CamcorderProfile.get(CamcorderProfile.QUALITY_480P);

}

if (profile != null) {

mMediaRecorder.setProfile(profile);

}

}

自定义参数,通过profile可以一步到位配置各个参数,但是缺点是没办法设置自己想要的视频清晰度,因为视频清晰度是根据码率和分辨率决定的,而每个profile已经固定了码率和分辨率,所以无法进行调整。这种情况我们就可以自己配置参数。

需要注意

帧率不可以随便定义,如果系统不支持就会报错。应该先通过camera获取支持的帧率,然后再设置。

视频尺寸的大小,可以根据需要的质量,比如需要高清720的尺寸,那么先获取系统720p的profile,然后取profile.videoFrameWidth; profile.videoFrameHeight作为输出宽高。我这里为了方便直接写了1280:720,大部分手机都尺寸这个参数。

示例代码

/**

* 自定义MediaRecorder的录制参数

*/

private void setConfig() {

//设置封装格式 默认是MP4

mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);

//音频编码

mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

//图像编码

mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

//声道

mMediaRecorder.setAudioChannels(1);

//设置最大录像时间 单位:毫秒

mMediaRecorder.setMaxDuration(60 * 1000);

//设置最大录制的大小60M 单位,字节

mMediaRecorder.setMaxFileSize(60 * 1024 * 1024);

//再用44.1Hz采样率

mMediaRecorder.setAudioEncodingBitRate(22050);

//设置帧率,该帧率必须是硬件支持的,可以通过Camera.CameraParameter.getSupportedPreviewFpsRange()方法获取相机支持的帧率

mMediaRecorder.setVideoFrameRate(mFps);

//设置码率

mMediaRecorder.setVideoEncodingBitRate(500 * 1024 * 8);

//设置视频尺寸,通常搭配码率一起使用,可调整视频清晰度

mMediaRecorder.setVideoSize(1280, 720);

}

录制的控制

控制流代码如下 chronometer是用于计时的

/**

* 开始录制和停止录制

*

* @param v

*/

public void control(View v) {

if (mStatus == RecorderStatus.RECORDING) {

stopRecord();

} else {

startRecord();

}

}

/**

* 开始录制

*/

private void startRecord() {

initCamera();

mCamera.unlock();

initMediaRecorder();

try {

mMediaRecorder.prepare();

mMediaRecorder.start();

} catch (IOException e) {

e.printStackTrace();

}

chronometer.setBase(SystemClock.elapsedRealtime());

chronometer.start();

mStatus = RecorderStatus.RECORDING;

}

/**

* 停止录制

*/

private void stopRecord() {

releaseMediaRecorder();

releaseCamera();

}

视频录制好之后可以在手机目录aaamedia文件夹下找到,以aaa开头方便查找!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值