模型外包网站,网站建设费用 多少钱,河北抖音seo系统,mvc 5 做网站的教程EasyAR可以使用视频源作为输入源#xff0c;官方给出了示例和文档#xff0c;但是对于大部分Unity开发人员来说看了文档还是一头雾水。
在Android Studio中将custom-camera.jar添加libs中#xff0c;就可以查看源代码了 分析其源代码#xff0c;主要是ExternalCameraSampl…EasyAR可以使用视频源作为输入源官方给出了示例和文档但是对于大部分Unity开发人员来说看了文档还是一头雾水。
在Android Studio中将custom-camera.jar添加libs中就可以查看源代码了 分析其源代码主要是ExternalCameraSample类中的open函数和Start函数。
open即找开相机或视频流start(callback)主要用于取图像帧当有新的Frame时调用callback将最新的帧数据传入一个ByteArrayWrapper的结构中在Unity中再将ByteArrayWrapper转换为InputFrame即可进行识中坚力量。
用java模拟调用端的代码如下 Button btnPlay findViewById(R.id.btnPlay);btnPlay.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View v) {externalCameraSample.open();externalCameraSample.start(new ExternalCameraSample.Callback() {Overridepublic void onPreviewFrame(ExternalCameraSample.ByteArrayWrapper var1) {String str String.valueOf(var1.BufferLength);Log.d(easyar, str);}});}});
修改ExternalCameraSample中open和start重点是ByteArrayWrapper赋值 以下修改后的Java代码C代码略需要自己写
public class ExternalCameraSample {private NativeLib nativeLib;private ExternalCameraParameters mCameraParameters;private boolean suc false;public ExternalCameraSample() {nativeLib new NativeLib();}public boolean open() {suc nativeLib.StartPlay(0, rtsp://admin:admin192.168.43.110:554/stream1);return suc;}private float getRatioError(float x, float x0) {float a x / Math.max(x0, 1.0F) - 1.0F;float b x0 / Math.max(x, 1.0F) - 1.0F;return a * a b * b;}private boolean ready() {return suc;}public boolean start(final ExternalCameraSample.Callback callback) {if (!this.ready()) {return false;} else {//刷新刷数据if(suc){Timer timer new Timer();timer.schedule(new TimerTask(){public int flag1;Overridepublic void run() {nativeLib.native_updateFrame(0);if(mCameraParameters null){mCameraParameters new ExternalCameraParameters();mCameraParameters.setCameraType(1);}mCameraParameters.setWidth(nativeLib.native_getWidth(0));mCameraParameters.setHeight(nativeLib.native_getHeight(0));mCameraParameters.setTimestamp(SystemClock.elapsedRealtimeNanos());ExternalCameraSample.ByteArrayWrapper wrapper new ExternalCameraSample.ByteArrayWrapper();wrapper.Buffer (byte[])nativeLib.native_getFrameData(0);wrapper.BufferLength nativeLib.native_getBytesLength(0);wrapper.camParams ExternalCameraSample.this.mCameraParameters;callback.onPreviewFrame(wrapper);}}, 1, 1);}return true;}}public boolean stop() {if (!this.ready()) {return true;} else {nativeLib.native_stopPlay(0);return true;}}public ExternalCameraParameters getCameraParameters() {return this.mCameraParameters;}public int getPixelFormat() {return 2;}public interface Callback {void onPreviewFrame(ExternalCameraSample.ByteArrayWrapper var1);}public static class ByteArrayWrapper {public byte[] Buffer;public int BufferLength;public ExternalCameraParameters camParams;public ByteArrayWrapper() {}}
}jni从C给java返回数组
extern C
JNIEXPORT jbyteArray JNICALL
Java_com_example_nativelib_NativeLib_native_1getFrameData(JNIEnv *env, jobject thiz, jint index) {//实例返回数组bytekeyjbyteArray jarrRV env-NewByteArray(player[index].m_numBytes);env-SetByteArrayRegion(jarrRV, 0,player[index].m_numBytes,(jbyte*)player[index].m_imgData);return jarrRV;
}
Unity代码在示例上做了少量修改
//
//
// Copyright (c) 2015-2023 VisionStar Information Technology (Shanghai) Co., Ltd. All Rights Reserved.
// EasyAR is the registered trademark or trademark of VisionStar Information Technology (Shanghai) Co., Ltd in China
// and other countries for the augmented reality technology developed by VisionStar Information Technology (Shanghai) Co., Ltd.
//
//#if !UNITY_EDITOR (UNITY_ANDROID || UNITY_IOS)
using AOT;
using System.Runtime.InteropServices;
#endif
using System;
using UnityEngine;
using UnityEngine.UI;namespace easyar
{public class CustomCameraSource : FrameSource{private bool willOpen false;public override OptionalInputFrameSourceType Type { get InputFrameSourceType.General; }public override Optionalbool IsAvailable { get Application.platform RuntimePlatform.Android || Application.platform RuntimePlatform.IPhonePlayer; }protected override void OnEnable(){base.OnEnable();if (externalCamera ! null)externalCamera.Callbool(start, cameraCallback);}protected override void OnDisable(){base.OnDisable();if (externalCamera ! null)externalCamera.Callbool(stop);}protected virtual void OnDestroy(){Close();}public override void OnAssemble(ARSession session){base.OnAssemble(session);Open();}public void Open(){if (Application.platform ! RuntimePlatform.Android Application.platform ! RuntimePlatform.IPhonePlayer){throw new UIPopupException(typeof(CustomCameraSource) not available under Application.platform);}willOpen true;CameraDevice.requestPermissions(EasyARController.Scheduler, (ActionPermissionStatus, string)((status, msg) {if (!willOpen){return;}externalCamera new AndroidJavaObject(com.example.nativelib.ExternalCameraSample);externalCamera.Callbool(open);cameraCallback new CameraCallback(dataWrapper {if (sink null){return;}using (var param dataWrapper.GetAndroidJavaObject(camParams)){var byteArray dataWrapper.GetAndroidJavaObject(Buffer);var jniByteArray byteArray.GetRawObject();var buffer JniUtility.wrapByteArray(jniByteArray, true, () { byteArray.Dispose(); });var format PixelFormat.RGBA8888;//色彩格式int orientation 90;//旋转角度0~360int cameraType 1;//1为后摄像头2为前摄像头double timestamp param.Calllong(getTimestamp) * 1e-9;var imageWidth param.Callint(getWidth);var imageHeight param.Callint(getHeight);var imageSize new Vector2(imageWidth, imageHeight);HandleSink(buffer, format, imageSize, orientation, cameraType, timestamp);}});if (enabled){OnEnable();}}));}public void Close(){willOpen false;OnDisable();if (externalCamera ! null)externalCamera.Dispose();}private void HandleSink(Buffer imageBuffer, PixelFormat format, Vector2 imageSize, int orientation, int cameraType, double timestamp){using (var cameraParams CameraParameters.createWithDefaultIntrinsics(new Vec2I((int)imageSize.x, (int)imageSize.y), (CameraDeviceType)cameraType, orientation))using (var image new Image(imageBuffer, format, (int)imageSize.x, (int)imageSize.y))using (var frame InputFrame.createWithImageAndCameraParametersAndTemporal(image, cameraParams, timestamp)){if (sink ! null)sink.handle(frame);}imageBuffer.Dispose();}private AndroidJavaObject externalCamera;private CameraCallback cameraCallback;private class CameraCallback : AndroidJavaProxy{private ActionAndroidJavaObject onPreviewFrameCallback;public CameraCallback(ActionAndroidJavaObject onPreviewFrameCallback) : base(com.example.nativelib.ExternalCameraSample$Callback){this.onPreviewFrameCallback onPreviewFrameCallback;}public void onPreviewFrame(AndroidJavaObject dataWrapper){// NOTE: Workaround callback parameter not disposed in some Unity versions like 2022.2.// This looks like a bug in Unity because usually the caller is responsible for disposing the callback parameter.// And the behavior change is not compatible which will cause serious memory leak.using (dataWrapper) // workaround{onPreviewFrameCallback(dataWrapper);}}}}
}运行效果