Delphi Firemonkey TVideoCaptureDevice Live Stream From Client-Server-Client

  

I have been struggling to send/receive TVideoCaptureDevice Live Stream to Client-Server-Client. I am using TIdTCPServer and TIdTCPClient. When try to receive I am getting Connection closed Gracefully. How to overcome the Connection closed gracefully?
Below is my code:

Server

//for send

procedure TWebSocket.videoSendServerExecute(AContext: TIdContext);
var
fip: string;
ms: TMemoryStream;
cmd: string;
begin
cmd := AContext.Connection.IOHandler.ReadLn(IndyTextEncoding_UTF8);
if AContext.Connection.Connected then
begin
fip := cmd;//AContext.Connection.Socket.Binding.PeerIP;
fip := Copy(fip, Pos(‘:’, fip) + 1, Length(fip));
ms := vWebcamCollection.GetItem(vWebcamCollection.GetIndexByIP(fip)).StartedStream;
ms.Position := 0;
AContext.Connection.IOHandler.LargeStream := True;
AContext.Connection.IOHandler.ReadStream(ms);
AContext.Connection.IOHandler.WriteLn(‘DONE’, IndyTextEncoding_UTF8);
end;
end;

//for receive

procedure TWebSocket.videoReceiveServerExecute(AContext: TIdContext);
var
ms: TMemoryStream;
cmd, viewip: string;
begin
cmd := AContext.Connection.IOHandler.ReadLn;
viewip := cmd;
viewip := Copy(viewip, Pos(‘:’, viewip) + 1, Length(viewip));
ms := vWebcamCollection.GetItem(vWebcamCollection.GetIndexByIP(viewip)).StartedStream;
ms.Position := 0;
AContext.Connection.IOHandler.LargeStream := True;
AContext.Connection.IOHandler.Write(ms, 0, True);
AContext.Connection.IOHandler.WriteLn(‘DONE’, IndyTextEncoding_UTF8);
end;

Client

both timers interval is 500
//for sending stream in TTimer.OnTimer

procedure TfrmVideoForm.sendTimerTimer(Sender: TObject);
begin
sendTimer.Enabled := False;
TThread.Synchronize(TThread.CurrentThread, (
procedure
var
aIp: String;
ms: TMemoryStream;
begin
aIp := getLocalIPAddress;
aIp := Format(‘send:%s’, [aIp]);
videoClient.IOHandler.WriteLn(aIp, IndyTextEncoding_UTF8);
ms := TMemoryStream.Create;
videoClient.IOHandler.LargeStream := True;
imgVideo.Bitmap.SaveToStream(ms);
ms.Position := 0;
videoClient.IOHandler.Write(ms, 0, True);
videoClient.IOHandler.ReadLn(IndyTextEncoding_UTF8);
end));
sendTimer.Enabled := True;
end;

//for receiving stream – fIPAddress = which IPAddress Start TVideoCaptureDevice

procedure TfrmVideoForm.receiveTimerTimer(Sender: TObject);
begin
receiveTimer.Enabled := False;
TThread.Synchronize(TThread.CurrentThread, (
procedure
var
strm: TMemoryStream;
begin
videoRcvClient.IOHandler.WriteLn(‘receive:’ + fIPAddress,
IndyTextEncoding_UTF8);
strm := TMemoryStream.Create;
videoRcvClient.IOHandler.LargeStream := True;
videoRcvClient.IOHandler.ReadStream(strm);
videoRcvClient.IOHandler.ReadLn(IndyTextEncoding_UTF8);
strm.Position := 0;
imgVideo.Bitmap.LoadFromStream(strm);
strm.Free;
end));
receiveTimer.Enabled := True;
end;

code for server holding IPAdress

{ TWebcamItem }

TWebcamItem = class(TCollectionItem)
private
fStartedIP: string;
fStartedStream: TMemoryStream;
public
procedure Assign(Source: TPersistent); override;
constructor Create(ACollection: TCollection); override;
destructor Destroy; override;
property StartedIP: string read fStartedIP write fStartedIP;
property StartedStream: TMemoryStream read fStartedStream write fStartedStream;
procedure CreateStream;
procedure FreeStream;
end;

{ TWebcamCollection }

TWebcamCollection = class(TCollection)
private
function GetItem(Index: integer): TWebcamItem;
procedure SetItem(Index: integer; AValue: TWebcamItem);
public
constructor Create;
function Add: TWebcamItem;
property Items[Index: integer]: TWebcamItem read GetItem write SetItem; default;
function GetIndexByIP(AIP: string): integer;
end;

Comments are closed.