[英]Streaming live footage from camera to Unity3D
假設我有一個無線攝像頭,我想實時地將素材傳輸成一體。 有沒有辦法做到這一點?
獎勵問題:
提前致謝
我假設這是一台具有以太網端口或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.mjpg
和http://192.168.1.5/mjpg/video.bin
每個相機都不一樣。 查找網址的唯一方法是閱讀其手冊。 如果該手冊不可用,請使用其官方應用程序連接至該手冊,然后使用Wireshark查找攝像機圖像的URL。 username
和password
(如果需要)也可以在手冊中找到。 如果不可用,請在google上找到型號和所需的一切。
從相機中提取JPEG :
連接到相機后,相機將向您發送無盡的數據。 您可以掃描這些數據並從中檢索圖像。
2。搜索JPEG標頭,該標頭是0xFF
后跟0xD8
。 如果這兩個字節彼此相鄰,則開始讀取字節並將其繼續保存到數組中。 您可以使用index( int
)變量來計數接收到的字節數。
int counter = 0;
byte[] completeImageByte = new byte[500000];
byte[] receivedBytes = new byte[500000];
receivedBytes[counter] = byteFromCamera;
counter++;
3.從相機讀取數據時,請檢查接下來的兩個字節是否為JPEG頁腳( 0xFF
后跟0xD9
。 如果是這樣,則您已收到完整的圖像(1幀)。
您的圖像字節應類似於:
0xFF
0xD8
(其中數千個).....然后0xFF
0xD9
復制receivedBytes
到completeImageByte
變量,以便它可用於稍后上顯示圖像。 將counter
變量重置為0。
Buffer.BlockCopy(receivedBytes, 0, completeImageByte, 0, counter);
counter = 0;
在屏幕上顯示JPEG圖像 :
4。顯示圖像到屏幕
由於您每秒將收到許多圖像,因此我發現顯示此圖像的最有效方法是使用RawImage
Component。 因此,如果您希望它在移動設備上運行,請不要使用Image
或Sprite Renderer
。
public RawImage screenDisplay;
if(updateFrame){
Texture2D camTexture = new Texture2D(2, 2);
camTexture.LoadImage(completeImageByte);
screenDisplay.texture = camTexture;
}
您只需要執行camTexture = new Texture2D(2, 2);
一次在Start()
函數中。
5。跳回到步驟2並繼續進行操作,直到您想要這樣做為止。
用於連接相機的API : 。
如果攝像機需要身份驗證(用戶名和密碼),請使用HttpWebRequest
。
對於不需要身份驗證的用戶,請使用UnityWebRequest
。 使用UnityWebRequest
,您必須從DownloadHandlerScript
派生您自己的類,否則您的應用程序將崩潰,因為您將不停地接收數據。
從DownloadHandlerScript
派生自己的類的示例:
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();
}
}
可以將它們執行步驟2,3,4和5中的ReceiveData
從功能CustomWebRequest
腳本。
控制相機 :
攝像頭具有平移,旋轉,翻轉,鏡像和執行其他功能的命令,這在每個攝像頭中都不同,但是很簡單,只需向攝像頭的url發出GET / POST請求並提供查詢即可。 這些命令可以在相機手冊中找到。
例如: http://192.168.1.5?pan=50&rotate=90
: http://192.168.1.5?pan=50&rotate=90
其他框架 :
AForge-一個免費的框架,可以處理來自相機的JPEG / MJPES和FFMPEG 。 你必須修改它與團結的工作,你應該,如果你不能做第2步,3,4和5。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.