[] FPS_RANGES) {
+ this.FPS_RANGES = FPS_RANGES;
+ }
+
+ public int getSensorOrientation() {
+ return sensorOrientation;
+ }
+
+ public void setSensorOrientation(int sensorOrientation) {
+ this.sensorOrientation = sensorOrientation;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+}
diff --git a/library/src/main/java/net/ossrs/yasea/CameraView.java b/library/src/main/java/net/ossrs/yasea/CameraView.java
new file mode 100644
index 0000000..d397e4c
--- /dev/null
+++ b/library/src/main/java/net/ossrs/yasea/CameraView.java
@@ -0,0 +1,258 @@
+package net.ossrs.yasea;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CaptureRequest;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 本类的主要功能是 : 开启摄像头
+ *
+ * 1,初始化,{@link CameraView#initCamera()}
+ * 2,权限,{@link CameraView#onRequestPermissionsResult(int, String[], int[])}
+ * 3,生命周期,{@link CameraView#onPause()}
+ *
+ * @author koko 2023/10/12 11:38
+ */
+public class CameraView extends SurfaceView {
+ private static final String TAG = "CameraView";
+ private static final int CAMERA_PERMISSION_REQUEST_CODE = 22;
+ private CameraDevice mCameraDevice;
+ private CameraCaptureSession mCaptureSession;
+ private CaptureRequest.Builder mPreviewBuilder;
+ public CameraView(Context context) {
+ super(context);
+ initView();
+ }
+ public CameraView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initView();
+ }
+ public CameraView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initView();
+ }
+ public CameraView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ initView();
+ }
+ private void initView() {
+ SurfaceHolder surfaceHolder = getHolder();
+ surfaceHolder.addCallback(new SurfaceHolder.Callback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ Log.e(TAG, "surfaceCreated: ");
+ // 初始化相机
+ // 在需要使用相机的地方进行权限检查
+ if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
+ // 如果权限未被授予,则请求相机权限
+ ActivityCompat.requestPermissions((Activity) getContext(),
+ new String[]{Manifest.permission.CAMERA},
+ CAMERA_PERMISSION_REQUEST_CODE);
+ } else {
+ // 如果权限已被授予,则直接打开相机
+ openCamera();
+ }
+ }
+ @Override
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ Log.e(TAG, "surfaceChanged: ");
+ // 更新相机预览尺寸
+ updatePreview();
+ }
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ Log.e(TAG, "surfaceDestroyed: ");
+ // 释放相机资源
+ closeCamera();
+ }
+ });
+ }
+ /**
+ * 初始化相机
+ */
+ public void initCamera() {
+ changeCameraOri(getResources().getConfiguration().orientation);
+ }
+ // 处理权限请求的回调
+ public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
+ if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ // 相机权限已被授予,打开相机
+ openCamera();
+ } else {
+ // 相机权限被拒绝,显示一个提示消息或执行其他操作
+ }
+ }
+ }
+ /**
+ * 暂停
+ */
+ protected void onPause() {
+ closeCamera();
+ }
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ changeCameraOri(newConfig.orientation);
+ }
+ /**
+ * 横竖屏处理
+ * @param orientation 横竖屏
+ */
+ private void changeCameraOri(int orientation) {
+ float ratioScreen = 0.28f;
+ float ratioCamera = 16 / 9f;
+ //以窄边为标准
+ //竖屏
+// int screenWidthPortrait = (int) (com.smart.camera2.PhoneHelper.getScreenWidthReal(getContext()) * ratioScreen);
+ int screenWidthPortrait = (int) 1080;
+ int screenHeightPortrait = (int) (screenWidthPortrait * ratioCamera);
+ //横屏
+// int screenHeightLandScape = (int) (com.smart.camera2.PhoneHelper.getScreenHeightReal(getContext()) * ratioScreen);
+ int screenHeightLandScape = (int) 1920;
+ int screenWidthLandScape = (int) (screenHeightLandScape * ratioCamera);
+ ViewGroup.LayoutParams layoutParams = getLayoutParams();
+ if (layoutParams == null) {
+ return;
+ }
+ switch (orientation) {
+ case Configuration.ORIENTATION_PORTRAIT:
+ Log.i(TAG, "onConfigurationChanged: " + "竖屏");
+ // 竖屏1080-1920
+ layoutParams.width = screenWidthPortrait;
+ layoutParams.height = screenHeightPortrait;
+ break;
+ case Configuration.ORIENTATION_LANDSCAPE:
+ Log.i(TAG, "onConfigurationChanged: " + "横屏");
+ // 横屏1920-1080
+ layoutParams.width = screenWidthLandScape;
+ layoutParams.height = screenHeightLandScape;
+ break;
+ }
+ setLayoutParams(layoutParams);
+ }
+ /**
+ * 打开相机
+ */
+ private void openCamera() {
+ CameraManager cameraManager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE);
+ getHolder().setFixedSize(9999, 9999);
+ try {
+ String cameraId = getFrontCameraId(cameraManager);
+ if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
+ return;
+ }
+ cameraManager.openCamera(cameraId, new CameraDevice.StateCallback() {
+ @Override
+ public void onOpened(CameraDevice camera) {
+ mCameraDevice = camera;
+ Log.e(TAG, "onOpened: ");
+ createCaptureSession();
+ }
+ @Override
+ public void onDisconnected(CameraDevice camera) {
+ Log.e(TAG, "onDisconnected: ");
+ }
+ @Override
+ public void onError(CameraDevice camera, int error) {
+ Log.e(TAG, "onError: ");
+ }
+ }, null);
+ } catch (CameraAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ /**
+ * 关闭相机
+ */
+ private void closeCamera() {
+ Log.e(TAG, "closeCamera: ");
+ if (mCaptureSession != null) {
+ mCaptureSession.close();
+ mCaptureSession = null;
+ }
+ if (mCameraDevice != null) {
+ mCameraDevice.close();
+ mCameraDevice = null;
+ }
+ }
+ /**
+ * 刷新
+ */
+ private void updatePreview() {
+ if (mCameraDevice == null) {
+ return;
+ }
+ if (mCaptureSession == null) {
+ return;
+ }
+ try {
+ mCaptureSession.setRepeatingRequest(mPreviewBuilder.build(), null, null);
+ } catch (CameraAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ /**
+ * 获取相机
+ * @param cameraManager cameraManager
+ * @return 相机id
+ * @throws CameraAccessException 异常
+ */
+ private String getFrontCameraId(CameraManager cameraManager) throws CameraAccessException {
+ String[] cameraIds = cameraManager.getCameraIdList();
+ for (String cameraId : cameraIds) {
+ CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
+ Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
+ if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
+ return cameraId;
+ }
+ }
+ return cameraIds[0];
+ }
+ /**
+ * 创建CaptureSession
+ */
+ private void createCaptureSession() {
+ try {
+ SurfaceHolder surfaceHolder = getHolder();
+ surfaceHolder.setFixedSize(getWidth(), getHeight());
+ List surfaces = new ArrayList<>();
+ surfaces.add(surfaceHolder.getSurface());
+ mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+ mPreviewBuilder.addTarget(surfaceHolder.getSurface());
+ mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
+ @Override
+ public void onConfigured(CameraCaptureSession session) {
+ mCaptureSession = session;
+ Log.e(TAG, "onConfigured: ");
+ updatePreview();
+ }
+ @Override
+ public void onConfigureFailed(CameraCaptureSession session) {
+ // 配置会话失败
+ }
+ }, null);
+ } catch (CameraAccessException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/library/src/main/java/net/ossrs/yasea/SrsCameraView.java b/library/src/main/java/net/ossrs/yasea/SrsCameraView.java
index c57962e..fbf6341 100644
--- a/library/src/main/java/net/ossrs/yasea/SrsCameraView.java
+++ b/library/src/main/java/net/ossrs/yasea/SrsCameraView.java
@@ -2,15 +2,29 @@ package net.ossrs.yasea;
import android.app.Activity;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.media.ImageReader;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
+import android.support.annotation.NonNull;
+import android.support.v4.app.ActivityCompat;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.Range;
+import android.util.Size;
import android.view.Surface;
import com.seu.magicfilter.base.gpuimage.GPUImageFilter;
@@ -21,6 +35,8 @@ import com.seu.magicfilter.utils.OpenGLUtils;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -59,6 +75,15 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
private ConcurrentLinkedQueue mGLIntBufferCache = new ConcurrentLinkedQueue<>();
private PreviewCallback mPrevCb;
private CameraCallbacksHandler cameraCallbacksHandler = new CameraCallbacksHandler();
+ private CameraDevice mCameraDevice;//摄像头设备
+ private Size imageDimension;
+ private ImageReader imageReader;
+ private CaptureRequest.Builder captureRequestBuilder;
+ private CameraCaptureSession cameraCaptureSession;
+ private CameraManager cameraManager;//摄像头管理类
+ private String[] cameraNames;//摄像头名称列表
+ private CameraItemData curItem;//当前选中的摄像头参数
+ private ArrayList itemlist = new ArrayList<>();
public SrsCameraView(Context context) {
this(context, null);
@@ -119,17 +144,17 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
@Override
public void onDrawFrame(GL10 gl) {
-
-
- if(mSurfaceWidth != mPreviewWidth || mSurfaceHeight != mPreviewHeight){
+
+
+ if (mSurfaceWidth != mPreviewWidth || mSurfaceHeight != mPreviewHeight) {
//May be a buffer overflow in enableEncoding()
//mPreviewWidth changed but onSurfaceCreated fired after enable encoding (mIsEncoding == true)
//could be calling magicFilter.onInputSizeChanged(width, height) in setPreviewResolution() after changing mGLPreviewBuffer?
//or start the encoder only after onSurfaceCreated ...
Log.e(TAG, String.format("Surface dimensions differ from Preview. May be a buffer overflow. Surface: %dx%d, Preview: %dx%d ", mSurfaceWidth, mSurfaceHeight, mPreviewWidth, mPreviewHeight));
return;
- }
-
+ }
+
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
@@ -140,8 +165,8 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
magicFilter.setTextureTransformMatrix(mTransformMatrix);
magicFilter.onDrawFrame(mOESTextureId);
- if (mIsEncoding) {
- mGLIntBufferCache.add(magicFilter.getGLFboBuffer());
+ if (mIsEncoding) {
+ mGLIntBufferCache.add(magicFilter.getGLFboBuffer());
synchronized (writeLock) {
writeLock.notifyAll();
}
@@ -151,34 +176,96 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
public void setPreviewCallback(PreviewCallback cb) {
mPrevCb = cb;
}
-
- public Camera getCamera(){
+
+ public Camera getCamera() {
return this.mCamera;
}
- public void setPreviewCallback(Camera.PreviewCallback previewCallback){
+
+ public void setPreviewCallback(Camera.PreviewCallback previewCallback) {
this.mCamera.setPreviewCallback(previewCallback);
}
- public int[] setPreviewResolution(int width, int height) {
- mCamera = openCamera();
-
+ //设置预览宽高
+ public int[] setPreviewResolution2(int width, int height) {
mPreviewWidth = width;
mPreviewHeight = height;
- Camera.Size rs = adaptPreviewResolution(mCamera.new Size(width, height));
- if (rs != null) {
- mPreviewWidth = rs.width;
- mPreviewHeight = rs.height;
+// try {
+// String s = cameraManager.getCameraIdList()[1];
+// CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(s);
+// //获取StreamConfigurationMap,它是管理摄像头支持的所有输出格式和尺寸
+// StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+// //根据TextureView的尺寸设置预览尺寸
+// Size mPreviewSize = getOptimalSize(map.getOutputSizes(SurfaceTexture.class), width, height);
+// mPreviewWidth = mPreviewSize.getWidth();
+// mPreviewHeight = mPreviewSize.getHeight();
+ return new int[]{mPreviewWidth, mPreviewHeight};
+// } catch (CameraAccessException e) {
+// throw new RuntimeException(e);
+// }
+ }
+
+ //选择sizeMap中大于并且接近width和height的size
+ private Size getOptimalSize(Size[] outputSizes, int width, int height) {
+ Size tempSize = new Size(width, height);
+ List sizes = new ArrayList<>();
+ for (Size outputSize : outputSizes) {
+ if (width > height) {
+ //横屏的时候
+ if (outputSize.getHeight() > height && outputSize.getWidth() > width) {
+ sizes.add(outputSize);
+ }
+ } else {
+ //竖屏的时候
+ if (outputSize.getWidth() > height && outputSize.getHeight() > width) {
+ sizes.add(outputSize);
+ }
+ }
+ }
+ if (sizes.size() > 0) {
+ //如果有多个符合条件找到一个差距最小的,最接近预览分辨率的
+ tempSize = sizes.get(0);
+ int minnum = 999999;
+ for (Size size : sizes) {
+ int num = size.getHeight() * size.getHeight() - width * height;
+ if (num < minnum) {
+ minnum = num;
+ tempSize = size;
+ }
+ }
}
-
+ return tempSize;
+ /*if (sizes.size() > 0) {
+ return Collections.min(sizes, new Comparator() {
+ @Override
+ public int compare(Size size, Size t1) {
+ return Long.signum(size.getWidth() * size.getHeight() - t1.getWidth() * t1.getHeight());
+ }
+ });
+ }
+ return outputSizes[0];*/
+
+ }
+
+
+ public int[] setPreviewResolution(int width, int height) {
+// mCamera = openCamera();
+
+ mPreviewWidth = width;
+ mPreviewHeight = height;
+// Camera.Size rs = adaptPreviewResolution(mCamera.new Size(width, height));
+// if (rs != null) {
+// mPreviewWidth = rs.width;
+// mPreviewHeight = rs.height;
+// }
+
getHolder().setFixedSize(mPreviewWidth, mPreviewHeight);
-
- mCamera.getParameters().setPreviewSize(mPreviewWidth, mPreviewHeight);
+
+// mCamera.getParameters().setPreviewSize(mPreviewWidth, mPreviewHeight);
mGLPreviewBuffer = ByteBuffer.allocate(mPreviewWidth * mPreviewHeight * 4);
- mInputAspectRatio = mPreviewWidth > mPreviewHeight ?
- (float) mPreviewWidth / mPreviewHeight : (float) mPreviewHeight / mPreviewWidth;
+ mInputAspectRatio = mPreviewWidth > mPreviewHeight ? (float) mPreviewWidth / mPreviewHeight : (float) mPreviewHeight / mPreviewWidth;
- return new int[] { mPreviewWidth, mPreviewHeight };
+ return new int[]{mPreviewWidth, mPreviewHeight};
}
public boolean setFilter(final MagicFilterType type) {
@@ -209,14 +296,20 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
queueEvent(new Runnable() {
@Override
public void run() {
- GLES20.glDeleteTextures(1, new int[]{ mOESTextureId }, 0);
+ GLES20.glDeleteTextures(1, new int[]{mOESTextureId}, 0);
mOESTextureId = OpenGLUtils.NO_TEXTURE;
}
});
}
}
- public void setCameraId(int id) {
+ public void setCameraId(CameraItemData item) {
+ stopTorch();
+ curItem = item;
+ setPreviewOrientation(mPreviewOrientation);
+ }
+
+ public void setCameraId2(int id) {
stopTorch();
mCamId = id;
setPreviewOrientation(mPreviewOrientation);
@@ -235,20 +328,38 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
case Surface.ROTATION_270:
return 270;
}
- }catch (Exception e){
+ } catch (Exception e) {
e.printStackTrace();
}
return -1;
}
-
+
public void setPreviewOrientation(int orientation) {
+ mPreviewOrientation = orientation;
+ try {
+ String s = cameraManager.getCameraIdList()[1];
+ CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(s);
+ Integer integer = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
+ if (integer == CameraCharacteristics.LENS_FACING_BACK) {
+ Log.e("yyy", "fds");
+ } else if (integer == CameraCharacteristics.LENS_FACING_BACK) {
+ Log.e("yyy", "fds");
+ } else {
+ Log.e("yyy", "fds");
+ }
+ } catch (CameraAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void setPreviewOrientation2(int orientation) {
mPreviewOrientation = orientation;
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(mCamId, info);
-
+
int rotateDeg = getRotateDeg();
-
+
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
mPreviewRotation = info.orientation % 360;
@@ -264,11 +375,11 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
mPreviewRotation = (info.orientation + 90) % 360;
}
}
-
- if(rotateDeg > 0){
+
+ if (rotateDeg > 0) {
mPreviewRotation = mPreviewRotation % rotateDeg;
- }
-
+ }
+
}
public int getCameraId() {
@@ -285,7 +396,7 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
IntBuffer picture = mGLIntBufferCache.poll();
mGLPreviewBuffer.asIntBuffer().put(picture.array());
mPrevCb.onGetRgbaFrame(mGLPreviewBuffer.array(), mPreviewWidth, mPreviewHeight);
- }catch (Exception e){
+ } catch (Exception e) {
cameraCallbacksHandler.onError(e);
e.printStackTrace();
worker.interrupt();
@@ -328,13 +439,104 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
}
}
- public boolean startCamera() {
- if (mCamera == null) {
- mCamera = openCamera();
- if (mCamera == null) {
- return false;
+ //相机状态变化时会调用这里的回调函数
+ private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
+ @Override
+ public void onOpened(@NonNull CameraDevice camera) {
+ //相机打开时执行
+ Log.e(TAG, "onOpened");
+ mCameraDevice = camera;
+ //创建相机预览会话
+ createCameraPreviewSession();
+ }
+
+ @Override
+ public void onDisconnected(@NonNull CameraDevice camera) {
+ //相机链接断开
+ Log.e("dsdsfd", "fdsdf");
+
+ }
+
+ @Override
+ public void onError(@NonNull CameraDevice camera, int error) {
+ Log.e("dsdsfd", "fdsdf");
+ }
+ };
+
+ private void createCameraPreviewSession() {
+// SurfaceTexture surfaceTexture=new SurfaceTexture();
+// assert surfaceTexture!=null;
+//
+// surfaceTexture.setDefaultBufferSize(imageDimension.getWidth(),imageDimension.getHeight());
+ //预览的输出画面
+ Surface surface = new Surface(surfaceTexture);
+
+ try {
+ //预览请求
+ captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+ captureRequestBuilder.addTarget(surface);
+ mCameraDevice.createCaptureSession(Arrays.asList(surface, imageReader.getSurface()), new CameraCaptureSession.StateCallback() {
+ @Override
+ public void onConfigured(@NonNull CameraCaptureSession session) {
+ if (mCameraDevice == null) {
+ return;
+ }
+ cameraCaptureSession = session;
+ updatePreview();
+ }
+
+ @Override
+ public void onConfigureFailed(@NonNull CameraCaptureSession session) {
+ Log.e("dkkd", "fdsa");
+ }
+ }, null);
+ } catch (CameraAccessException e) {
+ throw new RuntimeException(e);
+ }
+
+
+ }
+
+ private void updatePreview() {
+ captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
+ CaptureRequest captureRequest = captureRequestBuilder.build();
+
+ try {
+ cameraCaptureSession.setRepeatingRequest(captureRequest, null, null);
+ } catch (CameraAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void startCamera() {
+ try {
+ if (curItem == null) {
+ curItem = itemlist.get(0);
}
+ //通过cameraId获取Camera参数
+// String cameraId = curItem.getId();
+ String cameraId = cameraManager.getCameraIdList()[1];
+ CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
+ StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+ imageDimension = map.getOutputSizes(SurfaceTexture.class)[0];
+ imageReader = ImageReader.newInstance(640, 480, ImageFormat.YUV_420_888, 10);
+// imageReader.setOnImageAvailableListener(onImageAvailableListener,null);
+ if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
+ }
+ cameraManager.openCamera(cameraId, stateCallback, null);
+
+ } catch (CameraAccessException e) {
+ throw new RuntimeException(e);
}
+ }
+
+ public boolean startCamera2() {
+// if (mCamera == null) {
+// mCamera = openCamera();
+// if (mCamera == null) {
+// return false;
+// }
+// }
Camera.Parameters params = mCamera.getParameters();
//params.setPictureSize(mPreviewWidth, mPreviewHeight);
@@ -387,6 +589,12 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
public void stopCamera() {
disableEncoding();
+ stopTorch();
+ mCameraDevice.close();
+ }
+
+ public void stopCamera2() {
+ disableEncoding();
stopTorch();
if (mCamera != null) {
@@ -395,22 +603,26 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
mCamera.release();
mCamera = null;
}
+
}
- protected Camera openCamera() {
+ protected Camera openCamera2() {
Camera camera = null;
if (mCamId < 0) {
Camera.CameraInfo info = new Camera.CameraInfo();
int numCameras = Camera.getNumberOfCameras();
int frontCamId = -1;
int backCamId = -1;
+ int otherCamId = -1;
for (int i = 0; i < numCameras; i++) {
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
backCamId = i;
} else if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
frontCamId = i;
- break;
+// break;
+ } else {
+ otherCamId = i;
}
}
if (frontCamId != -1) {
@@ -418,28 +630,93 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
} else if (backCamId != -1) {
mCamId = backCamId;
} else {
- mCamId = 0;
+ mCamId = otherCamId;
}
}
-
+
try {
- camera = Camera.open(mCamId);
-
- camera.setErrorCallback(new Camera.ErrorCallback(){
+// if (mCamId == 0) {
+// camera = Camera.open(2);
+// } else {
+ camera.stopPreview();
+ camera.release();
+ camera = Camera.open();
+// }
+
+ camera.setErrorCallback(new Camera.ErrorCallback() {
@Override
public void onError(int error, Camera camera) {
//may be Camera.CAMERA_ERROR_EVICTED - Camera was disconnected due to use by higher priority user
stopCamera();
}
- });
-
- }catch (Exception e){
+ });
+
+ } catch (Exception e) {
e.printStackTrace();
}
-
+
return camera;
}
+ public List getCameraData() {
+ itemlist = new ArrayList();
+ cameraManager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE);//获取摄像头管理类
+ try {
+ cameraNames = cameraManager.getCameraIdList();//获取摄像头名称列表
+ } catch (CameraAccessException e) {
+ throw new RuntimeException(e);
+ }
+
+ for (String cameraName : cameraNames) {
+ CameraItemData itemData = new CameraItemData();
+ itemData.setId(cameraName);//摄像头编号
+
+ CameraCharacteristics characteristics = null;
+ try {
+ characteristics = cameraManager.getCameraCharacteristics(cameraName);//获取摄像头各种特性
+ } catch (CameraAccessException e) {
+ throw new RuntimeException(e);
+ }
+ int sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
+ itemData.setSensorOrientation(sensorOrientation);//摄像头朝向
+
+
+ Range[] ranges = characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
+ itemData.setFPS_RANGES(ranges);//
+
+ Long aLong = characteristics.get(CameraCharacteristics.SENSOR_INFO_MAX_FRAME_DURATION);
+ itemData.setMAX_FRAME_DURATION(aLong);
+
+ int lensFacing = characteristics.get(CameraCharacteristics.LENS_FACING);
+ itemData.setLENS_FACING(lensFacing);
+
+ switch (lensFacing) {
+ case CameraMetadata.LENS_FACING_FRONT:
+ Log.e("lensFacing(前后摄):", "front");
+ break;
+ case CameraMetadata.LENS_FACING_BACK:
+ Log.e("lensFacing(前后摄):", "back");
+ break;
+ case CameraMetadata.LENS_FACING_EXTERNAL:
+ Log.e("lensFacing(前后摄):", "external");
+ break;
+ }
+
+ List list = new ArrayList<>();
+ Size[] supportedSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.YUV_420_888);
+ for (Size size : supportedSizes) {
+ int width = size.getWidth();
+ int height = size.getHeight();
+ // 在这里处理支持的分辨率格式
+ int[] temp = {width, height};
+ list.add(temp);
+ }
+ itemData.setSupportedSizes(list);//摄像头输出格式
+ itemlist.add(itemData);
+ }
+ return itemlist;
+ }
+
private Camera.Size adaptPreviewResolution(Camera.Size resolution) {
float diff = 100f;
float xdy = (float) resolution.width / (float) resolution.height;
@@ -494,7 +771,7 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
Camera.Parameters params = mCamera.getParameters();
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
mCamera.setParameters(params);
- }catch (Exception e){
+ } catch (Exception e) {
e.printStackTrace();
}
}
@@ -504,27 +781,28 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
void onGetRgbaFrame(byte[] data, int width, int height);
}
-
- static public class CameraCallbacksHandler implements CameraCallbacks{
+
+ static public class CameraCallbacksHandler implements CameraCallbacks {
@Override
public void onCameraParameters(Camera.Parameters params) {
}
-
+
@Override
public void onError(Exception e) {
//stop publish
- }
-
+ }
+
}
public interface CameraCallbacks {
void onCameraParameters(Camera.Parameters params);
+
void onError(Exception e);
}
public void setCameraCallbacksHandler(CameraCallbacksHandler cameraCallbacksHandler) {
this.cameraCallbacksHandler = cameraCallbacksHandler;
- }
+ }
}
diff --git a/library/src/main/java/net/ossrs/yasea/SrsPublisher.java b/library/src/main/java/net/ossrs/yasea/SrsPublisher.java
index a8c9988..825be28 100644
--- a/library/src/main/java/net/ossrs/yasea/SrsPublisher.java
+++ b/library/src/main/java/net/ossrs/yasea/SrsPublisher.java
@@ -308,15 +308,13 @@ public class SrsPublisher {
return mCameraView.setFilter(type);
}
- public void switchCameraFace(int id) {
-
+ public void switchCameraFace(CameraItemData item) {
if (mEncoder != null && mEncoder.isEnabled()) {
mEncoder.pause();
}
-
mCameraView.stopCamera();
- mCameraView.setCameraId(id);
- if (id == 0) {
+ mCameraView.setCameraId(item);
+ if (item.getLENS_FACING() == 0) {
mEncoder.setCameraBackFace();
} else {
mEncoder.setCameraFrontFace();