Unity使用NatML的NatDevice功能调用外部摄像机
NatCam
最开始在Unity中使用WebCamTexture
获取外部摄像机的画面。后来发现WebCamTexture
的功能过于简单,外部摄像机的很多深层效果无法实现。故使用了插件NatCam,但现在此插件已经下架,上架了全新版本,可发布全平台名称NatDevice。
该文章就将NatDevice的下载和使用,做一个简单的介绍记录。其中大部分都来自官网和GitHub:
NatDevice
适用于Unity引擎的高性能、跨平台媒体设备流传输。
NatDevice是一个跨平台的媒体设备API,它简化了您的摄像头和麦克风工作流程。首先,创建一个媒体设备:
- 摄像机
// Create a device query for a camera device
var filter = MediaDeviceCriteria.CameraDevice;
var query = new MediaDeviceQuery(filter);
// Get the camera device
var device = query.current as CameraDevice;
- 麦克风
// Create a device query for a microphone device
var filter = MediaDeviceCriteria.AudioDevice;
var query = new MediaDeviceQuery(filter);
// Get the microphone device
var device = query.current as AudioDevice;
然后从设备获取流媒体数据:
- 摄像机
// Start streaming camera images
device.StartRunning(OnCameraImage);
void OnCameraImage (CameraImage cameraImage)
{
// Do stuff
...
}
- 麦克风
// Start streaming audio sample buffers
device.StartRunning(OnAudioBuffer);
void OnAudioBuffer (AudioBuffer audioBuffer)
{
// Do stuff
...
}
广泛和轻量级
NatDevice是一个轻量级API,为使用媒体设备提供了广泛的功能。功能包括:
- 流摄像头预览和麦克风音频与非常小的延迟。
- 支持高分辨率相机预览,在全高清和更高的支持。
- 支持指定麦克风采样率和通道计数。
- 广泛的相机控制,包括高分辨率照片捕捉,闪光灯,对焦,手动曝光,白平衡,手电筒,变焦和方向支持。
- 广泛的元数据,包括曝光偏差,曝光持续时间,ISO,焦距等。
- 支持卡拉ok和语音通话应用程序的回音消除麦克风。
- 与NatML集成,实现低延迟、高性能。
在Unity中使用NatDevice
导入NatDevice
首先,用Unity包管理器(Package Manag)导入API,方法是将下面的设置添加到项目的Packages/manifest.json文件中:
{
"scopedRegistries": [
{
"name": "NatML",
"url": "https://registry.npmjs.com",
"scopes": ["ai.natml"]
}
],
"dependencies": {
"ai.natml.natdevice": "1.2.3"
}
}
这里因为我使用的Unity版本(2020.3.5)的原因,所以我是用的插件是1.2.3版本,可在下图中插件GitHub的界面选择自己所需的版本下载使用:
指定访问密钥
为了使用NatDevice,您需要一个NatML访问密钥,以及有效的云计划订阅从NatML中心检索访问权限:https://hub.natml.ai/profile。
这里注册使用的方式做简单的介绍:
- 点击上面的链接;
- 在弹出的网页中输入所需的邮箱地址;
- 登录邮箱,找到收到的邮件,点击下图中的Log in to NatML按钮;
- 刷新https://hub.natml.ai/profile页面,就会出现Access Key。
获得访问密钥后,将其添加到Project Settings -> NatML中:
使用NatDevice需要一个活动的NatML MediaKit订阅。你可以免费试用,但功能有限。请参阅常见问题解答。
运行摄像头预览
现在我们全部设置好了,让我们编写一个最小的示例来显示相机预览。
using NatML.Devices;
using NatML.Devices.Outputs;
using System;
using UnityEngine;
using UnityEngine.UI;
public class HelloCam : MonoBehaviour
{
[Header(@"UI")]
public RawImage rawImage;
public AspectRatioFitter aspectFitter;
async void Start()
{
//为后置摄像头创建一个设备查询
Predicate<IMediaDevice> filter = MediaDeviceCriteria.RearCamera;
为前置摄像头创建一个设备查询
//Predicate<IMediaDevice> filter = MediaDeviceCriteria.FrontCamera;
MediaDeviceQuery query = new MediaDeviceQuery(filter);
//推进下一个满足提供条件的可用设备
query.Advance();
//获取摄像设备
CameraDevice device = query.current as CameraDevice;
//device.exposureBias = value;//曝光调节
//device.zoomRatio = value;//焦距调节
//device.torchMode = CameraDevice.TorchMode.Maximum;//CameraDevice.TorchMode.Off;//手电筒
//开始预览相机
TextureOutput textureOutput = new TextureOutput();//请耐心等待解释
device.StartRunning(textureOutput);
//在我们的UI中显示预览
Texture2D previewTexture = await textureOutput;
rawImage.texture = previewTexture;
aspectFitter.aspectRatio = (float)previewTexture.width / previewTexture.height;
}
}
现在,让我们来设置UI。我们将使用RawImage
来显示相机预览到屏幕上。我们还将添加一个AspectRatioFitter
,以便预览显示看起来不会被拉伸。
现在,让我们在我们的场景中设置HelloCam。我们将创建一个空的游戏对象并添加脚本。然后,分配 我们上面创建的RawImage
和AspectRatioFitter
。
现在可以打包运行测试了。
示例测试结果
经过测试,出了画面有一定的延迟,没有其他毛病。
延迟的问题可能是,测试的手机本身性能的问题。
文章如有遗漏错误,欢迎指正。