Create video streaming server in indy

房东的猫 提交于 2019-12-02 06:13:29

There are several errors in your server code.

You are not validating that a range is actually being requested, or even respecting an end range if one is present.

You are setting the AResponseInfo.ContentLength property to the full size of the file, even when you are not sending the full file at one time. That value belongs in the AResponseInfo.ContentRangeInstanceLength property instead when sending a ranged response. You must set ContentLength to the size of the data actually being sent in the response, which in this case is your current range chunk. It is best not to set the ContentLength at all, you can let the server calculate it for you based on the assigned ContentStream.

You are setting the AResponseInfo.ResponseNo property to 206 unconditionally, even if a range is not requested at all, or if the requested range cannot be satisfied. TIdHTTPRangeStream performs validations in its constructor and sets its ResponseCode property accordingly. That is the value you should be assigning to ResponseNo.

Try something more like this instead:

procedure TForm1.External_Get(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  FS: TFileStream;
  Range: TIdEntityRange;
  StartPos, EndPos: Int64;
begin
  if not FileExists('/home/user/Desktop/large_file.mp4') then
  begin
    AResponseInfo.ResponseNo := 404;
    Exit;
  end;

  try
    FS := TFileStream.Create('/home/user/Desktop/large_file.mp4', fmOpenRead or fmShareDenyWrite);
  except
    AResponseInfo.ResponseNo := 500;
    Exit;
  end;

  AResponseInfo.ContentType := 'video/mp4';
  AResponseInfo.AcceptRanges := 'bytes';

  if ARequestInfo.Ranges.Count = 1 then
  begin
    Range := ARequestInfo.Ranges.Ranges[0];

    StartPos := Range.StartPos;
    EndPos := Range.EndPos;

    if StartPos >= 0 then
    begin
      // requesting prefix range from BOF
      if EndPos >= 0 then
        EndPos := IndyMin(EndPos, StartPos + (1024*1024*10) - 1)
      else
        EndPos := StartPos + (1024*1024*10) - 1;
    end else
    begin
      // requesting suffix range from EOF
      if EndPos >= 0 then
        EndPos := IndyMin(EndPos, 1024*1024*10)
      else
        EndPos := (1024*1024*10);
    end;

    AResponseInfo.ContentStream := TIdHTTPRangeStream.Create(FS, StartPos, EndPos);
    AResponseInfo.ResponseNo := TIdHTTPRangeStream(AResponseInfo.ContentStream).ResponseCode;

    if AResponseInfo.ResponseNo = 206 then
    begin
      AResponseInfo.ContentRangeStart := TIdHTTPRangeStream(AResponseInfo.ContentStream).RangeStart;
      AResponseInfo.ContentRangeEnd := TIdHTTPRangeStream(AResponseInfo.ContentStream).RangeEnd;
      AResponseInfo.ContentRangeInstanceLength := FS.Size;
    end;
  end else
  begin
    AResponseInfo.ContentStream := FS;
    AResponseInfo.ResponseNo := 200;
  end;
end; 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!