使用Delphi 2007和Indy TIdHTTP v10从流中获取x个字节的数据

时间:2015-04-13 15:54:37

标签: delphi http indy

我试图定期从我们办公室周围的各种安全摄像头拍摄静止图像。我使用以下代码来执行此操作:

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);

这适用于大多数相机,因为它们具有您可以去获取当前静止图像的URL。我有一些相机,但只会给你一个MJPEG流,因此,FHTTP.Get永远不会完成,因为流基本上是无限的。我怎么能进行HTTP GET并且只获得第一个MB左右,然后我可以从中提取第一个图像?

1 个答案:

答案 0 :(得分:3)

回答您的具体问题:

  

我怎么能进行HTTP GET并且只得到第一个MB左右

IF Web服务器支持Range请求标头,您可以使用TIdHTTP.Request.Range属性指定要检索的所需字节范围,例如:

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

支持字节范围由Accept-Ranges: bytes响应头(参见TIdHTTP.Response.AcceptRanges属性)的存在表示,例如对{1}}请求的同一资源将被检索随后的HEAD请求。

但是,如果Web服务器不支持字节范围,并且 IF ,则Web服务器使用MIME格式的server push来发送图像,例如{{3 }}内容类型,然后您可以在GET属性中启用hoNoReadMultipartMIME标志,以告知TIdHTTP.HTTPOptions在到达流数据的开头时退出,然后您可以手动读取直接TIdHTTP.Get()并根据需要处理流数据。 Indy的网站上有一篇关于该主题的博客文章:

multipart/x-mixed-replace