将实时镜头从相机流式传输到Unity3D

时间:2016-09-14 16:02:00

标签: c# unity3d camera video-streaming

假设我有一台无线摄像头,我想将视频从实时流式传输到统一。有没有办法实现这个目标?

奖金问题:

  • 角度较大的相机(180,甚至360)
  • 如果这是我希望与
  • 交互的素材,延迟会有多大问题
  • 除了常规镜头外,还可以发送更多数据,例如深度感知(使用深度感知相机)吗?
  • 我疯了还是这样做了?

提前致谢

1 个答案:

答案 0 :(得分:5)

我认为这是一台带有以太网端口或Wi-Fi的摄像头,您可以连接到该摄像头并实时流式传输图像。

如果是,那么是的,它可以用Unity完成。

没有外部库如何完成

连接相机

1 。使用相机连接到同一本地网络,或者如果支持unpn,您也可以通过互联网连接到它。通常,您需要相机的IP和端口才能执行此操作。我们假设摄像机IP地址为192.168.1.5,端口号为900。要连接的网址是http://192.168.1.5:900

有时,它只是一个以 .mjpg .bin 结尾的网址,例如http://192.168.1.5/mjpg/video.mjpghttp://192.168.1.5/mjpg/video.bin

每台相机都不同。找到网址的唯一方法是阅读其手册。如果手册不可用,请使用其官方应用程序连接到该手册,然后使用Wireshark发现相机Image的URL。 usernamepassword(如果需要)也可以在手册中找到。如果没有,请在Google上输入型号,找到您需要的所有内容。

从相机中提取JPEG

连接相机时,相机会向您发送无尽的数据。您可以通过此数据扫描并从中检索图像。

2 。搜索0xFF后跟0xD8的JPEG标头。如果这两个字节彼此相邻,则开始读取字节并继续将它们保存到数组中。您可以使用索引(int)变量来计算已接收的字节数。

int counter = 0;
byte[] completeImageByte = new byte[500000];
byte[] receivedBytes = new byte[500000];
receivedBytes[counter] = byteFromCamera;
counter++;

3 。从相机读取数据时,检查接下来的两个字节是否为0xFF后跟0xD9的JPEG页脚。如果这是真的,那么您已收到完整的图像(1帧)。

您的图片字节应如下所示:

0xFF 0xD8 someotherbytes(数千条).....然后0xFF 0xD9

receivedBytes复制到completeImageByte变量,以便以后可以用它来显示图像。将counter变量重置为0.

Buffer.BlockCopy(receivedBytes, 0, completeImageByte, 0, counter);
counter = 0;

将JPEG图像显示到屏幕

4 。显示图像到屏幕

由于您每秒会收到许多图片,因此我发现显示此RawImage的最多方法是使用Image组件。因此,如果您希望在移动设备上运行,请不要使用Sprite Rendererpublic RawImage screenDisplay; if(updateFrame){ Texture2D camTexture = new Texture2D(2, 2); camTexture.LoadImage(completeImageByte); screenDisplay.texture = camTexture; }

camTexture = new Texture2D(2, 2);

您只需在Start()功能中执行UnityWebRequest次。

5 。回到步骤 2 并继续这样做,直到你想要完全。

用于连接相机的API:

如果相机需要验证(用户名和密码),请使用efficient

对于不需要身份验证的用户,请使用HttpWebRequest。使用DownloadHandlerScript时,您必须从UnityWebRequest派生自己的类,否则您的应用会崩溃,因为您将不停地接收数据。

using UnityEngine; using System.Collections; using UnityEngine.Networking; public class CustomWebRequest : DownloadHandlerScript { // Standard scripted download handler - will allocate memory on each ReceiveData callback public CustomWebRequest() : base() { } // Pre-allocated scripted download handler // Will reuse the supplied byte array to deliver data. // Eliminates memory allocation. public CustomWebRequest(byte[] buffer) : base(buffer) { } // Required by DownloadHandler base class. Called when you address the 'bytes' property. protected override byte[] GetData() { return null; } // Called once per frame when data has been received from the network. protected override bool ReceiveData(byte[] byteFromCamera, int dataLength) { if (byteFromCamera == null || byteFromCamera.Length < 1) { //Debug.Log("CustomWebRequest :: ReceiveData - received a null/empty buffer"); return false; } //Search of JPEG Image here return true; } // Called when all data has been received from the server and delivered via ReceiveData protected override void CompleteContent() { //Debug.Log("CustomWebRequest :: CompleteContent - DOWNLOAD COMPLETE!"); } // Called when a Content-Length header is received from the server. protected override void ReceiveContentLength(int contentLength) { //Debug.Log(string.Format("CustomWebRequest :: ReceiveContentLength - length {0}", contentLength)); } } 派生自己的类的示例:

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class Test : MonoBehaviour
{

    CustomWebRequest camImage;
    UnityWebRequest webRequest;
    byte[] bytes = new byte[90000];

    void Start()
    {
        string url = "http://camUrl/mjpg/video.mjpg";
        webRequest = new UnityWebRequest(url);
        webRequest.downloadHandler = new CustomWebRequest(bytes);
        webRequest.Send();
    }
}

<强>用法

ReceiveData

您可以在CustomWebRequest中执行步骤 2 3 4 5 来自http://192.168.1.5?pan=50&rotate=90脚本的函数。

控制相机

相机具有平移,旋转,翻转,镜像和执行其他功能的命令。这在每个相机中都有所不同,但它很简单,因为对相机的网址发出GET / POST请求并提供查询。这些命令可在相机手册中找到。

例如:select e.*, sum(travel_time) over (partition by dispatch_number, session_date) as total_drivetime from exampleDB;

其他框架

DownloadHandlerScript - 一个可以从相机处理AForgeJPEG/MJPES的免费框架。您必须修改它以与Unity一起使用,如果您不能执行 2 3 4 5