您的位置:首页 > 移动开发 > Android开发

Android-->如何填MediaRecorder的坑(附TextureView的使用)

2016-05-20 23:29 676 查看
在Android系统中,录像官方使用的是MediaRecorder,这也是录像的正确姿势.因为系统已经帮你控制了很多复杂流程,复杂的转码操作,总之…

当然,矫情的你也可以使用MediaCodec录制,这样就可以单独控制音频和视频了.

您可以移步至:/article/7771662.html 查看相关资料;

竟然是官方的东西, 为什么文章标题还会是填坑呢?

不要着急,填坑历史即将上演:



如果您稍微有一点了解, 你应该很熟悉上图;

这就是MediaRecorder的官方控制流程, 看到图中密密麻麻的箭头指向, 头晕了吗?

这只是入坑的开始,如果你读不懂这张图,那么你还是不要下手的好;

因为只要有一步错误,整个流程就跑不起来.程序就会Crash…绝对不是危言耸听!

正确的使用流程:

1:首先在布局中创建一个用于预览摄像头的TextureView

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.angcyo.camera.MediaRecordActivity">

<TextureView
android:id="@+id/textureView"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</RelativeLayout>


2:打开并配置Camera(建议在子线程中操作,因为会阻塞线程)

private void openCamera() {
mCamera = Camera.open();
try {
mCamera.setPreviewTexture(mSurfaceTexture);//注意处,如果没有设置preview,录像会报错.坑1
} catch (IOException e) {
e.printStackTrace();
}
initCamera(mCamera);
}


private void initCamera(Camera camera) {
if (camera == null) {
return;
}
Parameters parameters = camera.getParameters();
//请通过parameters.getSupportedPreviewSizes();设置预览大小,否则设置了一个摄像头不支持大小,将会报错.
parameters.setPreviewSize(1920, 1080);//如果设置了一个不支持的大小,会崩溃.坑2

//请通过parameters.getSupportedPictureSizes();设置拍照图片大小,这一步对于录像来说是非必须的.
//parameters.setPictureSize(1920, 1080);
List<String> focusModes = parameters.getSupportedFocusModes();
if (focusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
//设置对焦模式
parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
camera.setParameters(parameters);
}


3:核心,开启录像.

–>录制声音和视频:

private void startRecorder() {
try {
mCamera.unlock();//注意处,一定要调用此方法,否则会崩溃. 坑3
} catch (Exception e) {
Log.e("angcyo", e.getMessage());
return;
}

if (mMediaRecorder == null) {
mMediaRecorder = new MediaRecorder();
}

mMediaRecorder.reset();//竟可能在调用其他方法之前,调用reset方法.避免状态异常调用.坑4
mMediaRecorder.setCamera(mCamera);//注意顺序,请注意此方法调用的顺序.调用顺序错了,会崩溃.坑5

CamcorderProfile camcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
//请注意, setVideoSource 和 setAudioSource 一定要比其他方法先调用.否则会崩溃. 坑6
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);

//为了避免手动设置参数导致的崩溃,建议使用系统配置的参数.^~^,后面会介绍单独配置参数.
mMediaRecorder.setProfile(camcorderProfile);
String filePath = getFilePath();
//setOutputFile方法总是放在最后面调用
mMediaRecorder.setOutputFile(filePath);
mMediaRecorder.setMaxDuration(MAX_DURATION);//设置最大录制时长,还可以设置最大录制文件大小.
mMediaRecorder.setOnInfoListener(this);//监听录制时长达到时的事件.
mMediaRecorder.setOnErrorListener(this);//设置录制错误的事件监听

//最后的2个步骤, 顺序调用不能有误哦. 否则崩溃...坑7.
mMediaRecorder.prepare();//start之前,一定要先调用prepare
mMediaRecorder.start();//如果一切OK的话,调用start方法是不会崩溃的.否则~~你只能看到崩溃信息...
}
//标注的7个坑,都是我亲自遇到过的.也许有更多,也许有更少.读者们注意就行了~~
//最难的就是调用顺序了,还有就是当前MediaRecorder处于什么状态,在这种状态下能执行什么操作.这一点要注意.否则执行了状态不允许的操作,就会崩溃.


–>只录制视频:

mMediaRecorder.reset();
mMediaRecorder.setCamera(mCamera);//注意顺序

CamcorderProfile camcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

mMediaRecorder.setOutputFormat(camcorderProfile.fileFormat);

/*一个都不能少,成群出现*/
mMediaRecorder.setVideoEncodingBitRate(camcorderProfile.videoBitRate);
mMediaRecorder.setVideoFrameRate(camcorderProfile.videoFrameRate);
mMediaRecorder.setVideoSize(1920, 1080);
mMediaRecorder.setVideoEncoder(camcorderProfile.videoCodec);

String filePath = getFilePath();
mMediaRecorder.setOutputFile(filePath);
mMediaRecorder.setMaxDuration(MAX_DURATION);
mMediaRecorder.setOnInfoListener(this);
mMediaRecorder.setOnErrorListener(this);
mMediaRecorder.prepare();
mMediaRecorder.start();


–>只录制声音(这个时候,可以不需要打开Camera):

mMediaRecorder.reset();
//mMediaRecorder.setCamera(mCamera);//此行可以不需要了.

CamcorderProfile camcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);

mMediaRecorder.setOutputFormat(camcorderProfile.fileFormat);

/*一个都不能少,成群出现*/
mMediaRecorder.setAudioChannels(camcorderProfile.audioChannels);
mMediaRecorder.setAudioSamplingRate(camcorderProfile.audioSampleRate);
mMediaRecorder.setAudioEncodingBitRate(camcorderProfile.audioBitRate);
mMediaRecorder.setAudioEncoder(camcorderProfile.audioCodec);

String filePath = getFilePath();
mMediaRecorder.setOutputFile(filePath);
mMediaRecorder.setMaxDuration(MAX_DURATION);
mMediaRecorder.setOnInfoListener(this);
mMediaRecorder.setOnErrorListener(this);
mMediaRecorder.prepare();
mMediaRecorder.start();


仔细观察,只录制视频和只录制音频的代码, 你会发现. 区别很简单;

友情提示:你可能需要以下权限.

<!-- 摄像头权限 -->
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>

<!-- 读写文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<!-- 录音录像权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.RECORD_VIDEO"/>

<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>


源代码:

https://github.com/angcyo/RJcenter/blob/6282caa3fcbd1a1e1f214b1bd53e5412700a0a12/sample/src/main/java/com/angcyo/camera/MediaRecordActivity.java

至此: 文章就结束了,如有疑问: QQ群:274306954 欢迎您的加入.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: