文章目录

  • 自定义相机的一般步骤
  • 设置权限
  • 检测相机
  • 访问相机
  • 检测相机功能
  • 创建预览类
  • 在布局文件中放预览视图
  • 录制视频步骤
  • 配置MediaRecorder
  • 启动和停止MediaRecorder
  • 释放相机

自定义相机的一般步骤

  • 是否有摄像头、是否有访问摄像头的权限
  • 创建相机预览类,继承SurfaceView并实现SurfaceHolder接口,用来预览相机的即时图片
  • 有了相机预览类之后,搭建预览布局将预览视图和界面控件结合起来
  • 连接控件的监听器以响应用户的动作,拍摄照片或视频,比如一个按钮点击事件
    拍摄照片和视频并保存输出
  • 摄像头使用完毕后,要正确地释放相机以便于其他应用使用

注意:

相机是共享资源,必须合理管理才不至于和其他同样用到相机的应用发生冲突

当你的应用使用完相机之后,记得调用Camera.release()方法以释放Camera对象。如果没有正确地释放相机,设备上的任何应用,随后任何访问相机的尝试,都有可能失败、退出

设置权限

    <!--摄像头权限--><uses-permission android:name="android.permission.CAMERA"/><!--具备摄像头--><uses-feature android:name="android.hardware.camera"/><!--存储图像或者视频权限--><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!--录制音频权限--><uses-permission android:name="android.permission.RECORD_AUDIO" />

检测相机

private boolean checkCameraHardware(Context context) {// 支持所有版本return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);//  Android 2.3 (API Level 9) 及以上的// return  Camera.getNumberOfCameras() > 0;
}

访问相机

public static Camera getCameraInstance(){Camera c = null;try {// 在多个摄像头时,默认打开后置摄像头c = Camera.open(); // Android 2.3(API 9之后可指定cameraId摄像头id,可选值为后置(CAMERA_FACING_BACK)/前置( CAMERA_FACING_FRONT)//  c = Camera.open(cameraId); } catch (Exception e){// Camera被占用或者设备上没有相机时会崩溃。}return c;  // returns null if camera is unavailable
}

注意: 在部分设备上,打开摄像头时可能会花费较长的时间,因此此操作应该在子线程上执行,然后以回调的方式传递Camera 对象,避免出现ANR;

检测相机功能

在获取到Camera对象之后,可以调用Camera.getParameters()方法并检测该方法返回的Camera.Parameters对象所支持的功能以获取到更多关于相机功能的信息。当使用API 9及以上时, 使用Camera.getCameraInfo()检测摄像头是前置还是后置、图像的方向,具体使用可以参看【Camera相机开发】实现开启相机

创建预览类

摄像头预览类继承自SurfaceView,能够实时的展示来自摄像头的图像数据,方便用户捕捉图片和视频
下面的代码演示了预览类的基本创建。这个类继承自SurfaceHolder.Callback以获取创建和销毁该预览视图的回调事件,这些事件在指派相机预览输入时所需要的

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {private SurfaceHolder mHolder;private Camera mCamera;private Context context;public CameraPreview(Context context, Camera camera) {super(context);this.context = context;mCamera = camera;// 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) {// 通知摄像头可以在这里绘制预览了try {mCamera.setPreviewDisplay(holder);mCamera.startPreview();} catch (IOException e) {Log.d(TAG, "Error setting camera preview: " + e.getMessage());}}public void surfaceDestroyed(SurfaceHolder holder) {// 什么都不做,但是在Activity中Camera要正确地释放预览视图}public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {// 如果预览视图可变或者旋转,要在这里处理好这些事件// 在重置大小或格式化时,确保停止预览if (mHolder.getSurface() == null) {// preview surface does not existreturn;}// 变更之前要停止预览try {mCamera.stopPreview();} catch (Exception e) {// ignore: tried to stop a non-existent preview}// 在这里重置预览视图的大小、旋转、格式化// 使用新设置启动预览视图try {mCamera.setPreviewDisplay(mHolder);mCamera.startPreview();} catch (Exception e) {Log.d(TAG, "Error starting camera preview: " + e.getMessage());}}
}

如果要给预览视图设置指定的大小,请在surfaceChanged()方法中像上面的注释中提到的一样设置。当设置预览视图大小时,必须使用从getSupportedPreviewSizes()获取到的值。不要在setPreviewSize()中随意设置值

在布局文件中放预览视图

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical"><FrameLayoutandroid:id="@+id/camera_preview"android:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_weight="1" /><Buttonandroid:id="@+id/button_capture"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="Capture" />
</LinearLayout>

在Activity中获取预览视图的容器视图,然后将预览视图放置在容器视图中

     // 创建Camera实例mCamera = getCameraInstance();// 创建预览视图,并作为Activity的内容mPreview = new CameraPreview(this, mCamera);FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);preview.addView(mPreview);

完成这一步就可以看到预览效果了

录制视频步骤

录制视频需要注意管理Camera以及MediaRecorder类。通过摄像头录制视频时,必须控制 Camera.lock()Camera.unlock()的调用以允许MediaRecorder访问摄像头设备,另外还有 Camera.open()Camera.release()的调用

从Android 4.0 (API 14)开始, Camera.lock() 和 Camera.unlock() 的调用已经被自动管理了

使用摄像头录制视频和拍照不同,录制视频需要特别的调用顺序。要想做好准备工作,必须遵从特定的执行顺序

  1. 打开摄像头 - 使用Camera.open()获取Camera实例

  2. 连接预览视图 - 使用Camera.setPreviewDisplay()连接SurfaceView

  3. 开始预览 - 使用Camera.startPreview() 方法显示即时录像图片(这三步我们之前已经做好了)

  4. 开始录制视频 - 要完成视频录制,必须按顺序完成下面的不步骤:
    1) 解锁摄像头 - 调用Camera.unlock()解锁摄像头以供MediaRecorder使用
    2) 配置MediaRecorder - 依次调用以下MediaRecorder的方法
    setCamera() - 设置视频录制所用到的摄像头
    setAudioSource - 设置音频源,使用 MediaRecorder.AudioSource.CAMCORDER
    setVideoSource() - 设置视频源,使用MediaRecorder.VideoSource.CAMERA
    ④设置视频的输出格式和编码方式。Android 2.2 (API 8)及以上版本,用MediaRecorder.setProfile方法,用CamcorderProfile.get()方法获取 profile 实例
    setOutputFile() - 设置输出文件
    setPreviewDisplay()

    注意:MediaRecorder的这些方法必须依次调用,否则应用会出错,录制失败

    3)准备MediaRecorder - 调用MediaRecorder.prepare()方法
    4)开始录制 - 调用MediaRecorder.start()

  5. 停止录制 - 依次调用下面的方法以完成录制
    1)Stop MediaRecorder - 调用 MediaRecorder.stop()
    2)Reset MediaRecorder - 非必须的,调用MediaRecorder.reset()方法移除Recorder的配置设置
    3)Release MediaRecorder - 调用MediaRecorder.release()方法
    4)Lock the Camera - 调用Camera.lock()锁定摄像头,随后其他的MediaRecorder才能使用它。从Android 4.0(API 14)开始,只有在MediaRecorder.prepare()方法调用失败时,才需要调用这个方法

  6. Stop the Preview - 当Activity完成使用完摄像头后,调用Camera.stopPreview()停止预览

  7. Release Camera - 调用Camera.release()释放摄像头,其他应用才能使用

