由于执法仪类项目要求摄像头录像录出来的视频要是横屏,正常手机录像是竖屏的和屏幕的比例一致,所以摄像头是横放的,带来的问题就是系统自带的
camera app 预览比例不对,是拉伸的,以及方向不对,需要修改
1 首先我们先看看方向问题,通过log 和code的查找,发现app 获取预览方向的接口在packages\apps\Camera2\common\src\com\mediatek\camera\common\utils下的
CameraUtil.java 文件中 getDisplayOrientationFromDeviceSpec 这个地方来获取底层设置的方向的进行计算,这里我们看到前摄由于要镜像的原因做了特别的mirror
处理, 我们只需要在这里看哪个摄像头方向不对,根据cameraId去判断处理 result 的值来控制一下方向就ok了
2 比例问题,我们根据设置预览比例的接口一路跟踪,发现 最终是在packages\apps\Camera2\host\src\com\mediatek\camera\ui\preview下的PreviewTextureView.java文件
中的 onMeasure 这个函数计算的,我们只要设置成和屏幕长宽比对应的比例就行了,可以具体计算下,这里我们设的是240x140
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int previewWidth = MeasureSpec.getSize(widthMeasureSpec);
int previewHeight = MeasureSpec.getSize(heightMeasureSpec);
boolean widthLonger = previewWidth > previewHeight;
int longSide = (widthLonger ? previewWidth : previewHeight);
int shortSide = (widthLonger ? previewHeight : previewWidth);
if (mAspectRatio > 0) {
double fullScreenRatio = findFullscreenRatio(getContext());
if (Math.abs((mAspectRatio - fullScreenRatio)) <= ASPECT_TOLERANCE) {
// full screen preview case
if (longSide < shortSide * mAspectRatio) {
longSide = Math.round((float) (shortSide * mAspectRatio) / 2) * 2;
} else {
shortSide = Math.round((float) (longSide / mAspectRatio) / 2) * 2;
}
} else {
// standard (4:3) preview case
if (longSide > shortSide * mAspectRatio) {
longSide = Math.round((float) (shortSide * mAspectRatio) / 2) * 2;
} else {
shortSide = Math.round((float) (longSide / mAspectRatio) / 2) * 2;
}
}
}
if (widthLonger) {
previewWidth = longSide;
previewHeight = shortSide;
} else {
if(xxxxxx) //sj add this
{
previewWidth = 240;//shortSide;
previewHeight = 140;//longSide;
}
else
{
previewWidth = shortSide;
previewHeight = longSide;
}
}
setMeasuredDimension(previewWidth, previewHeight);
}
3 添加后副摄的切换
自带的前后摄切换是点一下切换到了前摄,在点一下切换到了后摄,这里我们就让切到前摄后,在点一下切到后副摄
摄像头的切换控制是在 packages\apps\Camera2\feature\setting\cameraswitcher\src\com\mediatek\camera\feature\setting下的
CameraSwitcher.java 文件中,很好理解, 因此我们只要在这跟着前后摄切换的地方处理下就ok了
首先我们跟着前后摄的地方添加下后副摄的值的定义,
private static final String CAMERA_FACING_BACK2 = "back2";
private static final int CAMERA_FACING_BACK2_VALUE = 2;
initView 中有切换按钮的callback函数switcher.setOnClickListener,在这里处理下如果是前摄就 nextFacing 就是后副,如果是后副是就后摄
private View initView() {
Activity activity = mApp.getActivity();
View switcher = activity.getLayoutInflater().inflate(R.layout.camera_switcher, null);
switcher.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (SystemProperties.getInt(SWITCH_CAMERA_DEBUG_PROPERTY, 0) == 1) {
LogHelper.d(TAG, "[onClick], enter debug mode.");
switchCameraInDebugMode();
} else {
String nextFacing = mFacing.equals(CAMERA_FACING_BACK) ? CAMERA_FACING_FRONT
: CAMERA_FACING_BACK;
LogHelper.d(TAG, "[onClick], switch camera to " + nextFacing);
String newCameraId = mFacing.equals(CAMERA_FACING_BACK) ? CameraUtil
.getCamIdsByFacing(false).get(0) : CameraUtil.getCamIdsByFacing(true)
.get(0);
//sj add
if(xxxxxx)
{
if(mFacing.equals(CAMERA_FACING_BACK))
nextFacing=CAMERA_FACING_FRONT;
else if(mFacing.equals(CAMERA_FACING_FRONT))
{
nextFacing=CAMERA_FACING_BACK2;
newCameraId=Integer.toString(2);
}
else if(mFacing.equals(CAMERA_FACING_BACK2))
nextFacing=CAMERA_FACING_BACK;
}
//end sj
boolean success = mApp.notifyCameraSelected(newCameraId);
if (success) {
LogHelper.d(TAG, "[onClick], switch camera success.");
mFacing = nextFacing;
mDataStore.setValue(KEY_CAMERA_SWITCHER, mFacing, getStoreScope(), true);
}
mSwitcherView.setContentDescription(mFacing);
}
}
});
switcher.setContentDescription(mFacing);
return switcher;
}
getCamerasFacing 中再处理下后副的facing值就ok了
private List<String> getCamerasFacing(int numOfCameras) {
List<String> camerasFacing = new ArrayList<>();
for (int i = 0; i < numOfCameras; i++) {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(i, info);
String facing = null;
if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
facing = CAMERA_FACING_BACK;
} else if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
facing = CAMERA_FACING_FRONT;
}
//sj add
else if (info.facing == CAMERA_FACING_BACK2_VALUE) {
facing = CAMERA_FACING_BACK2;
}
if (!camerasFacing.contains(facing)) {
camerasFacing.add(facing);
}
}
return camerasFacing;
}
至此,我们发现切换 和 预览都正常了,虽然切换预览ok了,但是后副录像的时候发现录不了像,这个我们下回在说了,因为一路查找发现问题并不是出在camera app中,而是系统的配置中