Caynadian
Caynadian

Reputation: 779

Using Delphi 2007 and Indy TIdHTTP v10 get x bytes of data from a stream

I am trying to capture still images from various security cameras around our offices on a regular basis. I use the following code to do so:

Var
  MS: TMemoryStream;
  I: Integer;
Begin
  MS := TMemoryStream.Create;
  Try
    // Loop through however many channels the camera has (most have 1 but 180
    //  cams have 4).
    For I := 1 To FCamera.Channels Do
    Begin
      MS.Clear;
      Try
        // Use basic authentication only if a user name and password has been
        //  specified for access to the camera.
        FHTTP.Request.BasicAuthentication := False;
        If (FCamera.UserName <> '') Or (FCamera.Password <> '') Then
        Begin
          FHTTP.Request.Username := FCamera.UserName;
          FHTTP.Request.Password := FCamera.Password;
          FHTTP.Request.BasicAuthentication := True;
        End;
        FHTTP.Request.UserAgent := USERAGENT;
        // Get the image from the camera.
        FHTTP.Get(FCamera.BuildURL(I), MS);

This works fine for most of the cameras as they have URLs that you can go to to get a current still image. I have a few cameras though that will only give you an MJPEG stream and therefore, the FHTTP.Get never finishes as the stream is basically infinite. How could I do a HTTP GET and only get the first MB or so which I could then extract the first image from?

Upvotes: 1

Views: 886

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 597951

To answer your specific question:

How could I do a HTTP GET and only get the first MB or so

IF the web server supports the Range request header, you can use the TIdHTTP.Request.Range property to specify the desired range of bytes to retrieve, eg:

FHTTP.Request.Range := 'bytes; 0-1048575';
FHTTP.Get(FCamera.BuildURL(I), MS);

Support for byte ranges is indicated by the presence of an Accept-Ranges: bytes response header (see the TIdHTTP.Response.AcceptRanges property), such as on a HEAD request for the same resource that will be retrieved with a subsequent GET request.

However, if the web server does not support bytes ranges, and IF the web server is using a MIME-formatted server push to send the images, such as with the multipart/x-mixed-replace content type, then you can enable the hoNoReadMultipartMIME flag in the TIdHTTP.HTTPOptions property to tell TIdHTTP.Get() to exit when it reaches the beginning of the stream data, and then you can manually read from the TIdHTTP.IOHanlder directly and process the stream data as needed. There is a blog post on Indy's website about that topic:

New TIdHTTP hoNoReadMultipartMIME flag

Upvotes: 3

Related Questions