Camera_CustomCamera¶
演示如何使用非系统API的自定义摄像头创建一个EasyAR应用。
你可以参考这个sample,自己定制一个CameraDevice。这个sample使用系统API作为示例,不直接支持Android USB摄像头,如果需要应集成libuvc,可以参考 这个帖子 。
注:Windows USB摄像头有自带支持,不需要使用此示例。
注:使用视频流作为Camera也是可以的,你可以参考接口文档修改这个样例来实现。
用法¶
详解¶
使用自定义FrameSource¶
在场景中使用自定义相机设备,只需要使用自定义的FrameSource替换VideoCamera。将它放到ARSession节点下面,session将会自动使用它。
继承FrameSource¶
这个sample继承FrameSource来实现camera功能。Override Type/IsAvailable/OnEnable/OnDisable/OnAssemble 方法来让camera可以运行。
public override Optional<InputFrameSourceType> Type { get => InputFrameSourceType.General; }
public override Optional<bool> IsAvailable { get => Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer; }
protected override void OnEnable()
{
base.OnEnable();
#if !UNITY_EDITOR && UNITY_ANDROID
if (externalCamera != null)
externalCamera.Call<bool>("start", cameraCallback);
#elif !UNITY_EDITOR && UNITY_IOS
if (externalCamera != null)
externalCamera.start(cameraCallback);
#endif
}
protected override void OnDisable()
{
base.OnDisable();
#if !UNITY_EDITOR && UNITY_ANDROID
if (externalCamera != null)
externalCamera.Call<bool>("stop");
#elif !UNITY_EDITOR && UNITY_IOS
if (externalCamera != null)
externalCamera.stop();
#endif
}
protected virtual void OnDestroy()
{
Close();
}
public override void OnAssemble(ARSession session)
{
base.OnAssemble(session);
Open();
}
public void Open()
{
}
public void Close()
{
}
原生camera实现¶
这个sample使用原生camera代码来提供camera功能。不同平台的代码位于不同的地方。
Android实现在sample的 AndroidProject~
文件夹内的Gradle工程中,它的输出被预先编译成custom-camera.jar并存在于sample的 Runtime/Android
文件夹中。 AndroidProject~
在Unity编辑器中不会显示,可以在文件系统上直接查看。
iOS实现在sample的 Runtime/iOS
文件夹的MyCamera文件中。
使用原生代码实现camera设备可以使用系统camera提供最大的灵活性。你可以修改这些代码来让没有被集成到EasyAR VideoCameraDevice中的系统相机的功能工作。
暴露原生相机接口到C#¶
sample中有一部分代码用来将原生接口包装成C#接口以便在C#中访问。这些代码会直接调用Java或C接口。
private AndroidJavaObject externalCamera;
private CameraCallback cameraCallback;
private class CameraCallback : AndroidJavaProxy
{
}
private ExternalCamera externalCamera;
private Action<IntPtr, int> cameraCallback;
private class ExternalCamera : IDisposable
{
}
在相机回调中处理InputFrame¶
sample中Android 和 iOS 的实现都将camera的回调暴露到了C#。在回调中, InputFrameSink.handle 用来处理从原始图像数据创建的InputFrame。
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();
}