streaming - parsing multipart requests

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By am1r_5h

Hi,

I am new to Godot, and have trouble with stream reading. Would be nice if you can help with your suggestions how to solve the delay issue, or hint what’s the best way to do stream reading, or forward me to docs already exists in this regard. Any helps is appreciated and many thanks in advance.

I have a server listening and exposing camera images (as jpeg) through an http request. the request has the content-type header “multipart/x-mixed-replace;boundary=–boundarydonotcross” - meaning it keeps the connection open to stream the camera images. By continuously reading and showing the images, the goal is to have just an element in the scene make us able to watch what’s going on the camera.

I did some test with HTTPClient, but it has lots of delay. Under a Node 2D as a root, I have have a TextureRect, which through code (in C#) I try to regularly set its texture (I’m not sure if I’m using the appropriate nodes for this purpose).

At first I’m preparing the connection in _Ready and try to read images in _Process:

public class TextureRect2 : Godot.TextureRect
{
 HTTPClient http = null;
    
public override void _Ready()
{
    string host = "192.168.1.9";

    Error err;
    http = new HTTPClient();
    err = http.ConnectToHost(host, 8887);
    Debug.Assert(err == Error.Ok); // Make sure the connection is OK.

    while (http.GetStatus() == HTTPClient.Status.Connecting || http.GetStatus() == HTTPClient.Status.Resolving)
    {
        // Connecting...

        http.Poll();
        OS.DelayMsec(500);
    }

    Debug.Assert(http.GetStatus() == HTTPClient.Status.Connected);

    http.Request(HTTPClient.Method.Get, "/video", null);
    Debug.Assert(err == Error.Ok); // Make sure all is OK.

    while (http.GetStatus() == HTTPClient.Status.Requesting)
    {
        // Requesting...

        http.Poll();
        OS.DelayMsec(500);
    }

    Debug.Assert(http.GetStatus() == HTTPClient.Status.Body || http.GetStatus() == HTTPClient.Status.Connected); // Make sure the request finished well.
}

public override void _Process(float delta)
{
    if (http.HasResponse())
    {
        if (http.GetStatus() == HTTPClient.Status.Body)
        {
            var image = new Image();
            
            var buf = http.ReadResponseBodyChunk();
            var error = image.LoadJpgFromBuffer(buf);
            if (error != Error.Ok)
                GD.PushError("Couldn't load the image.");

            var texture = new ImageTexture();
            texture.CreateFromImage(image);

            this.Texture = texture;

            http.Poll();
        }
    }
}
}

Thank you so much.