package com.yydcdut.note.model.camera.impl;
import android.content.Context;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import com.yydcdut.note.model.camera.ICameraFocus;
import com.yydcdut.note.model.camera.ICameraModel;
import com.yydcdut.note.model.camera.ICaptureModel;
import com.yydcdut.note.model.camera.IPreviewModel;
import com.yydcdut.note.utils.YLog;
import com.yydcdut.note.utils.camera.param.Size;
import com.yydcdut.note.widget.camera.AutoFitPreviewView;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.inject.Inject;
/**
* Created by yuyidong on 16/2/3.
*/
public class CameraModelImpl implements ICameraModel {
private static final String TAG = CameraModelImpl.class.getSimpleName();
private Camera mCamera;
private static final int STATE_CAMERA_CLOSE = 0;
private static final int STATE_CAMERA_OPEN = 1;
private static final int STATE_CAMERA_PREVIEW = 2;
private static final int STATE_CAMERA_CAPTURE = 3;
private int mCameraState = STATE_CAMERA_CLOSE;
private CameraSettingModel mCameraSettingModel;
private CameraFocusModel mCameraFocusModel;
private PreviewModel mPreviewModel;
private CaptureModel mCaptureModel;
private PicturesPreviewCallback mPicturesPreviewCallback;
@Inject
public CameraModelImpl() {
}
@Override
public void openCamera(String id, OnCameraOpenedCallback callback, int orientation, Size pictureSize) {
if (mCameraState != STATE_CAMERA_CLOSE) {
return;
}
if (callback == null) {
throw new IllegalArgumentException("");
}
if (mCameraState == STATE_CAMERA_CLOSE && mCamera == null) {
int cameraId = 0;
try {
cameraId = Integer.parseInt(id);
} catch (Exception e) {
//String转int失败,id不是数字
YLog.e(e);
}
mCamera = Camera.open(cameraId);
mCamera.setDisplayOrientation(orientation);
mCameraState = STATE_CAMERA_OPEN;
mPreviewModel = new PreviewModel();
} else {
printLog("openCamera");
}
mCameraSettingModel = new CameraSettingModel(mCamera);
if (pictureSize == null) {
List<Size> list = mCameraSettingModel.getSupportPictureSizes();
Collections.sort(list, new Comparator<Size>() {
@Override
public int compare(Size lhs, Size rhs) {
return -(rhs.getWidth() * rhs.getHeight() - lhs.getWidth() * lhs.getHeight());
}
});
pictureSize = list.get(list.size() - 1);
}
mCameraSettingModel.setPictureSize(pictureSize.getWidth(), pictureSize.getHeight());
callback.onOpen(mPreviewModel, mCameraSettingModel);
}
public class PreviewModel implements IPreviewModel {
@Override
public void startPreview(AutoFitPreviewView.PreviewSurface previewSurface,
OnCameraPreviewCallback callback, Size previewSize) {
if (callback == null) {
throw new IllegalArgumentException("");
}
if (mCameraState == STATE_CAMERA_OPEN && mCamera != null) {
try {
mCameraSettingModel.setPreviewSize(previewSize.getWidth(), previewSize.getHeight());
if (previewSurface.getSurfaceHolder() != null) {
mCamera.setPreviewDisplay(previewSurface.getSurfaceHolder());
} else {
mCamera.setPreviewTexture(previewSurface.getSurfaceTexture());
}
} catch (IOException e) {
YLog.e(e);
callback.onPreviewError();
return;
}
mCamera.startPreview();
mCaptureModel = new CaptureModel();
mCameraState = STATE_CAMERA_PREVIEW;
} else {
printLog("startPreview");
}
mCameraFocusModel = new CameraFocusModel(mCamera, previewSize.getWidth(), previewSize.getHeight());
callback.onPreview(mCaptureModel, mCameraFocusModel);
}
@Override
public void continuePreview() {
mCamera.startPreview();
mCameraState = STATE_CAMERA_PREVIEW;
}
@Override
public void stopPreview() {
if (mCameraState == STATE_CAMERA_PREVIEW && mCamera != null) {
mCamera.stopPreview();
mCameraState = STATE_CAMERA_OPEN;
mCameraFocusModel = null;
} else {
printLog("stopPreview");
}
}
@Override
public boolean isPreview() {
return mCameraState == STATE_CAMERA_PREVIEW;
}
}
public class CaptureModel implements ICaptureModel {
@Override
public long capture(PictureReturnCallback pictureReturnCallback) {
long time = 0l;
if (mCameraFocusModel != null && mCameraFocusModel.getFocusState() != ICameraFocus.FOCUS_STATE_FOCUSING
&& mCameraState == STATE_CAMERA_PREVIEW && pictureReturnCallback != null) {
time = System.currentTimeMillis();
try {
// mCamera.takePicture(sound ? new SoundCallBack() : null, null, new PictureCallBack(time, mCategoryId, ratio, isMirror));
mCamera.takePicture(null, null, new PictureCallBack(time, pictureReturnCallback));
mCameraState = STATE_CAMERA_CAPTURE;
} catch (Exception e) {
YLog.e(e);
pictureReturnCallback.onPictureTaken(false, null, 0l);
}
} else {
YLog.i(TAG, "capture focusState--->" + mCameraFocusModel.getFocusState() + " CameraState--->" + mCameraState);
}
return time;
}
@Override
public void startStillCapture(StillPictureReturnCallback stillPictureReturnCallback) {
if (mCameraFocusModel != null && mCameraFocusModel.getFocusState() != ICameraFocus.FOCUS_STATE_FOCUSING
&& mCameraState == STATE_CAMERA_PREVIEW) {
if (mPicturesPreviewCallback == null) {
mPicturesPreviewCallback = new PicturesPreviewCallback(stillPictureReturnCallback);
} else {
if (mPicturesPreviewCallback.stillPictureReturnCallback != stillPictureReturnCallback) {
mPicturesPreviewCallback = null;
mPicturesPreviewCallback = new PicturesPreviewCallback(stillPictureReturnCallback);
}
}
mCamera.setPreviewCallback(mPicturesPreviewCallback);
} else {
YLog.i(TAG, "capture focusState--->" + mCameraFocusModel.getFocusState() + " CameraState--->" + mCameraState);
}
}
@Override
public void stopStillCapture() {
mCamera.setPreviewCallback(null);
mPicturesPreviewCallback = null;
}
}
private class PicturesPreviewCallback implements Camera.PreviewCallback {
private ICaptureModel.StillPictureReturnCallback stillPictureReturnCallback;
public PicturesPreviewCallback(ICaptureModel.StillPictureReturnCallback stillPictureReturnCallback) {
this.stillPictureReturnCallback = stillPictureReturnCallback;
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
if (stillPictureReturnCallback != null) {
stillPictureReturnCallback.onStillPictureTaken(ImageFormat.NV21, data, System.currentTimeMillis(),
mCameraSettingModel.getPreviewSize().getWidth(), mCameraSettingModel.getPreviewSize().getHeight());
}
}
}
@Override
public void closeCamera() {
if (mCameraState == STATE_CAMERA_OPEN && mCamera != null) {
mCamera.release();
mCamera = null;
mCameraSettingModel = null;
mCameraState = STATE_CAMERA_CLOSE;
} else {
printLog("closeCamera");
}
}
@Override
public boolean isOpen() {
return mCameraState == STATE_CAMERA_OPEN;
}
@Override
public int getCameraNumber(Context context) {
return Camera.getNumberOfCameras();
}
/**
* 创建jpeg图片回调数据对象
*/
private class PictureCallBack implements Camera.PictureCallback {
private long time;
private ICaptureModel.PictureReturnCallback pictureReturnCallback;
public PictureCallBack(long time, ICaptureModel.PictureReturnCallback pictureReturnCallback) {
this.time = time;
this.pictureReturnCallback = pictureReturnCallback;
}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
if (pictureReturnCallback != null) {
pictureReturnCallback.onPictureTaken(true, data, time);
}
// //这里经常崩溃,做个延时处理
// new Handler().postDelayed(new Runnable() {
// @Override
// public void run() {
// reStartPreview();
// }
// }, 300);
}
}
private class SoundCallBack implements Camera.ShutterCallback {
@Override
public void onShutter() {
// try {
// AudioManager meng = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
// int volume = meng.getStreamVolume(AudioManager.STREAM_NOTIFICATION);
// if (volume != 0) {
// if (mShootSound == null) {
// mShootSound = MediaPlayer.create(mContext, Uri.parse("file:///system/media/audio/ui/camera_click.ogg"));
// }
// if (mShootSound != null) {
// mShootSound.start();
// }
// }
// } catch (Exception e) {
// e.getStackTrace();
// }
}
}
private void printLog(String method) {
StringBuilder sb = new StringBuilder(method + " ");
switch (mCameraState) {
case STATE_CAMERA_OPEN:
sb.append("STATE_CAMERA_OPEN");
break;
case STATE_CAMERA_PREVIEW:
sb.append("STATE_CAMERA_PREVIEW");
break;
case STATE_CAMERA_CLOSE:
sb.append("STATE_CAMERA_CLOSE");
break;
case STATE_CAMERA_CAPTURE:
sb.append("STATE_CAMERA_CAPTURE");
break;
}
YLog.i(TAG, "State--->" + sb.toString() + " Camera == null --->" + (mCamera == null));
}
}