温馨提示:如果应用通常用来拍摄视频,启动预览视图是使用 设置setRecordingHint(boolean)为true。这个设置可以减少启动录制的时间。

配置MediaRecorder

private boolean prepareVideoRecorder() {if(mCamera == null){mCamera = getCameraInstance();}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(CamcorderProfile.QUALITY_HIGH));// Step 4: Set output filemMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());// Step 5: Set the preview outputmMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());// 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;}

启动和停止MediaRecorder

当使用MediaRecorder启动和停止录制时,必须遵从指定的顺序:

  1. Camera.unlock()
  2. 如以上的代码示例配置MediaRecorder
  3. MediaRecorder.start()启动录制
  4. 录制视频
  5. MediaRecorder.stop()停止录制
  6. MediaRecorder.release()释放MediaRecorder
  7. Camera.lock()锁定摄像头

以下代码演示了怎样使用Camera和MediaRecorder通过一个按钮正确的启动和停止视频录制

private boolean isRecording = false;private void record(){if (isRecording) {// stop recording and release cameramMediaRecorder.stop();  // stop the recordingreleaseMediaRecorder(); // release the MediaRecorder objectmCamera.lock();         // take camera access back from MediaRecorder// inform the user that recording has stoppedbtn.setText("Capture");isRecording = false;} else {// initialize video cameraif (prepareVideoRecorder()) {// Camera is available and unlocked, MediaRecorder is prepared,// now you can start recordingmMediaRecorder.start();// inform the user that recording has startedbtn.setText("Stop");isRecording = true;} else {// prepare didn't work, release the camerareleaseMediaRecorder();// inform user}}}

当完成一个视频录制后,不要释放Camera,否则预览视图也会停止

释放相机

一个设备上,摄像头是所有应用的共享资源,因此在自身的应用处于onPause状态时,要立即释放掉正在使用的Camera对象

 @Overrideprotected void onPause() {super.onPause();releaseMediaRecorder();       // if you are using MediaRecorder, release it firstreleaseCamera();              // release the camera immediately on pause event}private void releaseMediaRecorder(){if (mMediaRecorder != null) {mMediaRecorder.reset();   // clear recorder configurationmMediaRecorder.release(); // release the recorder objectmMediaRecorder = null;mCamera.lock();           // lock camera for later use}}private void releaseCamera(){if (mCamera != null){mCamera.release();        // release the camera for other applicationsmCamera = null;}}

录制完视频会存放在以下路径

感谢简书作者
https://www.jianshu.com/p/b10f6aa1cb5f

Android自定义视频录制相关推荐

  1. Android自定义照相机录制视频

    Android端视频的录制: 1.自定义Camera和MediaRecorder录制视频和拍摄照片,基本功能都能实现,但是也存在一定的问题.a.后置摄像头拍摄完成后照片自动旋转90度或者270度b.如 ...

  2. android 后台视频录制【原创】

    2012-08-02 21:41:39|  分类: android记录 |  标签:android视频  |举报|字号 订阅 题记:记录下这几天一直在苦恼的一件事,心情各种起伏.先是有个变态的客户(嗯 ...

  3. android 录音原始文件_Android 11可能最终会取消Android对视频录制的4GB文件大小限制...

    2019年,智能手机品牌在相机质量上有了巨大的飞跃,尤其是在变焦和微光方面.另一方面,视频质量并没有得到同等的重视.2020年,随着高通骁龙(Qualcomm Snapdragon) 865网络服务提 ...

  4. android gpu 视频编码,Android Mp4视频录制(OpenGL实现篇,附DEMO)

    上一篇中(http://www.jianshu.com/p/113e4eedb752),我们已经了解了视频录制的大概流程,以及部分关键代码,在这一篇,我给大家介绍借助OpenGL来对视频图像进行处理的 ...

  5. Android 小视频录制

    一·视频录制界面 SurfaceView 的使用 SurfaceView我们可以把它当作一个容器,它放在所有窗口的下面·提供了一个可见区域,通过SurfaceHolder接口访问这个surface,g ...

  6. Android中小视频录制,预览

    工作中项目需求,在动态里面支持查看录制的小视频:录制视频主要用到Android中MediaRecorder这个类,在录制的过程中需要结合SurfaceView和Camera,Camera管理手机摄像头 ...

  7. Android小视频录制技术实现

    老大下达了一个要求,让我高仿一个类似微信录制小视频的功能,根据网上各路大神的demo及思路参考下,然后我就粗糙的做了一个小demo,个人感觉还不错,不喜者忽喷.源码链接在文件后面提供,欢迎大家学习及参 ...

  8. android自定义视频列表,Github最火开源项目-高仿今日头条视频列表功能

    主要特点视频全屏播放和浮层小窗播放 可以完全自定义UI 能在ListView.ViewPager和ListView.ViewPager和Fragment等多重嵌套模式下全屏工作 手势修改进度和音量 视 ...

  9. android 录像 源代码,android安卓视频录制摄像拍摄源码(测试可用)

    [实例简介] [实例截图] [核心代码] package com.cn.mvideo; import java.io.File; import java.io.IOException; import ...

最新文章

  1. 资金只够支撑10个月,自动驾驶致命事故重演:特斯拉陷入困境
  2. 用于构建集成式桌面应用程序的新指南和新工具(转载于MSDN)
  3. c语言extern关键字详解
  4. div 隐藏_div的position属性
  5. pandas获取最大值/最小值对应的index
  6. Leetcode每日一题:80.remove-duplicates-from-sorted-array-ii(删除排序数组中的重复项Ⅱ)
  7. 机器人(人工智能python) arduino编程 scratch2.0 乐高ev3编程 教育政策及考试
  8. 2022-2028年中国光纤放大器行业市场发展潜力及投资策略研究报告
  9. TCP/IP常见攻击手段
  10. 测试显卡用什么软件最好,显卡测试用什么软件 怎么测试显卡性能
  11. 1688API item_search_img - 拍立淘搜索淘宝商品
  12. 可视化大屏设计尺寸_数据可视化大屏设计尺寸怎么定?
  13. 通天阁塔机器人图片_CORNER | 大阪 · 东京铁塔也比不过跟你一起看的通天阁
  14. Android 本地化、多语言
  15. 关系数据库之关系代数
  16. 存储及可编程是未来物联网芯片发展的关键
  17. xdm,外包能干吗?实在是....
  18. QPushButton去掉虚线框(焦点框)
  19. day79_babasport第五天
  20. 小米手环2来电不震动,来电不提醒怎么办

热门文章

  1. 分享一下小米3G 3a 3c 4c 4a不拆机刷机的过程(小米4c)
  2. 从华为云到米家APP,智能家居行业如何突破发展?智能家居未来发展方向(下)
  3. to B变道to C,优信二手车的下一阶段怎么跑?
  4. 急切寻求电路方面人才
  5. 第1节 IMPALA:2、架构介绍
  6. html 项目 目录架构,前端项目目录结构规范.pdf
  7. 一文读懂基于PN532和S50的NFC开发
  8. 完全分布式集群时间同步
  9. oracle强弱动态游标,Oracle动态游标的使用
  10. 使用Python+yolov3实现对帧数不等长视频进行批处理