using UnityEngine; using System.Collections; using System; using System.Net; using System.IO; using UnityEngine.UI; //SOURCE //https://answers.unity.com/questions/1151512/show-video-from-ip-camera-source.html public class WebStream : MonoBehaviour { public RawImage image; //Mesh for displaying video public string sourceURL = "http://192.168.86.38:10000"; public float fps { get { return _fps; } } [SerializeField] [Tooltip("Show FPS streaming performance")] private float _fps; private Texture2D texture; private Stream stream; private System.Diagnostics.Stopwatch fpsStopwatch = new System.Diagnostics.Stopwatch(); //--------------------------------------------------------------------------- private void Start() { Debug.Log(">> Start()"); System.Diagnostics.Stopwatch cronometro = new System.Diagnostics.Stopwatch(); cronometro.Start(); GetVideo(); cronometro.Stop(); Debug.Log($"<< Start() {cronometro.ElapsedMilliseconds}"); } //--------------------------------------------------------------------------- public void GetVideo() { Debug.Log(">> startCoroutine(GetFrame())"); System.Diagnostics.Stopwatch cronometro = new System.Diagnostics.Stopwatch(); cronometro.Start(); StartCoroutine(GetFrame()); cronometro.Stop(); Debug.Log($"<< startCoroutine(GetFrame()) {cronometro.ElapsedMilliseconds}"); } //--------------------------------------------------------------------------- private void Connection() { texture = new Texture2D(2, 2); // create HTTP request Debug.Log($"Connecting {sourceURL}"); HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sourceURL); //Optional (if authorization is Digest) //req.Credentials = new NetworkCredential("username", "password"); // get response WebResponse resp = req.GetResponse(); // get response stream stream = resp.GetResponseStream(); } //--------------------------------------------------------------------------- // MAIN CORUTINE // TODO: Poner un sleep (o equivalente) en el While? IEnumerator GetFrame() { yield return new WaitForSeconds(UnityEngine.Random.Range(0.1f,0.5f)); Connection(); //TARDA 2000 ms Byte[] JpegData = new Byte[65536]; while (true) { int bytesToRead = FindLength(stream); if (bytesToRead == -1) { Debug.Log("End of stream"); yield break; } int leftToRead = bytesToRead; while (leftToRead > 0) { leftToRead -= stream.Read(JpegData, bytesToRead - leftToRead, leftToRead); yield return null; } MemoryStream ms = new MemoryStream(JpegData, 0, bytesToRead, false, true); texture.LoadImage(ms.GetBuffer()); //image.material.mainTexture = texture; image.texture = texture; stream.ReadByte(); // CR after bytes stream.ReadByte(); // LF after bytes if (fpsStopwatch.IsRunning) _fps = Convert.ToSingle(1.0 / fpsStopwatch.Elapsed.TotalSeconds); fpsStopwatch.Restart(); } } //--------------------------------------------------------------------------- int FindLength(Stream stream) { int b; string line = ""; int result = -1; bool atEOL = false; while ((b = stream.ReadByte()) != -1) { if (b == 10) continue; // ignore LF char if (b == 13) { // CR if (atEOL) { // two blank lines means end of header stream.ReadByte(); // eat last LF return result; } if (line.StartsWith("Content-Length:")) { result = Convert.ToInt32(line.Substring("Content-Length:".Length).Trim()); } else { line = ""; } atEOL = true; } else { atEOL = false; line += (char)b; } } return -1; } }