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

Android:使用MediaRecorder录制高清视频,TextureView预览

2018-03-04 18:25 856 查看

用户权限获取

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<uses-feature android:name="android.hardware.camera" android:required="true"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="true" />
<!--保证有硬件支持-->


使用TextureView预览Camera的像

在activity的onCreate方法中调用:

//调用摄像头
myTexture = (TextureView) findViewById(R.id.texture);
if (myTexture != null) {
myTexture.setSurfaceTextureListener(this);
}


设置继承自本身的监听器TextureView.SurfaceTextureListener,重载以下方法

@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
openCamera(Camera.CameraInfo.CAMERA_FACING_BACK,surface);
this.surface = surface;
}


下面提供一个打开摄像头并且设置全屏预览方法,也就是上面的openCamera()

/**
* 打开摄像头
* @param position 摄像头位置
*/
public void openCamera(int position,SurfaceTexture surface){
current_camera = position;
camera = Camera.open(position);//打开摄像头
parameters= camera.getParameters();//设置参数   parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);//设置自动对焦
try {
parameters.setPreviewSize(1920,1080);//设置预览尺寸,为了全屏展示,我们选择最大尺寸,同时TextureView也应该是match_parent全屏
camera.setParameters(parameters);//设置相机的参数
camera.setDisplayOrientation(90);//设置显示翻转,为0则是水平录像,90为竖屏
camera.setPreviewTexture(surface);//将onSurfaceTextureAvailable监听中的surface传入进来,设置预览的控件
} catch (IOException t) {
Log.d(TAG, "onSurfaceTextureAvailable: IO异常");
}
camera.startPreview();//开始预览
myTexture.setAlpha(1.0f);
}


MediaRecorder设置录制视频时的参数

/**
* 录制视频
*/
public void record(){
Log.d(TAG, "record: 开始录制");
mediaRecorder = new MediaRecorder();
camera.unlock();
mediaRecorder.setCamera(camera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
//        mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); //setProfile不能和后面的setOutputFormat等方法一起使用
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);  // 设置视频的输出格式 为MP4

mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); // 设置音频的编码格式
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); // 设置视频的编码格式
//        mediaRecorder.setVideoSize(176, 144);  // 设置视频大小
//        mediaRecorder.setVideoSize(320, 240);  // 设置视频大小
mediaRecorder.setVideoSize(1920, 1080);  // 设置视频大小
mediaRecorder.setVideoEncodingBitRate(5*1024*1024);
mediaRecorder.setVideoFrameRate(60); // 设置帧率

/*
* 设置视频文件的翻转角度
* 改变保存后的视频文件播放时是否横屏(不加这句,视频文件播放的时候角度是反的)
* */
if (current_camera == Camera.CameraInfo.CAMERA_FACING_FRONT){
mediaRecorder.setOrientationHint(270);
}else if (current_camera == Camera.CameraInfo.CAMERA_FACING_BACK){
mediaRecorder.setOrientationHint(90);
}

//        mRecorder.setMaxDuration(10000); //设置最大录像时间为10s
//        mediaRecorder.setPreviewDisplay();
//        mediaRecorder.setPreviewDisplay(myTexture);

//设置视频存储路径
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + File.separator + "yuewu");
if (!file.exists()) {
//多级文件夹的创建
file.mkdirs();
}

Log.d(TAG, "record: path " +file.getPath() + File.separator + "乐舞_" + System.currentTimeMillis() + ".mp4");
mediaRecorder.setOutputFile(file.getPath() + File.separator + "乐舞_" + System.currentTimeMillis() + ".mp4");

//开始录制
try {
mediaRecorder.prepare();
mediaRecorder.start();
} catch (IOException e) {
e.printStackTrace();
}
}


上面的代码有很多坑,首先setOutputFormat()方法必须在setAudioResource和setVideoResource之后,prepare()之前。源码给出的解释如下:

/**

* Sets the format of the output file produced during recording. Call this

* after setAudioSource()/setVideoSource() but b
bec6
efore prepare().

*

*
It is recommended to always use 3GP format when using the H.263

* video encoder and AMR audio encoder. Using an MPEG-4 container format

* may confuse some desktop players.

*

* @param output_format the output format to use. The output format

* needs to be specified before setting recording-parameters or encoders.

* @throws IllegalStateException if it is called after prepare() or before

* setAudioSource()/setVideoSource().

* @see android.media.MediaRecorder.OutputFormat

*/

如果使用了setOutputFormate()方法,就不应该使用setProfile方法了,本人亲测使用了setProfile方法之后,后面有关mediaRecorder对象的其他参数就不应该被设置,否则就会报illegalStateException,也就是说在这一个方法中就可以完成低质量和高质量的设置。

不过还是希望大家不要使用setProfile这个方法,这个方法不够灵活。我们可以自定义MediaRecorder的一些设置。高清视频的设置主要是以下几个方法:

mediaRecorder.setVideoSize(1920, 1080); // 设置视频大小

mediaRecorder.setVideoEncodingBitRate(5*1024*1024);

mediaRecorder.setVideoFrameRate(60); // 设置帧率

帧率越高,size越大(size是指录像时预览的size和保存的视频尺寸,我们和上面设置的预览size保持一致),bit流越大,视频质量就越高。如果需要低质量的视频就从这几个参数中修改就行了。

停止录制

停止录制的方法也很简单,方法如下:

/**
* 停止录制
*/
public void stop(){
//        mediaRecorder.setOnErrorListener(null);
//        mediaRecorder.setOnInfoListener(null);
camera.lock();

mediaRecorder.stop();
mediaRecorder.release();

openCamera(Camera.CameraInfo.CAMERA_FACING_BACK,surface);//启动预览,可以判断之前是前置摄像头还是后置摄像头来继续启动预览

Log.d(TAG, "stop: 录制完成");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: