我想将颤振应用程序与 ArGear SDK 集成。
Flutter中没有直接使用该SDK的包或插件,需要在平台端实现SDK,并通过方法通道调用对应的方法。
我想在平台端打开相机并在平台端执行图像处理,然后在颤振小部件旁边显示用框架布局实现的相机platform view
。
实现在 android 本机项目中运行良好。但是在将实现代码移动到平台端的颤振应用程序后出现了问题。应用程序正在运行,但屏幕为黑色,并且控制台中没有错误。
initGLView()
在注释方法和setContentView(R.layout.camera_activity);
代码中修复了错误。
SDK有一个监听器来检测摄像头,我测试了另一种方式并打开摄像头,camera plugin
但SDK无法检测到摄像头,在这种情况下我应该在平台端打开摄像头。
android平台实现:
public static final String CHANNEL = "flutter.native/argear";
public static final String STREAM = "argear";
public static final String API_URL = "";
public static final String API_KEY = "";
public static final String SECRET_KEY = "";
public static final String AUTH_KEY = "";
private ARGFrame.Ratio mScreenRatio = ARGFrame.Ratio.RATIO_FULL;
private boolean mUseARGSessionDestroy = false;
private GLView mGlView;
private ReferenceCamera mCamera;
private ARGConfig config;
private Set<ARGInferenceConfig.Feature> inferenceConfig;
private ARGSession argsession;
private ARGMedia argMedia;
private ScreenRenderer mScreenRenderer;
private CameraTexture mCameraTexture;
private CameraActivityBinding mDataBinding;
private boolean mIsShooting = false;
// preview size
private int mDeviceWidth = 0;
private int mDeviceHeight = 0;
private int mGLViewWidth = 0;
private int mGLViewHeight = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//todo : this method cause error on flutter app
setContentView(R.layout.camera_activity);
Point realSize = new Point();
Display display = ((WindowManager) this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
display.getRealSize(realSize);
mDeviceWidth = realSize.x;
mDeviceHeight = realSize.y;
mGLViewWidth = realSize.x;
mGLViewHeight = realSize.y;
//todo : this method cause error on flutter app
mDataBinding = CameraActivityBinding.inflate(getLayoutInflater());
View view = mDataBinding.getRoot();
setContentView(view);
}
@Override
protected void onResume() {
super.onResume();
if (argsession == null) {
if (!PermissionHelper.hasPermission(this)) {
if (PermissionHelper.shouldShowRequestPermissionRationale(this)) {
Toast.makeText(this, "Please check your permissions!", Toast.LENGTH_SHORT).show();
return;
}
PermissionHelper.requestPermission(this);
return;
}
config = new ARGConfig(API_URL, API_KEY, SECRET_KEY, AUTH_KEY);
inferenceConfig
= EnumSet.of(ARGInferenceConfig.Feature.FACE_MESH_TRACKING);
argsession = new ARGSession(this, config, inferenceConfig);
argMedia = new ARGMedia(argsession);
mScreenRenderer = new ScreenRenderer();
mCameraTexture = new CameraTexture();
//todo : this method cause error on flutter app
initGLView();
initCamera();
}
try {
mCamera.startCamera();
} catch (Exception e) {
System.out.println("error is : " + e);
}
argsession.resume();
setGLViewSize(mCamera.getPreviewSize());
addFaceEffect();
}
public void addFaceEffect() {
argsession.contents().setBulge(ARGContents.BulgeType.FUN6);
}
public void changeCameraFace() {
argsession.pause();
mCamera.changeCameraFacing();
argsession.resume();
}
public void setMeasureSurfaceView(View view) {
if (view.getParent() instanceof FrameLayout) {
view.setLayoutParams(new FrameLayout.LayoutParams(mGLViewWidth, mGLViewHeight));
} else if (view.getParent() instanceof RelativeLayout) {
view.setLayoutParams(new RelativeLayout.LayoutParams(mGLViewWidth, mGLViewHeight));
}
/* to align center */
if ((mScreenRatio == ARGFrame.Ratio.RATIO_FULL) && (mGLViewWidth > mDeviceWidth)) {
view.setX((mDeviceWidth - mGLViewWidth) / 2);
} else {
view.setX(0);
}
}
public int getGLViewWidth() {
return mGLViewWidth;
}
public int getGLViewHeight() {
return mGLViewHeight;
}
private void setGLViewSize(int[] cameraPreviewSize) {
int previewWidth = cameraPreviewSize[1];
int previewHeight = cameraPreviewSize[0];
if (mScreenRatio == ARGFrame.Ratio.RATIO_FULL) {
mGLViewHeight = mDeviceHeight;
mGLViewWidth = (int) ((float) mDeviceHeight * previewWidth / previewHeight);
} else {
mGLViewWidth = mDeviceWidth;
mGLViewHeight = (int) ((float) mDeviceWidth * previewHeight / previewWidth);
}
if (mGlView != null
&& (mGLViewWidth != mGlView.getViewWidth() || mGLViewHeight != mGlView.getHeight())) {
mDataBinding.cameraLayout.removeView(mGlView);
mGlView.getHolder().setFixedSize(mGLViewWidth, mGLViewHeight);
mDataBinding.cameraLayout.addView(mGlView);
}
}
@Override
protected void onPause() {
super.onPause();
if (argsession != null) {
mCamera.stopCamera();
argsession.pause();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (argsession != null) {
mCamera.destroy();
mUseARGSessionDestroy = true;
}
}
//todo : this method cause error on flutter app
private void initGLView() {
final FrameLayout cameraLayout = findViewById(R.id.camera_layout);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
mGlView = new GLView(this, glViewListener);
mGlView.setZOrderMediaOverlay(true);
cameraLayout.addView(mGlView, params);
}
private void initCamera() {
mCamera = new ReferenceCamera1(this, cameraListener);
}
ReferenceCamera.CameraListener cameraListener = new ReferenceCamera.CameraListener() {
@Override
public void setConfig(int previewWidth,
int previewHeight,
float verticalFov,
float horizontalFov,
int orientation,
boolean isFrontFacing,
float fps) {
argsession.setCameraConfig(new ARGCameraConfig(previewWidth,
previewHeight,
verticalFov,
horizontalFov,
orientation,
isFrontFacing,
fps));
}
@Override
public void feedRawData(byte[] data) {
Log.d("FEED_RAW_DATA", "feedRawData: Send preview frame raw data from camera device to ARGear");
System.out.println("****************************");
System.out.println("camera detected");
System.out.println("****************************");
// Send preview frame raw data from camera device to ARGear
argsession.feedRawData(data);
}
@Override
public void feedRawData(Image data) {
argsession.feedRawData(data);
}
};
GLView.GLViewListener glViewListener = new GLView.GLViewListener() {
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
mScreenRenderer.create(gl, config);
mCameraTexture.createCameraTexture();
}
@Override
public void onDrawFrame(GL10 gl, int width, int height) {
if (mCameraTexture.getSurfaceTexture() == null) {
return;
}
if (mCamera != null) {
mCamera.setCameraTexture(mCameraTexture.getTextureId(), mCameraTexture.getSurfaceTexture());
}
ARGFrame frame = argsession.drawFrame(gl, mScreenRatio, width, height);
mScreenRenderer.draw(frame, ARGFrame.Ratio.RATIO_4_3, width, height);
if (argMedia != null) {
if (argMedia.isRecording()) argMedia.updateFrame(frame.getTextureId());
}
// check destroy boolean to destroy arg session
if (mUseARGSessionDestroy)
argsession.destroy();
}
};