Android使用MediaRecorder类进行录制视频
毛票票提醒大家使用MediaRecorder录音录像的设置代码步骤一定要按照API指定的顺序来设置,否则报错
步骤为:
1、设置视频源,音频源,即输入源
2、设置输出格式
3、设置音视频的编码格式
一、首先看布局文件,这里有一个SurfaceView,这是一个绘制容器,可以直接从内存或者DMA等硬件接口取得图像数据,
<LinearLayoutxmlns: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" android:orientation="vertical" tools:context="com.xqx.mediarecorder.app.WorkRecorder"> <!--开始录制按钮--> <Button android:id="@+id/startRecord" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="btnStartRecord" android:text="开始录制" /> <Button android:id="@+id/stopRecord" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="btnStopRecord" android:text="停止录制" /> <SurfaceView android:id="@+id/surView" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
二、Activity代码
1、首先看下成员变量
//开始录制,停止录制按钮 privateButtonstartRecord,stopRecord; //显示预览的SurfaceView privateSurfaceViewsurfaceView; //标记,判断当前是否正在录制 booleanisRunning=false; //录制类 privateMediaRecorderrecorder; //存储文件 privateFilesaveFile;
2、onCreate()方法中进行一些初始化
startRecord=(Button)findViewById(R.id.startRecord);
stopRecord=(Button)findViewById(R.id.stopRecord);
surfaceView=(SurfaceView)findViewById(R.id.surView);
//onCreate()初始化,一开始肯定没有开始录制,所以停止按钮不可点击
stopRecord.setEnabled(false);
//设置Surface不需要维护自己的缓冲区
surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
//设置分辨率
surfaceView.getHolder().setFixedSize(320,280);
//设置该组件不会让屏幕自动关闭
surfaceView.getHolder().setKeepScreenOn(true);
3、现在看“开始录制”监听事件
----3.1
创建MediaRecorder对象 recorder=newMediaRecorder(); recorder.reset();
----3.2设置三步,顺序固定
//1.设置采集声音 recorder.setAudioSource(MediaRecorder.AudioSource.MIC); //设置采集图像 recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); //2.设置视频,音频的输出格式 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); //3.设置音频的编码格式 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); //设置图像的编码格式 recorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
----3.3其他可选设置,更多请查看API
//设置立体声 recorder.setAudioChannels(2); //设置最大录像时间单位:毫秒 recorder.setMaxDuration(600000); //设置最大录制的大小单位,字节 recorder.setMaxFileSize(1024*1024); //音频一秒钟包含多少数据位 recorder.setAudioEncodingBitRate(128); //设置选择角度,顺时针方向,因为默认是逆向90度的,这样图像就是正常显示了,这里设置的是观看保存后的视频的角度 recorder.setOrientationHint(90); //设置录像的分辨率 recorder.setVideoSize(176,144);
----3.4设置文件存储路径,这里简陋了,实际开发中需要判断是否有外部存储,是否有目标目录,是否已经存在相同名字的文件等问题
//设置输出文件路径
saveFile=newFile(Environment.getExternalStorageDirectory() .getCanonicalFile()+"/myvideo.mp4"); recorder.setOutputFile(saveFile.getAbsolutePath());
----3.5使用SurfaceView进行预览
recorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
----3.6开始录制
recorder.prepare(); //开始录制 recorder.start(); //让开始按钮不可点击,停止按钮可点击 startRecord.setEnabled(false); stopRecord.setEnabled(true); isRunning=true;
----3.7停止录制
//停止录制 recorder.stop(); //释放资源 recorder.release(); recorder=null; //设置开始按钮可点击,停止按钮不可点击 startRecord.setEnabled(true); stopRecord.setEnabled(false);
完整代码:
packagecom.xqx.mediarecorder.app; importandroid.app.Activity; importandroid.media.MediaRecorder; importandroid.os.Bundle; importandroid.os.Environment; importandroid.view.SurfaceHolder; importandroid.view.SurfaceView; importandroid.view.View; importandroid.widget.Button; importandroid.hardware.Camera; importjava.io.File; importjava.io.IOException; publicclassWorkRecorderextendsActivityimplementsCamera.PreviewCallback{ //开始录制,停止录制按钮 privateButtonstartRecord,stopRecord; //显示预览的SurfaceView privateSurfaceViewsurfaceView; //标记,判断当前是否正在录制 booleanisRunning=false; //录制类 privateMediaRecorderrecorder; //存储文件 privateFilesaveFile; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_work_recorder); startRecord=(Button)findViewById(R.id.startRecord); stopRecord=(Button)findViewById(R.id.stopRecord); surfaceView=(SurfaceView)findViewById(R.id.surView); //onCreate()初始化,一开始肯定没有开始录制,所以停止按钮不可点击 stopRecord.setEnabled(false); //设置Surface不需要维护自己的缓冲区 surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); //设置分辨率 surfaceView.getHolder().setFixedSize(,); //设置该组件不会让屏幕自动关闭 surfaceView.getHolder().setKeepScreenOn(true); } /** *开始录制 *@paramview */ publicvoidbtnStartRecord(Viewview){ //首先判断当前是否处理视频录制状态,只有不是录制状态的时候,才可以开始录制 if(!isRunning){ try{ //创建MediaRecorder对象 recorder=newMediaRecorder(); recorder.reset(); //.设置采集声音 recorder.setAudioSource(MediaRecorder.AudioSource.MIC); //设置采集图像 recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); //.设置视频,音频的输出格式 recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_); //.设置音频的编码格式 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); //设置图像的编码格式 recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H); //设置立体声 recorder.setAudioChannels(); //设置最大录像时间单位:毫秒 recorder.setMaxDuration(); //设置最大录制的大小单位,字节 recorder.setMaxFileSize(*); //音频一秒钟包含多少数据位 recorder.setAudioEncodingBitRate(); //设置选择角度,顺时针方向,因为默认是逆向度的,这样图像就是正常显示了,这里设置的是观看保存后的视频的角度 recorder.setOrientationHint(); //设置输出文件路径 //saveFile=FileUtils.getMediaRecoderFolder(this); saveFile=newFile(Environment.getExternalStorageDirectory() .getCanonicalFile()+"/myvideo.mp"); //recorder.setVideoSize(,); //recorder.setVideoFrameRate(); recorder.setOutputFile(saveFile.getAbsolutePath()); //使用SurfaceView预览 recorder.setPreviewDisplay(surfaceView.getHolder().getSurface()); recorder.prepare(); //开始录制 recorder.start(); //让开始按钮不可点击,停止按钮可点击 startRecord.setEnabled(false); stopRecord.setEnabled(true); isRunning=true; }catch(IOExceptione){ e.printStackTrace(); } } } /** *结束录制 *@paramview */ publicvoidbtnStopRecord(Viewview){ if(isRunning){ //停止录制 recorder.stop(); //释放资源 recorder.release(); recorder=null; //设置开始按钮可点击,停止按钮不可点击 startRecord.setEnabled(true); stopRecord.setEnabled(false); } } @Override publicvoidonPreviewFrame(byte[]data,Cameracamera){ } }
本例子只是一个简单的Demo,用于给刚接触MediaRecorder音频录制的coder学习,存在一些Bug和不足,各位coder可以继续拓展
不足:
1、只有当点击“开始录制”的时候SurfaceView组件才可以看到摄像头拍摄的预览,否则是一篇黑,这里可以看下Canera类,进行相应的调整
2、保存路径,需要判断是否有外部存储,存储空间是否足够,路径是否不存在,是否有已有的文件名相同的文件存在等问题,设置文件的名字,我这里是固定路径固定文件名
3、摄像预览效果是有90度旋转的,这里需要大家个人去看下MedioRecoder的API去进行设置
4、没有设置对焦,像素不清楚,摄像宽高变形