Supposons que je dispose d’une caméra sans fil que je souhaite diffuser en continu, en temps réel, des séquences vidéo à l’unité. Y a-t-il un moyen d’y parvenir?
Questions bonus:
Merci d’avance
Je suppose que c’est une caméra avec port Ethernet ou Wi-Fi à laquelle vous pouvez vous connecter et diffuser des images en direct.
Si oui, alors oui, cela peut être fait avec Unity.
Comment cela se fait sans une bibliothèque externe :
Connexion à la caméra :
1 .Connectez-vous au même réseau local avec la caméra ou si le protocole unpn est pris en charge, vous pouvez également vous connecter via Internet. Pour ce faire, vous avez généralement besoin de l’adresse IP et du port de la caméra. Supposons que l’adresse IP de la caméra est 192.168.1.5
et le numéro de port est 900
. L’URL à laquelle se connecter est http://192.168.1.5:900
.
Parfois, il s’agit simplement d’une URL se terminant par .mjpg ou .bin, telle que http://192.168.1.5/mjpg/video.mjpg
et http://192.168.1.5/mjpg/video.bin
Chaque caméra est différente. La seule façon de trouver l’URL est de lire son manuel. Si le manuel n’est pas disponible, connectez-le avec son application officielle, puis utilisez Wireshark pour découvrir l’URL de la caméra Image. Le username
et le password
(si nécessaire) sont également disponibles dans le manuel. Si non disponible, google le numéro de modèle et tout ce dont vous avez besoin devrait être trouvé.
Extraire le JPEG de la caméra :
Une fois connecté à l’appareil photo, celui-ci vous enverra une infinité de données. Ces données, vous pouvez numériser et récupérer l’image à partir d’elle.
2. Recherchez l’en-tête JPEG qui est 0xFF
suivi de 0xD8
. Si ces deux octets sont côte à côte, commencez à les lire et continuez de les enregistrer dans un tableau. Vous pouvez utiliser une variable d’index ( int
) pour conserver le nombre d’octets que vous avez reçus.
int counter = 0; byte[] completeImageByte = new byte[500000]; byte[] receivedBytes = new byte[500000]; receivedBytes[counter] = byteFromCamera; counter++;
3. Pendant la lecture des données de la caméra, vérifiez si les deux octets suivants sont le pied de page JPEG, 0xFF
suivi de 0xD9
. Si cela est vrai, alors vous avez reçu l’image complète (1 image).
Vos octets d’image doivent ressembler à quelque chose comme:
0xFF
0xD8
octets (en milliers) ….. puis 0xFF
0xD9
Copiez receivedBytes
dans la variable completeImageByte
afin qu’elle puisse être utilisée pour afficher l’image ultérieurement. Remettre la variable de counter
à 0.
Buffer.BlockCopy(receivedBytes, 0, completeImageByte, 0, counter); counter = 0;
Affichage de l’image JPEG à l’écran :
4. Afficher l’image à l’écran
Etant donné que vous recevrez plusieurs images par seconde, le moyen le plus efficace d’afficher ceci est d’utiliser le composant RawImage
. Donc, n’utilisez pas Image
ou Sprite Renderer
pour cela si vous voulez que cela fonctionne sur des appareils mobiles.
public RawImage screenDisplay; if(updateFrame){ Texture2D camTexture = new Texture2D(2, 2); camTexture.LoadImage(completeImageByte); screenDisplay.texture = camTexture; }
Il suffit de faire camTexture = new Texture2D(2, 2);
une fois dans la fonction Start()
.
5. Revenez à l’étape 2 et continuez jusqu’à ce que vous souhaitiez tout à fait.
API pour la connexion à la caméra:.
Utilisez HttpWebRequest
si la caméra nécessite une authentification (nom d’utilisateur et mot de passe).
Pour ceux qui ne nécessitent pas d’authentification, utilisez UnityWebRequest
. Lorsque vous utilisez UnityWebRequest
, vous devez UnityWebRequest
vos propres classes à partir de DownloadHandlerScript
, UnityWebRequest
votre application se bloquera lorsque vous recevrez des données sans interruption.
Exemple de dérivation de votre propre classe à partir de 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)); } }
Utilisation :
using UnityEngine; using System.Collections; using UnityEngine.Networking; public class Test : MonoBehaviour { CustomWebRequest camImage; UnityWebRequest webRequest; byte[] bytes = new byte[90000]; void Start() { ssortingng url = "http://camUrl/mjpg/video.mjpg"; webRequest = new UnityWebRequest(url); webRequest.downloadHandler = new CustomWebRequest(bytes); webRequest.Send(); } }
Vous pouvez les exécuter aux étapes 2 , 3 , 4 et 5 dans la fonction ReceiveData
partir du script CustomWebRequest
.
Caméra de contrôle :
Les caméras ont des commandes pour effectuer un panoramique, une rotation, un retournement, un miroir et une autre fonction. C’est différent dans chaque caméra, mais il est simple de faire une demande GET / POST à une URL de la caméra et de fournir les requêtes. Ces commandes peuvent être trouvées dans le manuel de l'appareil photo.
Par exemple: http://192.168.1.5?pan=50&rotate=90
Autres frameworks :
AForge - Un cadre libre capable de gérer les formats JPEG / MJPES et FFMPEG à partir de l'appareil photo. Vous devez le modifier pour fonctionner avec Unity et vous devriez le faire si vous ne pouvez pas effectuer les étapes 2 , 3 , 4 et 5 .