Android前置后置摄像头录制视频综合版
2017-01-10 14:12
387 查看
这个版本,当时以为没bug了,后来发现还是有不少问题的,然后又更新了一个版本,支持横竖屏的录制,以及摄像头的切换,横竖屏录制的标准是在录制开始之前,而不是录制过程中。<工具类的地址>
公司有个项目,有一个需求是录制视频上传到网上,原本准备使用系统的录制功能,发现界面的跳转不能满足需求。于是就只能用自己写的,然后我也不会,就找了很多网上的例子,发现总是有些问题,然后我总结了一下写成了一个工具类,现在分享出来。
import java.io.File; import java.io.IOException; import android.content.Context; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.media.MediaRecorder; import android.view.SurfaceHolder; import android.view.SurfaceView; /** * 用于录制视频的工具类 * * @author 街角慢嗨 * @email 754155526@qq.com * @time 2017-01-10 */ public class MediaRecorderUtil { private MediaRecorder mediaRecorder; // 录像camera private Camera camera; // 用于判断前置摄像头还是后置摄像头 private int cameraPosition = 1; // 判断前置摄像头 还是后置 private boolean isCheck; private SurfaceHolder.Callback callback; // 上下文 @SuppressWarnings("unused") private Context context; // 容器 private SurfaceView surfaceView; /** * 创建录制环境 * * @param surfaceView * 需要用到的surfaceview * @param context * 上下文 */ @SuppressWarnings("deprecation") public void create(SurfaceView surfaceView, Context context) { this.context = context; this.surfaceView = surfaceView; surfaceView.getHolder() .setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); surfaceView.setKeepScreenOn(true); callback = new SurfaceHolder.Callback() { // 在控件创建的时候,进行相应的初始化工作 public void surfaceCreated(SurfaceHolder holder) { // 打开相机,同时进行各种控件的初始化mediaRecord等 camera = Camera.open(); mediaRecorder = new MediaRecorder(); } // 当控件发生变化的时候调用,进行surfaceView和camera进行绑定,可以进行画面的显示 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { doChange(holder); } @Override public void surfaceDestroyed(SurfaceHolder holder) { } }; // 为SurfaceView设置回调函数 surfaceView.getHolder().addCallback(callback); } // 当我们的程序开始运行,即使我们没有开始录制视频,我们的surFaceView中也要显示当前摄像头显示的内容 private void doChange(SurfaceHolder holder) { try { camera.setPreviewDisplay(holder); // 设置surfaceView旋转的角度,系统默认的录制是横向的画面,把这句话注释掉运行你就会发现这行代码的作用 camera.setDisplayOrientation(90); camera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } // public int getDegree() { // // 获取当前屏幕旋转的角度 // int rotating = this.getWindowManager().getDefaultDisplay() // .getRotation(); // int degree = 0; // // 根据手机旋转的角度,来设置surfaceView的显示的角度 // switch (rotating) { // case Surface.ROTATION_0: // degree = 90; // break; // case Surface.ROTATION_90: // degree = 0; // break; // case Surface.ROTATION_180: // degree = 270; // break; // case Surface.ROTATION_270: // degree = 180; // break; // } // return degree; // } /** * 切换摄像头 */ public void changeCamara() { // 切换前后摄像头 int cameraCount = 0; CameraInfo cameraInfo = new CameraInfo(); cameraCount = Camera.getNumberOfCameras();// 得到摄像头的个数 for (int i = 0; i < cameraCount; i++) { Camera.getCameraInfo(i, cameraInfo);// 得到每一个摄像头的信息 if (cameraPosition == 1) { // 现在是后置,变更为前置 if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {// 代表摄像头的方位,CAMERA_FACING_FRONT前置 // CAMERA_FACING_BACK后置 camera.stopPreview();// 停掉原来摄像头的预览 camera.release();// 释放资源 camera = null;// 取消原来摄像头 camera = Camera.open(i);// 打开当前选中的摄像头 try { camera.setPreviewDisplay(surfaceView.getHolder());// 通过surfaceview显示取景画面 camera.setDisplayOrientation(90); } catch (IOException e) { e.printStackTrace(); } camera.startPreview();// 开始预览 cameraPosition = 0; isCheck = true; break; } } else { // 现在是前置, 变更为后置 if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {// 代表摄像头的方位,CAMERA_FACING_FRONT前置 // CAMERA_FACING_BACK后置 camera.stopPreview();// 停掉原来摄像头的预览 camera.release();// 释放资源 camera = null;// 取消原来摄像头 camera = Camera.open(i);// 打开当前选中的摄像头 try { camera.setPreviewDisplay(surfaceView.getHolder());// 通过surfaceview显示取景画面 camera.setDisplayOrientation(90); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } camera.startPreview();// 开始预览 cameraPosition = 1; isCheck = false; break; } } } } public void stopRecord() { // 当结束录制之后,就将当前的资源都释放 mediaRecorder.release(); camera.release(); mediaRecorder = null; // 然后再重新初始化所有的必须的控件和对象 camera = Camera.open(); if (isCheck) { } else { } mediaRecorder = new MediaRecorder(); doChange(surfaceView.getHolder()); } /** * 开始录制 * * @param path * 录制保存的路径 * @param name * 文件名称 */ public void startRecord(String path, String name) { // 先释放被占用的camera,在将其设置为mediaRecorder所用的camera // 解锁并将摄像头指向MediaRecorder camera.unlock(); mediaRecorder.setCamera(camera); // 指定输入源 mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // mediaRecorder.setCamera(camera)如果不用这个方式 那么下面这句话可以加入用来设置视频清晰度的 不然会产生冲突 // 报错 我也不知道是为什么 // mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); // 设置输出格式和编码格式 mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); // 设置编码格式 mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); // 这句必须加上 用来搞视频清晰度的 mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024); // 设置视频录制的分辨率。必须放在设置编码和格式的后面,否则报错 mediaRecorder.setVideoSize(1280, 720); // 还有个设置焦距的 发现没卵用 我就不加了 自己找去 // File file = new File(path); if (!file.exists()) { file.mkdirs(); } // 保存的路径以及文件名称 mediaRecorder.setOutputFile(path + "/" + name + ".mp4"); // 预览输出 mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface()); // 判断是前置摄像头还是后置摄像头 然后设置视频旋转 如果不加上 后置摄像头没有问题 但是前置摄像头录制的视频会导致上下翻转 if (isCheck) { mediaRecorder.setOrientationHint(180); } else { mediaRecorder.setOrientationHint(90); } // 开始录制 try { mediaRecorder.prepare(); mediaRecorder.start(); } catch (IOException e) { e.printStackTrace(); } } }使用的demo
import com.example.videocamara.R; import android.app.Activity; import android.os.Bundle; import android.os.Environment; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity implements OnClickListener { private Button button, button2, button3; private SurfaceView surfaceView; private String path; private String name; private MediaRecorderUtil util; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); initSurfaceView(); } private void initSurfaceView() { surfaceView = (SurfaceView) findViewById(R.id.surfaceView); util = new MediaRecorderUtil(); util.create(surfaceView, this); } private void init() { button = (Button) findViewById(R.id.button); button2 = (Button) findViewById(R.id.button2); button3 = (Button) findViewById(R.id.button3); button.setOnClickListener(this); button2.setOnClickListener(this); button3.setOnClickListener(this); path = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/yundd_vedio"; name = "123213"; } @Override public void onClick(View v) { switch (v.getId()) { case R.id.button: util.startRecord(path, name); break; case R.id.button2: util.stopRecord(); break; case R.id.button3: util.changeCamara(); break; } } }
相关文章推荐
- Android前置摄像头视频录制失败(MediaRecorder: start failed: -19)
- Android开发:实时处理摄像头预览帧视频------浅析PreviewCallback,onPreviewFrame,AsyncTask的综合应用
- Android切换前后置摄像头并录制视频
- OpenCV Android 打开前置后置摄像头
- 解决华为M2 平板前置摄像头录制视频黑屏
- Android开发:实时处理摄像头预览帧视频------浅析PreviewCallback,onPreviewFrame,AsyncTask的综合应用
- 【Android应用实例00】 用摄像头录制视频并本地保存
- Android开发:实时处理摄像头预览帧视频------浅析PreviewCallback,onPreviewFrame,AsyncTask的综合应用
- Android开发:实时处理摄像头预览帧视频--浅析PreviewCallback,onPreviewFrame,AsyncTask的综合应用
- Android切换前后置摄像头并录制视频
- Android开发:实时处理摄像头预览帧视频------浅析PreviewCallback,onPreviewFrame,AsyncTask的综合应用
- Android切换前后置摄像头并录制视频
- Android开发:实时处理摄像头预览帧视频------浅析PreviewCallback,onPreviewFrame,AsyncTask的综合应用(转)
- android打开前置摄像头和后置摄像头
- Android切换前后置摄像头并录制视频
- Android开发:实时处理摄像头预览帧视频------浅析PreviewCallback,onPreviewFrame,AsyncTask的综合应用(转)
- 前置摄像头后台视频录制,即可以自动拍摄也可以手动干涉,实现完全控制
- android前置竖屏摄像头录制视频保存到本地
- 在APP当中调用Android系统摄像头进行视频录制
- android打开前置摄像头和后置摄像头