How to download streamed images with MultipartReader?

Andrew Syrov 46 Reputation points
2021-09-29T23:34:25.673+00:00

I have a web service that sends an endless stream of images with multipart content type and need to write client code that would save (image by image the response). For reference, this service is implemented as python (but I'm using C# on the client). Here is the relevant python code:

python
self.set_header("Content-type",
                        "multipart/x-mixed-replace;boundary=--boundarydonotcross")

        served_image_timestamp = time.time()
        my_boundary = "--boundarydonotcross\n"
        while True:

            interval = .01
            if served_image_timestamp + interval < time.time() and \
                    hasattr(self.application, 'img_arr'):

                img = utils.arr_to_binary(self.application.img_arr)
                self.write(my_boundary)
                self.write("Content-type: image/jpeg\r\n")
                self.write("Content-length: %s\r\n\r\n" % len(img))
                self.write(img)
                served_image_timestamp = time.time()
                try:
                    await self.flush()
                except tornado.iostream.StreamClosedError:
                    pass
            else:
                await tornado.gen.sleep(interval)

The stream displays with no issues in a web browser, but I cannot make it work in c# (the only way to make it work is to read one image, then send a new request, and so on). Here is the code that I'm using currently to download image by image as separate requests:

csharp
            ...
            var boundary = "boundarydonotcross";
            using (var client = new HttpClient())
            {

                var uri = new Uri("http://.../video");
                while (imgId < count)
                {
                    var res = await client.GetStreamAsync(uri);
                    var mp = new MultipartReader(boundary, res);
                    var sec = await mp.ReadNextSectionAsync();
                    var length = int.Parse(sec.Headers["Content-length"]);
                    var data = await sec.Body.ReadBytesAsync(length);
                    SaveImage(data, imgId++);
                }
            }

My attempts to do consecutive ReadNextSectionAsync() requests on the same stream are not successful. They just hang in DrainAsync.

Can anyone point me to the code with a successful example of similar functionality or handling such an eternal stream of images (or advice on how to change my code)?

Thank you very much

ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,288 questions
.NET Runtime
.NET Runtime
.NET: Microsoft Technologies based on the .NET software framework.Runtime: An environment required to run apps that aren't compiled to machine language.
1,126 questions
0 comments No comments
{count} votes