Android使用MediaRecorder类进行录制视频
提醒大家使用mediarecorder录音录像的设置代码步骤一定要按照api指定的顺序来设置,否则报错
步骤为:
1、设置视频源,音频源,即输入源
2、设置输出格式
3、设置音视频的编码格式
一、首先看布局文件,这里有一个surfaceview,这是一个绘制容器,可以直接从内存或者dma等硬件接口取得图像数据,
<linearlayout 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" 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、首先看下成员变量
// 开始录制,停止录制按钮 private button startrecord,stoprecord; // 显示预览的surfaceview private surfaceview surfaceview; // 标记,判断当前是否正在录制 boolean isrunning = false; // 录制类 private mediarecorder recorder; // 存储文件 private file savefile;
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 = new mediarecorder(); 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 = new file(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);
完整代码:
package com.xqx.mediarecorder.app; import android.app.activity; import android.media.mediarecorder; import android.os.bundle; import android.os.environment; import android.view.surfaceholder; import android.view.surfaceview; import android.view.view; import android.widget.button; import android.hardware.camera; import java.io.file; import java.io.ioexception; public class workrecorder extends activity implements camera.previewcallback { // 开始录制,停止录制按钮 private button startrecord,stoprecord; // 显示预览的surfaceview private surfaceview surfaceview; // 标记,判断当前是否正在录制 boolean isrunning = false; // 录制类 private mediarecorder recorder; // 存储文件 private file savefile; @override protected void oncreate(bundle savedinstancestate) { 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); } /** * 开始录制 * @param view */ public void btnstartrecord(view view) { // 首先判断当前是否处理视频录制状态,只有不是录制状态的时候,才可以开始录制 if (!isrunning){ try { //创建mediarecorder对象 recorder = new mediarecorder(); 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 = new file(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 (ioexception e) { e.printstacktrace(); } } } /** * 结束录制 * @param view */ public void btnstoprecord(view view) { if (isrunning){ //停止录制 recorder.stop(); //释放资源 recorder.release(); recorder = null; //设置开始按钮可点击,停止按钮不可点击 startrecord.setenabled(true); stoprecord.setenabled(false); } } @override public void onpreviewframe(byte[] data, camera camera) { } }
本例子只是一个简单的demo,用于给刚接触mediarecorder音频录制的coder学习,存在一些bug和不足,各位coder可以继续拓展
不足:
1、只有当点击“开始录制”的时候surfaceview组件才可以看到摄像头拍摄的预览,否则是一篇黑,这里可以看下canera类,进行相应的调整
2、保存路径,需要判断是否有外部存储,存储空间是否足够,路径是否不存在,是否有已有的文件名相同的文件存在等问题,设置文件的名字,我这里是固定路径固定文件名
3、摄像预览效果是有90度旋转的,这里需要大家个人去看下mediorecoder的api 去进行设置
4、没有设置对焦,像素不清楚,摄像宽高变形