自定义录像功能具体步骤大致为:

  1. 获取摄像头的ID(现在大部分相机都是前后两个摄像头,你需要根据需求打开前置摄像头或者后置摄像头),并且使用Camera对象将其打开。
  2. 获取一个SurfaceView对象,用于显示预览的图像。
  3. 当开始录制视频时(例如用户点击某个按钮),创建一个MediaRecorder对象
  4. 对MediaRecorder对象进行配置
  5. 录制视频

获取摄像头ID并打开摄像头

每个摄像头都有ID,分别代表为前置摄像头和后置摄像头,用户可以根据具体的业务需求开启相应的摄像头。
Android API文档中说,开启摄像头,是在UI线程中,并且需要一段时间。
如果你想在onCreate中开启,对好开辟一个线程去处理
或者将摄像头的开启放在onResume中

Getting an instance of the Camera object is the first step in the process of directly controlling the camera. As Android’s own Camera application does, the recommended way to access the camera is to open Camera on a separate thread that’s launched from onCreate(). This approach is a good idea since it can take a while and might bog down the UI thread. In a more basic implementation, opening the camera can be deferred to the onResume() method to facilitate code reuse and keep the flow of control simple.

获取前置摄像头(因为博主的项目只针对于前置摄像头开发):

private int FindFrontCamera(){int cameraCount = 0;Camera.CameraInfo cameraInfo = new Camera.CameraInfo();cameraCount = Camera.getNumberOfCameras(); for (int camIdx = 0; camIdx < cameraCount;camIdx++) {Camera.getCameraInfo(camIdx, cameraInfo); if ( cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {return camIdx;}}return -1;}

Camera.getNumberOfCameras()可访问的摄像机设备总数,如果没有摄像头,则为0。
Camera.CameraInfo是摄像头的信息,常量里面为CAMERA_FACING_BACKCAMERA_FACING_FRONT后置摄像头和前置摄像头。
打开摄像头

     mId = FindFrontCamera();try {mCamera = Camera.open(mId);} catch (Exception e) {Toast.makeText(MainActivity.this, "摄像头正在使用", Toast.LENGTH_LONG).show();return;}

开启摄像头的时候应该进行异常检查

Caution: Always check for exceptions when using Camera.open(). Failing to check for exceptions if the camera is in use or does not exist will cause your application to be shut down by the system.
小心:使用Camera.open()时总是检查异常。如果相机正在使用或不存在,则无法检查异常会导致您的应用程序被系统关闭。

预览图像

当录制视频的时候,用户肯定需要看到自己的图像信息,这时候应该使用SurfaceView对相机捕获的信息进行预览

 public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {private SurfaceHolder mHolder;private Camera mCamera;private int mId;public CameraPreview(Context context, Camera camera, int id) {super(context);mCamera = camera;mId = id;// Install a SurfaceHolder.Callback so we get notified when the// underlying surface is created and destroyed.mHolder = getHolder();mHolder.addCallback(this);// deprecated setting, but required on Android versions prior to 3.0mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);}public void surfaceCreated(SurfaceHolder holder) {// The Surface has been created, now tell the mCamera where to draw the preview.try {mCamera.setPreviewDisplay(holder);mCamera.startPreview();startFaceDetection();} catch (IOException e) {Log.d(TAG, "Error setting mCamera preview: " + e.getMessage());}}public void surfaceDestroyed(SurfaceHolder holder) {// empty. Take care of releasing the Camera preview in your activity.// Surface will be destroyed when we return, so stop the preview.if (mCamera != null) {// Call stopPreview() to stop updating the preview surface.mCamera.stopPreview();}}public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {// If your preview can change or rotate, take care of those events here.// Make sure to stop the preview before resizing or reformatting it.if (mHolder.getSurface() == null){// preview surface does not existreturn;}// stop preview before making changestry {mCamera.stopPreview();} catch (Exception e){// ignore: tried to stop a non-existent preview}// set preview size and make any resize, rotate or reformatting changes here//从Android 2.2(API Level 8)开始,您可以使用setDisplayOrientation()方法来//设置预览图像的旋转。 为了在用户重定向手机时更改预览方向,//请在surfaceChanged()方法内,先用Camera.stopPreview()停止预览,//然后更改方向,然后再次使用Camera.startPreview()。setCameraDisplayOrientation(MainActivity.this, mId, mCamera);List<Camera.Size> supportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();Camera.Size bestSize = supportedPreviewSizes.get(0);for(int i = 1; i < supportedPreviewSizes.size(); i++){if((supportedPreviewSizes.get(i).width * supportedPreviewSizes.get(i).height) >(bestSize.width * bestSize.height)){bestSize = supportedPreviewSizes.get(i);}}Camera.Parameters parameters = mCamera.getParameters();//注意!!!!!!!!!!!!!!!!!!!!!!//!!!!!!!!!!!!!!!!!!!!!!!!//当设置预览大小的时候,不要自己随意去写值,应该选择在getSupportedPreviewSizes中提供的值parameters.setPreviewSize(bestSize.width, bestSize.height);mCamera.setParameters(parameters);// start preview with new settingstry {mCamera.setPreviewDisplay(mHolder);mCamera.startPreview();} catch (Exception e){Log.d(TAG, "Error starting mCamera preview: " + e.getMessage());}}public void setCameraDisplayOrientation(AppCompatActivity activity,int cameraId, android.hardware.Camera camera) {android.hardware.Camera.CameraInfo info =new android.hardware.Camera.CameraInfo();android.hardware.Camera.getCameraInfo(cameraId, info);int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();int degrees = 0;switch (rotation) {case Surface.ROTATION_0: degrees = 0; break;case Surface.ROTATION_90: degrees = 90; break;case Surface.ROTATION_180: degrees = 180; break;case Surface.ROTATION_270: degrees = 270; break;}int result;if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {result = (info.orientation + degrees) % 360;result = (360 - result) % 360;  // compensate the mirror} else {  // back-facingresult = (info.orientation - degrees + 360) % 360;}camera.setDisplayOrientation(result);}}

创建MediaRecorder对象并对其进行配置

private boolean prepareVideoRecorder(Camera mCamera){mMediaRecorder = new MediaRecorder();// Step 1: Unlock and set camera to MediaRecordermCamera.unlock();mMediaRecorder.setCamera(mCamera);// Step 2: Set sourcesmMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)// 注意这里,最好和预览设置的尺寸保持一直,否则录制时的视频会出现放大或缩小的情况mMediaRecorder.setProfile(CamcorderProfile.get(mId, CamcorderProfile.QUALITY_1080P));// Step 4: Set output filemPath = getOutputMediaFile(MEDIA_TYPE_VIDEO).toString();System.out.println("path = " + mPath);mMediaRecorder.setOutputFile(mPath);// Step 5: Set the preview outputSurface surface = mPreview.getHolder().getSurface();mMediaRecorder.setPreviewDisplay(surface);// Step 6: Prepare configured MediaRecordertry {mMediaRecorder.prepare();} catch (IllegalStateException e) {Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());releaseMediaRecorder();return false;} catch (IOException e) {Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());releaseMediaRecorder();return false;}return true;}

录制视频

录制视频结束后应该调用mCamera.lock()方法

注意
大部分相机功能都处在Camera.Parameters里面,可以通过mCamera.getParameters();方法去获得
如图

不同的设备使用相机的时候,有的功能可以使用,有的功能不能使用(博主的设备不支持自动对焦)。所以要在一些功能使用前,判断是否支持这个功能)。

// get Camera parameters
Camera.Parameters params = mCamera.getParameters();List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {// Autofocus mode is supportedparameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);mCamera.setParameters(parameters);mCamera.autoFocus(null);
}

大体就是这个流程
具体代码,我实在是没有C币了,我也很无奈

微信公众号

欢迎赞赏


QQ群:365473065

Android自定义录像功能相关推荐

  1. Android自定义View(七)_Canvas之图片文字

    在上一篇文章Canvas之画布操作中我们了解了画布的一些基本操作方法,本次了解一些绘制图片文字相关的内容.如果你对前几篇文章讲述的内容熟练掌握的话,那么恭喜你,本篇结束之后,大部分的自定义View已经 ...

  2. Android自定义ViewGroup基本步骤

    1.自定义属性,获取自定义属性,可参考 ​ Android自定义View基本步骤 ​ 2.onMeasure() 方法,for循环测量子View,根据子View的宽高来计算自己的宽 高 3.onDra ...

  3. Android自定义View —— TypedArray

    在上一篇中Android 自定义View Canvas -- Bitmap写到了TypedArray 这个属性 下面也简单的说一下TypedArray的使用 TypedArray 的作用: 用于从该结 ...

  4. Android 自定义View —— Canvas

    上一篇在android 自定义view Paint 里面 说了几种常见的Point 属性 绘制图形的时候下面总有一个canvas ,Canvas 是是画布 上面可以绘制点,线,正方形,圆,等等,需要和 ...

  5. android 自定义loading,Android自定义动画-StarLoadingView

    今天来分享第二个自定义loading的动画,起了个名字叫 蹦跶的星星 ,还是老规矩先介绍,后上图. 实现效果在最后,GIF有点大,手机流量慎重. 介绍 首先声明做这个动画的初衷是为了学习和分享,所以从 ...

  6. android自定义view获取控件,android 自定义控件View在Activity中使用findByViewId得到结果为null...

    转载:http://blog.csdn.net/xiabing082/article/details/48781489 1.  大家常常自定义view,,然后在xml 中添加该view 组件..如果在 ...

  7. android 自定义命名空间,Android自定义ActionBar实例

    本文实例讲述了android自定义actionbar的实现方法.分享给大家供大家参考.具体实现方法如下: android 3.0及以上已经有了actionbar的api,可以通过引入support p ...

  8. Android自定义View:ViewGroup(三)

    自定义ViewGroup本质是什么? 自定义ViewGroup本质上就干一件事--layout. layout 我们知道ViewGroup是一个组合View,它与普通的基本View(只要不是ViewG ...

  9. Android自定义视图四:定制onMeasure强制显示为方形

    这个系列是老外写的,干货!翻译出来一起学习.如有不妥,不吝赐教! Android自定义视图一:扩展现有的视图,添加新的XML属性 Android自定义视图二:如何绘制内容 Android自定义视图三: ...

最新文章

  1. Excel超级链接方式应用技巧
  2. Oracle OS Block Header
  3. 什么是groupid和artifactId?
  4. xampp for Ubuntu安装.run文件
  5. 618 京东到家-小程序也狂欢
  6. 职场信念:人生的12种财富(转帖)
  7. 抓屏的各种方法(http://www.codeproject.com/KB/dialog/screencap.aspx)
  8. XHTML教会我的一些东西-1
  9. js笔记(六)事件、正则
  10. 2020年苹果App Store销售额达6430亿美元 同比增长24%
  11. 20155226 实验三 敏捷开发与XP实践 实验报告
  12. python爬取酒店评论_scrapy爬取酒店评论数据
  13. wow工程修理机器人图纸_wow修理机器人74a型介绍及图纸怎么得
  14. Android模拟器哪个稳定,哪个安卓模拟器好 什么安卓模拟器稳定流畅速度快不卡顿...
  15. 如何将已有图片做成透明水印_如何给图片制作透明水印
  16. 通俗易懂的傅立叶级数理解
  17. MySQL索引原理(标贝科技)
  18. 大数据应用之 --- apache doris 基于ssb测试
  19. NANK南卡降噪耳机和OPPO蓝牙耳机哪个更好呢?哪款更能打?
  20. Python_001_旅游评论情感倾向性分析

热门文章

  1. 笔记:腾讯CodeReview规范
  2. 毕业生就业管理系统的设计与实现
  3. jxl去掉excel有效性验证
  4. 超全展厅店铺sketchup模型素材网站整理
  5. CAD初学者笔记AutoCAD2008版本
  6. 【每日总结】数据在内存中的存储
  7. 吉林大学966java_2021年吉林大学计算机考研科目
  8. 绿色环保作为经济长线主题,MOVE PROTOCOL运动APP来助力
  9. 全年合辑 | 网安产业40万字报告,400页幻灯片,200项政策打包带走
  10. 计算机二级python模拟软件、真题