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

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

当然,矫情的你也可以使用MediaCodec录制,这样就可以单独控制音频和视频了.
您可以移步至:http://blog.csdn.net/angcyo/article/details/51043367 查看相关资料;

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

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


这里写图片描述
如果您稍微有一点了解, 你应该很熟悉上图;

这就是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 欢迎您的加入.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值