最近一段时间都在做一些录像相关的事情,通过直接找到一些大神的博客,学习怎么使用MediaRecord,总算完成,如果只是这样就不写这篇文章了,关键在我们的技术支持是一个追求完美的人,他提出了三个问题:
1、录像出来的文件清晰度不够;
2、录像文件和系统对比,亮度不够;
3、帧数达不到要求;
总之就是和系统录像有差距,录制的视频文件要和系统录制出来的一样,头大,针对个问题,又是一番百度:
1、针对清晰度问题,直接采用系统配置的参数
private @Nullable CamcorderProfile getBestCamcorderProfile() { int quality = CamcorderProfile.QUALITY_HIGH; if (videoType == 1 && CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P)) { quality = CamcorderProfile.QUALITY_1080P; } else if (videoType == 2 && CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)) { quality = CamcorderProfile.QUALITY_720P; } else if (videoType == 3 && CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P)) { quality = CamcorderProfile.QUALITY_480P; } else { quality = CamcorderProfile.QUALITY_CIF; } return CamcorderProfile.get(quality); }
这样录制的视频清晰度绝对是系统级别的,如果不需要,可以自由调整比特率和分辨率来满足需求;
2、针对亮度不够的问题:
这里走了不少弯路,首先想到的是黑白平衡、亮度、饱和度、曝光级别,设置了都没用,至少在我测试的定制机上是没有效果的;后面又想到了自动聚焦和区域聚焦,结果把自己调到一个更大的坑,一把辛酸泪不多说;最后实在没办法,翻阅系统MediaRecord相关demo,想从这个里面找到原因,看了两天,txt上看真的头疼,好不容易看完,修改录像代码,测试发现没效果;最后只能去阅读camera 源码,在源码里面总算找到一个方法:
没错 就是这个方法,设置之后效果和系统录像一致,达到了要求;
3、第三个问题相比起来简直不是问题,camera直接提供了相应的方法:
查阅了不少大神博客,发现很少有用这个方法的,为了达到要求,设置了这个方法,和系统录像达到一样的帧率,不过要注意的是,最大最小帧率都是30帧,录像文件只有29.xx帧,会有一点损失。
三个问题总算解决,成功保住了饭碗,下面贴出代码:
public class MediaRecorderActivity extends BaseActivity implements SurfaceHolder.Callback, MediaRecorder.OnErrorListener , MediaRecorder.OnInfoListener { // ---------------------------- 常量------------------------------- // -------------------------- 全局变量------------------------------ private MediaRecorder mediarecorder;// 录制视频的类 private SizeSurfaceView surfaceview;// 显示视频的控件 // 用来显示视频的一个接口,我靠不用还不行,也就是说用mediarecorder录制视频还得给个界面看 private SurfaceHolder surfaceHolder; private int WIDTH_DEF = 1920; private int HEIGHT_DEF = 1080; private static final int ONE_MINUTE_TIME = 60 * 1000; private static final int ONE_HOUR_TIME = 60 * ONE_MINUTE_TIME; private String outString; private String parentString; private static Timer timer; private Camera mCamera; private int videoType = 3; //1 : 1080P 2 : 720 P 3 : 480 4: 流畅 //控制闪光灯 手电筒的 public static final int FLASH_MODE_OFF = 0; public static final int FLASH_MODE_ON = 1; public static int flashType = FLASH_MODE_OFF; private boolean isNotify = false; private long mMediaRecorderStartTImes = 0; //记录本地视频信息 private VideoData videoData = new VideoData(); private long fragmentVideoDataStartTimes; private ArrayList<FragmentVideoData> fragmentVideoDatas = new ArrayList<>(); public static void launch(Context context) { Intent i = new Intent(context, MediaRecorderActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** * 如果录像按钮不处于按下状态,结束录制本地视频 * 防止出现本地视频自己会开启的情况 */ if (!HandlerManager.isPress) { finish(); return; } setContentView(R.layout.activity_mediarecord); initView(); initData(); } @Override public void surfaceCreated(SurfaceHolder holder) { // 将holder,这个holder为开始在oncreat里面取得的holder,将它赋给surfaceHolder surfaceHolder = holder; initCamera(); start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // 将holder,这个holder为开始在oncreat里面取得的holder,将它赋给surfaceHolder surfaceHolder = holder; } @Override public void surfaceDestroyed(SurfaceHolder holder) { releaseCamera(); surfaceview = null; surfaceHolder = null; } @Override public void onDestroy() { super.onDestroy(); stopMediarecorder(); releaseCamera(); stopTimer(); LightPoingManager.getInstance().cancel(); getDuration(); VideoManager.getInstance().setIsPress(true); } @Override public void onError(MediaRecorder mr, int what, int extra) { TtsManager.getInstance().say("录制出错,已经结束本次录制"); releaseCamera(); finish(); } @Override public void onInfo(MediaRecorder mr, int what, int extra) { if (what == MediaRecorder.M