安卓调用系统相机拍照录视频
安卓使用系统相机拍照录视频调用系统相机拍照和录制视频代码和踩的坑的总结。文章目录安卓使用系统相机拍照录视频前言1、问题记录2、工具类代码前言使用surfaceView+MediaRecorder进行视频拍摄和问题记录1、问题记录问题记录1:无法手指缩小放大问题:修改如下首先重新 onTouchEvent ,记录俩点之间距离和缩放比列,然后重新设置camera中Parameters里的zoom。pr
·
安卓使用系统相机拍照录视频
调用系统相机拍照和录制视频代码和踩的坑的总结。
前言
使用surfaceView+MediaRecorder进行视频拍摄和问题记录
1、问题记录
问题记录
1:无法手指缩小放大问题:
修改如下首先重新 onTouchEvent ,记录俩点之间距离和缩放比列,然后重新设置camera中Parameters里的zoom。
private float startDis;
private boolean isTouch;
/**
* 记录是拖拉照片模式还是放大缩小照片模式
*/
private static final int MODE_INIT = 0;
/**
* 放大缩小照片模式
*/
private static final int MODE_ZOOM = 1;
private int mode = MODE_INIT;// 初始状态
private Point point;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mode = MODE_INIT;
break;
case MotionEvent.ACTION_POINTER_DOWN:
if (event.getPointerCount() < 2)
return super.onTouchEvent(event);
mode = MODE_ZOOM;
startDis = spacing(event);//两点的距离
break;
case MotionEvent.ACTION_MOVE:
if (mode == MODE_ZOOM) {
if (event.getPointerCount() < 2)
return super.onTouchEvent(event);
float endDis = spacing(event);//两点的距离
int scale = (int) ((endDis - startDis) / 10f);
if (scale >= 1 || scale <= -1) {
cameraUtils.setCameraZoom(scale);//设置zoom
startDis = endDis;
}
}
break;
case MotionEvent.ACTION_UP:
if (mode == MODE_INIT) {
point = new Point((int) event.getX(), (int) event.getY());
SensorManger.getIntance().lockFocus();
cameraUtils.focus();//重新聚焦
}
break;
}
return super.onTouchEvent(event);
}
/**
* 两点的距离
*/
private float spacing(MotionEvent event) {
if (event == null) {
return 0;
}
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
Camera.Parameters parameters = camera.getParameters();
int zoom = parameters.getZoom() + scale;
if (zoom < 0) zoom = 0;
if (zoom > parameters.getMaxZoom())
zoom = parameters.getMaxZoom();
parameters.setZoom(zoom);
camera.setParameters(parameters);
2:部分手机拍摄导致崩溃 start failed:或拍摄后空文件
问题原因:1,MediaRecorder参数设置错误,有的手机不支持。2,参数配置顺序出错。
//按以下顺序,亲测,都可以正常拍摄视频
camera.unlock();
mediaRecorder.setCamera(camera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
//mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mediaRecorder.setVideoEncodingBitRate(10*1024 * 1024);
CamcorderProfile mProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_720P);
if (null!=mProfile){
mediaRecorder.setVideoEncoder(mProfile.videoCodec);
mediaRecorder.setVideoFrameRate(mProfile.videoFrameRate);
Log.d("分辨率",mProfile.videoFrameWidth+"::"+ mProfile.videoFrameHeight);
//设置录像的分辨率
mediaRecorder.setVideoSize(mProfile.videoFrameWidth, mProfile.videoFrameHeight);
mediaRecorder.setAudioEncodingBitRate((int) (mProfile.videoBitRate * 0.7));
}
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
mediaRecorder.setOutputFile(name);
Log.d("录制视频地址",name);
// 发送广播,通知刷新图库的显示
ContextFactory.getContext().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse("file://" + name)));
mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
mediaRecorder.prepare();
mediaRecorder.start();
3:拍摄后导致旋转
/***不设置时,录制的视频总是倒着,翻屏导致视频上下翻滚*/
Log.d("摄像头",backOrFtont+"::"+isBack);
if (backOrFtont == Camera.CameraInfo.CAMERA_FACING_BACK){
mediaRecorder.setOrientationHint(90);
}else if (backOrFtont==Camera.CameraInfo.CAMERA_FACING_FRONT){
mediaRecorder.setOrientationHint(270);
}
2、工具类代码
代码如下(示例):
public class CameraUtils {
private MediaRecorder mediaRecorder;
private Camera camera;
/*** 标识当前是前摄像头还是后摄像头 back:0 front:1*/
private int backOrFtont = 0;
private SurfaceHolder.Callback callback;
private Context context;
private SurfaceView surfaceView;
/***录制视频的videoSize*/
private int height, width;
/***photo的height ,width*/
private int heightPhoto, widthPhoto;
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) {
camera = Camera.open();
getVideoSize();//获取拍摄尺寸
mediaRecorder = new MediaRecorder();
}
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
doChange(holder);//切换摄像头
focus();//聚焦
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (camera != null) {
camera.release();
camera = null;
}
}
};
surfaceView.getHolder().addCallback(callback);
}
private void doChange(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(holder);
camera.setDisplayOrientation(90);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
//缩放
public void setCameraZoom(int scale) {
Camera.Parameters parameters = camera.getParameters();
int zoom = parameters.getZoom() + scale;
if (zoom < 0) zoom = 0;
if (zoom > parameters.getMaxZoom())
zoom = parameters.getMaxZoom();
parameters.setZoom(zoom);
camera.setParameters(parameters);
}
/**
* 切换摄像头
*/
public void changeCamera() {
int cameraCount = 0;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for (int i = 0; i < cameraCount; i++) {
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT && backOrFtont == 0) {
camera.stopPreview();
camera.release();
camera = null;
camera = Camera.open(i);
try {
camera.setPreviewDisplay(surfaceView.getHolder());
camera.setDisplayOrientation(90);
} catch (IOException e) {
e.printStackTrace();
}
backOrFtont = 1;
camera.startPreview();
break;
} else if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK && backOrFtont == 1) {
camera.stopPreview();
camera.release();
camera = null;
camera = Camera.open(i);
try {
camera.setPreviewDisplay(surfaceView.getHolder());
camera.setDisplayOrientation(90);
} catch (IOException e) {
e.printStackTrace();
}
camera.startPreview();
backOrFtont = 0;
break;
}
}
}
public void stopRecord() {
if (mediaRecorder != null) {
//设置后不会崩
mediaRecorder.setOnErrorListener(null);
mediaRecorder.setPreviewDisplay(null);
}
mediaRecorder.release();
camera.release();
mediaRecorder = null;
camera = Camera.open();
mediaRecorder = new MediaRecorder();
doChange(surfaceView.getHolder());
}
public void remuse() {
backOrFtont=0;
}
public void stop() {
if (mediaRecorder != null && camera != null) {
mediaRecorder.release();
camera.release();
}
}
public void destroy() {
if (mediaRecorder != null && camera != null) {
mediaRecorder.release();
camera.release();
mediaRecorder = null;
camera = null;
}
}
/**
* @param path 保存的路径
* @param name 录像视频名称(不包含后缀)
* @param isBack
*/
public void startRecord(String path, String name, boolean isBack) {
try {
camera.unlock();
mediaRecorder.setCamera(camera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
//mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mediaRecorder.setVideoEncodingBitRate(10*1024 * 1024);
/* if (backOrFtont==0){
mediaRecorder.setVideoSize(640,480);
mediaRecorder.setVideoFrameRate(24);
}else {*/
CamcorderProfile mProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_720P);
if (null!=mProfile){
mediaRecorder.setVideoEncoder(mProfile.videoCodec);
mediaRecorder.setVideoFrameRate(mProfile.videoFrameRate);
Log.d("分辨率",mProfile.videoFrameWidth+"::"+ mProfile.videoFrameHeight);
//设置录像的分辨率
mediaRecorder.setVideoSize(mProfile.videoFrameWidth, mProfile.videoFrameHeight);
mediaRecorder.setAudioEncodingBitRate((int) (mProfile.videoBitRate * 0.7));
}else {
// mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
//mediaRecorder.setVideoFrameRate(30);
// mediaRecorder.setVideoSize(WIDTH_DEF, HEIGHT_DEF);
// mediaRecorder.setVideoEncodingBitRate((int) (1920000 * 0.7));
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
//mediaRecorder.setAudioEncodingBitRate(128000);
//mediaRecorder.setAudioChannels(2);
//mediaRecorder.setAudioSamplingRate(48000);
}
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
mediaRecorder.setOutputFile(name);
Log.d("录制视频地址",name);
// 发送广播,通知刷新图库的显示
ContextFactory.getContext().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse("file://" + name)));
mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
/***不设置时,录制的视频总是倒着,翻屏导致视频上下翻滚*/
Log.d("摄像头",backOrFtont+"::"+isBack);
if (backOrFtont == Camera.CameraInfo.CAMERA_FACING_BACK){
mediaRecorder.setOrientationHint(90);
}else if (backOrFtont==Camera.CameraInfo.CAMERA_FACING_FRONT){
mediaRecorder.setOrientationHint(270);
}
mediaRecorder.prepare();
mediaRecorder.start();
}catch (Exception e){
e.printStackTrace();
ToastUtils.showToast(AppManager.getAppManager().currentActivity(),"拍摄视频出错",false);
}
}
/***
* 获取SupportedVideoSizes 控制输出视频width在300到600之间(尽可能小)
* 获取PictureSize的大小(控制在w:1000-2000之间)
*/
public void getVideoSize() {
Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> videoSize = parameters.getSupportedVideoSizes();
for (int i = 0; i < videoSize.size(); i++) {
int width1 = videoSize.get(i).width;
int height1 = videoSize.get(i).height;
if (width1 >= 600 && width1 <= 900) {
if (height1 >= 700 && height1 <= 1000) {
width = width1;
height = height1;
}
}
Log.d("路径", "getVideoSize:----w:-- " + videoSize.get(i).width + "---h:--" + videoSize.get(i).height);
}
parameters.setRecordingHint(true); //主要用于MediaRecord录像
parameters.setPreviewFpsRange(30000, 30000); //主要用于设置视频的帧数
camera.setParameters(parameters);
List<Camera.Size> photoSize = parameters.getSupportedPictureSizes();
for (int i = 0; i < photoSize.size(); i++) {
int width1 = photoSize.get(i).width;
int height1 = photoSize.get(i).height;
if (width1 >= 1400 && width1 <= 2000) {
if (height1 >= 1400 && height1 <=2000) {
widthPhoto = width1;
heightPhoto = height1;
}
}
}
}
/**
* 聚焦
*/
public void focus(){
try {
Camera.Parameters parameters=camera.getParameters();
parameters.setPictureSize(widthPhoto,heightPhoto);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
camera.setParameters(parameters);
camera.cancelAutoFocus();
}catch (Exception e){
e.printStackTrace();
}
}
public void takePicture(String photoPath, String photoName) {
Camera.Parameters parameters=camera.getParameters();
parameters.setJpegQuality(100);
camera.takePicture(null, null, new PictureCallBack(photoPath, photoName));
}
private Bitmap bitmap;
/*** 拍照功能*/
private class PictureCallBack implements Camera.PictureCallback {
/*** 照片保存的路径和名称*/
private String path;
private String name;
public PictureCallBack(String path, String name) {
this.path = path;
this.name = name;
}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
if (backOrFtont == Camera.CameraInfo.CAMERA_FACING_BACK){
bitmap = matrixBitmap(bitmap,90); //此方法将Bitmap 旋转90度
}else if (backOrFtont == Camera.CameraInfo.CAMERA_FACING_FRONT){
bitmap = matrixBitmap(bitmap,-90);
}
try {
File filePic = new File(path + name);
if (!filePic.exists()) {
filePic.getParentFile().mkdirs();
filePic.createNewFile();
}
FileOutputStream fos = new FileOutputStream(filePic);
//Bitmap endBit = Bitmap.createScaledBitmap(mBitmap, 720, 1280, true); //创建新的图像大小
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.flush();
fos.close();
// 发送广播,通知刷新图库的显示
ContextFactory.getContext().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse("file://" + filePic)));
} catch (Exception e) {
e.printStackTrace();
}
camera.startPreview();
}
}
/**
* 对bitmap进行旋转
*
* @param bitmap
* @param i
* @return
*/
public Bitmap matrixBitmap(Bitmap bitmap, int i) {
Matrix matrix = new Matrix();
matrix.postRotate(i);
Bitmap bm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
return bm;
}
/**
* 返回合适的照片尺寸参数
*
* @param cameraParameters
* @param bl
* @return
*/
private Camera.Size findFitPicResolution(Camera.Parameters cameraParameters, float bl) throws Exception {
List<Camera.Size> supportedPicResolutions = cameraParameters.getSupportedPictureSizes();
Camera.Size resultSize = null;
for (Camera.Size size : supportedPicResolutions) {
if ((float) size.width / size.height == bl && size.width <= ALLOW_PIC_LEN && size.height <= ALLOW_PIC_LEN) {
if (resultSize == null) {
resultSize = size;
} else if (size.width > resultSize.width) {
resultSize = size;
}
}
}
if (resultSize == null) {
return supportedPicResolutions.get(0);
}
return resultSize;
}
private boolean equalRate(int width, int height, float rate) {
float r = (float) width / (float) height;
if (Math.abs(r - rate) <= 0.2) {
return true;
} else {
return false;
}
}
}
更多推荐
已为社区贡献2条内容
所有评论(0)