您的位置:首页 > 移动开发 > Android开发

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;
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