是这样,想做个双方视频的功能,可惜不懂idTCPserver的具体使用,现在贴出发送视频的单元,是用clientsocket发送的,想请大家帮我转成用idTCPserver发送的。基本的流程我都放在下面了,这个是clientsocket发送,然后idTCPserver接收。大家帮我改成idTCPserver发送,clientsocket接收的就行了。{视频单元}
unit UnitWebcam;interfaceuses
Windows,
Sysutils,
Messages,
Classes,
Graphics,
jpeg,
SocketUnit;const
WM_CAP_START = $0400;
WM_CAP_DRIVER_CONNECT = $0400 + 10;
WM_CAP_DRIVER_DISCONNECT = $0400 + 11;
WM_CAP_EDIT_COPY = WM_CAP_START + $1E;
WM_CAP_SAVEDIB = $0400 + 25;
WM_CAP_GRAB_FRAME = $0400 + 60;
WM_CAP_STOP = $0400 + 68;
ENTER = #10;type
TMyWebcam = class
private
FWcamStream: TMemoryStream;
FBmp: TBitmap;
FJpg: TjpegImage;
//
FSocket: TClientSocket;
FHost: string;
FPort: Integer;
FSH: string;
//
function SendData: Boolean;
public
constructor Create(SH, sHost: string; nPort: Integer); reintroduce;
destructor Destroy; override;
function Connect: Boolean;
function GetWebcam(NumeroDeWebcam, NivelCompresion: Integer): Boolean;
function Connected: Boolean;
end;var
CaptureWindow: dword;function capCreateCaptureWindowA(lpszWindowName: pchar; dwStyle: dword; x, y, nWidth, nHeight: word; ParentWin: dword; nId: word): dword; stdcall external 'AVICAP32.DLL';
function capGetDriverDescriptionA(wDriverIndex: UINT; lpszName: LPSTR; cbName: integer; lpszVer: LPSTR; cbVer: integer): BOOL; stdcall; external 'AVICAP32.DLL';function ListarDispositivos(): String;implementationfunction ListarDispositivos(): String;
var
szName,
szVersion: array[0..MAX_PATH] of char;
iReturn: Boolean;
x: integer;
begin
x := 0;
repeat
iReturn := capGetDriverDescriptionA(x, @szName, sizeof(szName), @szVersion, sizeof(szVersion));
If iReturn then
begin
Result := Result + szName + ' - ' + szVersion + '|';
Inc(x);
end;
until iReturn = False;
end;Function SaveBitmapToStream(Stream: TMemoryStream; HBM: HBitmap): Integer;
Const
BMType = $4D42;
Type
TBitmap = Record
BMType: Integer;
bmWidth: Integer;
bmHeight: Integer;
bmWidthBytes: Integer;
bmPlanes: byte;
bmBitsPixel: byte;
bmBits: Pointer;
End;
Var
BM: TBitmap;
BFH: TBitmapFileHeader;
BIP: PBitmapInfo;
DC: HDC;
HMem: THandle;
Buf: Pointer;
ColorSize, DataSize: Longint;
BitCount: word; Function AlignDouble(Size: Longint): Longint;
Begin
Result := (Size + 31) Div 32 * 4;
End;Begin
Result := 0;
If GetObject(HBM, SizeOf(TBitmap), @BM) = 0 Then Exit;
BitCount := 32;
If (BitCount <> 24) Then
ColorSize := SizeOf(TRGBQuad) * (1 Shl BitCount)
Else
ColorSize := 0;
DataSize := AlignDouble(BM.bmWidth * BitCount) * BM.bmHeight;
GetMem(BIP, SizeOf(TBitmapInfoHeader) + ColorSize);
If BIP <> Nil Then
Begin
With BIP^.bmiHeader Do
Begin
biSize := SizeOf(TBitmapInfoHeader);
biWidth := BM.bmWidth;
biHeight := BM.bmHeight;
biPlanes := 1;
biBitCount := BitCount;
biCompression := 0;
biSizeImage := DataSize;
biXPelsPerMeter := 0;
biYPelsPerMeter := 0;
biClrUsed := 0;
biClrImportant := 0;
End;
With BFH Do
Begin
bfOffBits := SizeOf(BFH) + SizeOf(TBitmapInfo) + ColorSize;
bfReserved1 := 0;
bfReserved2 := 0;
bfSize := Longint(bfOffBits) + DataSize;
bfType := BMType;
End;
HMem := GlobalAlloc(gmem_Fixed, DataSize);
If HMem <> 0 Then
Begin
Buf := GlobalLock(HMem);
DC := GetDC(0);
If GetDIBits(DC, HBM, 0, BM.bmHeight,
Buf, BIP^, dib_RGB_Colors) <> 0 Then
Begin
Stream.WriteBuffer(BFH, SizeOf(BFH));
Stream.WriteBuffer(pchar(BIP)^, SizeOf(TBitmapInfo) + ColorSize);
Stream.WriteBuffer(Buf^, DataSize);
Result := 1;
End;
ReleaseDC(0, DC);
GlobalUnlock(HMem);
GlobalFree(HMem);
End;
End;
FreeMem(BIP, SizeOf(TBitmapInfoHeader) + ColorSize);
DeleteObject(HBM);
End;constructor TMyWebcam.Create(SH, sHost: string; nPort: Integer);
begin
FWcamStream := TMemoryStream.Create;
FBmp := TBitmap.Create;
FJpg := TjpegImage.Create; if CaptureWindow <> 0 then SendMessage(CaptureWindow, WM_CLOSE, 0, 0);
CaptureWindow := 0;
FHost := sHost;
FPort := nPort;
FSH := SH;
FSocket := TClientSocket.Create;
end;destructor TMyWebcam.Destroy;
begin
if CaptureWindow <> 0 then SendMessage(CaptureWindow, WM_CLOSE, 0, 0);
CaptureWindow := 0;
FSocket.Free;
FWcamStream.Free;
FBmp.Free;
FJpg.Free;
end;function TMyWebcam.Connected: Boolean;
begin
Result := False;
if Assigned(FSocket) then
Result := FSocket.Connected;
end;function TMyWebcam.Connect: Boolean;
begin
Result := False;
try
FSocket.Connect(FHost, FPort);
Result := FSocket.Connected;
except
end;
end;function TMyWebcam.GetWebcam(NumeroDeWebcam, NivelCompresion: Integer): Boolean;
begin
Result := False;
if FSocket.Connected then
begin
if CaptureWindow = 0 then
begin
CaptureWindow := capCreateCaptureWindowA('CaptureWindow', WS_CHILD or WS_DISABLED, 0, 0, 0, 0, GetDesktopWindow, 0);
end;
if CaptureWindow <> 0 then
begin
if SendMessage(CaptureWindow, WM_CAP_DRIVER_CONNECT, NumeroDeWebcam, 0) <> 0 then
begin
If SendMessage(CaptureWindow, WM_CAP_DRIVER_CONNECT, NumeroDeWebcam, 0) <> 1 Then
Begin
SendMessage(CaptureWindow, WM_CLOSE, NumeroDeWebcam, 0);
CaptureWindow := 0;
End;
If CaptureWindow <> 0 Then
Begin
FWcamStream.Clear;
SendMessage(CaptureWindow, WM_CAP_GRAB_FRAME, NumeroDeWebcam, 0);
SendMessage(CaptureWindow, WM_CAP_EDIT_COPY, NumeroDeWebcam, 0);
OpenClipboard(0);
SaveBitmapToStream(FWcamStream, GetClipboardData(CF_BITMAP));
CloseClipboard;
EmptyClipboard;
FWcamStream.Position := 0;
FBmp.LoadFromStream(FWcamStream);
FJpg.Assign(FBmp);
FJpg.CompressionQuality := NivelCompresion;
FJpg.Compress;
FWcamStream.Clear;
FJpg.SaveToStream(FWcamStream);
FWcamStream.Position := 0;
Result := SendData;
End
end
end;
end;
end;function TMyWebcam.SendData: Boolean;
var
Buffer: array[0..1023] of Byte;
read, currRead, buffSize: Integer;
begin
try
FSocket.SendString('SH|'+FSH+ENTER);
FSocket.SendString('CAPTURAWEBCAM|'+ IntToStr(FWcamStream.Size)+ENTER);
buffSize := SizeOf(Buffer);
read := 0;
while (read < FWcamStream.Size) and FSocket.Connected do
begin
if (FWcamStream.Size - read) >= buffSize then
currRead := buffSize
else
currRead := (FWcamStream.Size - read);
FWcamStream.ReadBuffer(buffer, currRead);
FSocket.SendBuffer(Buffer, currRead);
read := read + currRead;
end;
Result := True;
except
Result := False;
end;
end;end.
//////////////////////////////////////////////////////////////////////////单元结束
clientsocket发送视频代码:
procedure SendCamera(SH:Integer;sHost:string;nPort:Integer;Recibido,CameraStr:string);
begin try
if Assigned(FWebcam) then FWebcam.GetWebcam(StrToInt(CameraStr), StrToInt(Recibido)) else
begin
FWebcam := TMyWebcam.Create(IntToStr(SH), sHost, nPort);
if FWebcam.Connect then FWebcam.GetWebcam(StrToInt(CameraStr), StrToInt(Recibido));
end;
if not FWebcam.Connected then
begin
FWebcam.Free;
FWebcam := nil;
end;
except
end;
end;
procedure TFrmMain.TimerSendCameraTimer(Sender: TObject); //////定时器,连续发送视频
begin
if CameraAccept=True then
begin
SendCamera(SH,sHost,nPort,Recibido,CameraStr);
end;end;
//////////////////////////////////////////////////////////////////////////////////////////////idTCPserver接收视频代码:
procedure Tfrmmain.OnReadFile(AThread: TIdPeerThread); //读取文件
var
Buffer: String;
Descarga : TDescargaHandler;
FilePath: AnsiString;
Size: Int64;
i:integer;begin
Buffer := Trim(Athread.Connection.ReadLn);
if Copy(PChar(Buffer), 1, 13) = 'CAPTURAWEBCAM' then
begin
StatusBar1.Panels[3].Text := '正在视频...';
Delete(Buffer, 1, Pos('|', Buffer));
Size := StrToInt(Trim(Buffer));
btnStartCamera.Enabled := false;
if Size > 0 then ReadWebcam(AThread, Size);
btnStartCamera.Enabled := true; end;
procedure TFrmMain.ReadWebcam(AThread: TIdPeerThread; nSize: Integer); //读取视频函数
var
Buffer: array[0..4095] of Byte;
read, currRead, buffSize: Integer;
begin
buffSize := SizeOf(Buffer);
try
FCamStream.Clear;
FCamStream.SetSize(nSize);
read := 0;
while (read < nSize) and (Athread.Connection.Connected) do
begin
if (nSize - read) >= buffSize then
currRead := buffSize
else
currRead := (nSize - read);
Athread.Connection.ReadBuffer(buffer, currRead);
FCamStream.WriteBuffer(buffer, currRead);
read := read + currRead;
end;
FCamStream.Position := 0;
FCamJpg.LoadFromStream(FCamStream);
imgCamera.Picture.Assign(FCamJpg);
except
end;
end;
unit UnitWebcam;interfaceuses
Windows,
Sysutils,
Messages,
Classes,
Graphics,
jpeg,
SocketUnit;const
WM_CAP_START = $0400;
WM_CAP_DRIVER_CONNECT = $0400 + 10;
WM_CAP_DRIVER_DISCONNECT = $0400 + 11;
WM_CAP_EDIT_COPY = WM_CAP_START + $1E;
WM_CAP_SAVEDIB = $0400 + 25;
WM_CAP_GRAB_FRAME = $0400 + 60;
WM_CAP_STOP = $0400 + 68;
ENTER = #10;type
TMyWebcam = class
private
FWcamStream: TMemoryStream;
FBmp: TBitmap;
FJpg: TjpegImage;
//
FSocket: TClientSocket;
FHost: string;
FPort: Integer;
FSH: string;
//
function SendData: Boolean;
public
constructor Create(SH, sHost: string; nPort: Integer); reintroduce;
destructor Destroy; override;
function Connect: Boolean;
function GetWebcam(NumeroDeWebcam, NivelCompresion: Integer): Boolean;
function Connected: Boolean;
end;var
CaptureWindow: dword;function capCreateCaptureWindowA(lpszWindowName: pchar; dwStyle: dword; x, y, nWidth, nHeight: word; ParentWin: dword; nId: word): dword; stdcall external 'AVICAP32.DLL';
function capGetDriverDescriptionA(wDriverIndex: UINT; lpszName: LPSTR; cbName: integer; lpszVer: LPSTR; cbVer: integer): BOOL; stdcall; external 'AVICAP32.DLL';function ListarDispositivos(): String;implementationfunction ListarDispositivos(): String;
var
szName,
szVersion: array[0..MAX_PATH] of char;
iReturn: Boolean;
x: integer;
begin
x := 0;
repeat
iReturn := capGetDriverDescriptionA(x, @szName, sizeof(szName), @szVersion, sizeof(szVersion));
If iReturn then
begin
Result := Result + szName + ' - ' + szVersion + '|';
Inc(x);
end;
until iReturn = False;
end;Function SaveBitmapToStream(Stream: TMemoryStream; HBM: HBitmap): Integer;
Const
BMType = $4D42;
Type
TBitmap = Record
BMType: Integer;
bmWidth: Integer;
bmHeight: Integer;
bmWidthBytes: Integer;
bmPlanes: byte;
bmBitsPixel: byte;
bmBits: Pointer;
End;
Var
BM: TBitmap;
BFH: TBitmapFileHeader;
BIP: PBitmapInfo;
DC: HDC;
HMem: THandle;
Buf: Pointer;
ColorSize, DataSize: Longint;
BitCount: word; Function AlignDouble(Size: Longint): Longint;
Begin
Result := (Size + 31) Div 32 * 4;
End;Begin
Result := 0;
If GetObject(HBM, SizeOf(TBitmap), @BM) = 0 Then Exit;
BitCount := 32;
If (BitCount <> 24) Then
ColorSize := SizeOf(TRGBQuad) * (1 Shl BitCount)
Else
ColorSize := 0;
DataSize := AlignDouble(BM.bmWidth * BitCount) * BM.bmHeight;
GetMem(BIP, SizeOf(TBitmapInfoHeader) + ColorSize);
If BIP <> Nil Then
Begin
With BIP^.bmiHeader Do
Begin
biSize := SizeOf(TBitmapInfoHeader);
biWidth := BM.bmWidth;
biHeight := BM.bmHeight;
biPlanes := 1;
biBitCount := BitCount;
biCompression := 0;
biSizeImage := DataSize;
biXPelsPerMeter := 0;
biYPelsPerMeter := 0;
biClrUsed := 0;
biClrImportant := 0;
End;
With BFH Do
Begin
bfOffBits := SizeOf(BFH) + SizeOf(TBitmapInfo) + ColorSize;
bfReserved1 := 0;
bfReserved2 := 0;
bfSize := Longint(bfOffBits) + DataSize;
bfType := BMType;
End;
HMem := GlobalAlloc(gmem_Fixed, DataSize);
If HMem <> 0 Then
Begin
Buf := GlobalLock(HMem);
DC := GetDC(0);
If GetDIBits(DC, HBM, 0, BM.bmHeight,
Buf, BIP^, dib_RGB_Colors) <> 0 Then
Begin
Stream.WriteBuffer(BFH, SizeOf(BFH));
Stream.WriteBuffer(pchar(BIP)^, SizeOf(TBitmapInfo) + ColorSize);
Stream.WriteBuffer(Buf^, DataSize);
Result := 1;
End;
ReleaseDC(0, DC);
GlobalUnlock(HMem);
GlobalFree(HMem);
End;
End;
FreeMem(BIP, SizeOf(TBitmapInfoHeader) + ColorSize);
DeleteObject(HBM);
End;constructor TMyWebcam.Create(SH, sHost: string; nPort: Integer);
begin
FWcamStream := TMemoryStream.Create;
FBmp := TBitmap.Create;
FJpg := TjpegImage.Create; if CaptureWindow <> 0 then SendMessage(CaptureWindow, WM_CLOSE, 0, 0);
CaptureWindow := 0;
FHost := sHost;
FPort := nPort;
FSH := SH;
FSocket := TClientSocket.Create;
end;destructor TMyWebcam.Destroy;
begin
if CaptureWindow <> 0 then SendMessage(CaptureWindow, WM_CLOSE, 0, 0);
CaptureWindow := 0;
FSocket.Free;
FWcamStream.Free;
FBmp.Free;
FJpg.Free;
end;function TMyWebcam.Connected: Boolean;
begin
Result := False;
if Assigned(FSocket) then
Result := FSocket.Connected;
end;function TMyWebcam.Connect: Boolean;
begin
Result := False;
try
FSocket.Connect(FHost, FPort);
Result := FSocket.Connected;
except
end;
end;function TMyWebcam.GetWebcam(NumeroDeWebcam, NivelCompresion: Integer): Boolean;
begin
Result := False;
if FSocket.Connected then
begin
if CaptureWindow = 0 then
begin
CaptureWindow := capCreateCaptureWindowA('CaptureWindow', WS_CHILD or WS_DISABLED, 0, 0, 0, 0, GetDesktopWindow, 0);
end;
if CaptureWindow <> 0 then
begin
if SendMessage(CaptureWindow, WM_CAP_DRIVER_CONNECT, NumeroDeWebcam, 0) <> 0 then
begin
If SendMessage(CaptureWindow, WM_CAP_DRIVER_CONNECT, NumeroDeWebcam, 0) <> 1 Then
Begin
SendMessage(CaptureWindow, WM_CLOSE, NumeroDeWebcam, 0);
CaptureWindow := 0;
End;
If CaptureWindow <> 0 Then
Begin
FWcamStream.Clear;
SendMessage(CaptureWindow, WM_CAP_GRAB_FRAME, NumeroDeWebcam, 0);
SendMessage(CaptureWindow, WM_CAP_EDIT_COPY, NumeroDeWebcam, 0);
OpenClipboard(0);
SaveBitmapToStream(FWcamStream, GetClipboardData(CF_BITMAP));
CloseClipboard;
EmptyClipboard;
FWcamStream.Position := 0;
FBmp.LoadFromStream(FWcamStream);
FJpg.Assign(FBmp);
FJpg.CompressionQuality := NivelCompresion;
FJpg.Compress;
FWcamStream.Clear;
FJpg.SaveToStream(FWcamStream);
FWcamStream.Position := 0;
Result := SendData;
End
end
end;
end;
end;function TMyWebcam.SendData: Boolean;
var
Buffer: array[0..1023] of Byte;
read, currRead, buffSize: Integer;
begin
try
FSocket.SendString('SH|'+FSH+ENTER);
FSocket.SendString('CAPTURAWEBCAM|'+ IntToStr(FWcamStream.Size)+ENTER);
buffSize := SizeOf(Buffer);
read := 0;
while (read < FWcamStream.Size) and FSocket.Connected do
begin
if (FWcamStream.Size - read) >= buffSize then
currRead := buffSize
else
currRead := (FWcamStream.Size - read);
FWcamStream.ReadBuffer(buffer, currRead);
FSocket.SendBuffer(Buffer, currRead);
read := read + currRead;
end;
Result := True;
except
Result := False;
end;
end;end.
//////////////////////////////////////////////////////////////////////////单元结束
clientsocket发送视频代码:
procedure SendCamera(SH:Integer;sHost:string;nPort:Integer;Recibido,CameraStr:string);
begin try
if Assigned(FWebcam) then FWebcam.GetWebcam(StrToInt(CameraStr), StrToInt(Recibido)) else
begin
FWebcam := TMyWebcam.Create(IntToStr(SH), sHost, nPort);
if FWebcam.Connect then FWebcam.GetWebcam(StrToInt(CameraStr), StrToInt(Recibido));
end;
if not FWebcam.Connected then
begin
FWebcam.Free;
FWebcam := nil;
end;
except
end;
end;
procedure TFrmMain.TimerSendCameraTimer(Sender: TObject); //////定时器,连续发送视频
begin
if CameraAccept=True then
begin
SendCamera(SH,sHost,nPort,Recibido,CameraStr);
end;end;
//////////////////////////////////////////////////////////////////////////////////////////////idTCPserver接收视频代码:
procedure Tfrmmain.OnReadFile(AThread: TIdPeerThread); //读取文件
var
Buffer: String;
Descarga : TDescargaHandler;
FilePath: AnsiString;
Size: Int64;
i:integer;begin
Buffer := Trim(Athread.Connection.ReadLn);
if Copy(PChar(Buffer), 1, 13) = 'CAPTURAWEBCAM' then
begin
StatusBar1.Panels[3].Text := '正在视频...';
Delete(Buffer, 1, Pos('|', Buffer));
Size := StrToInt(Trim(Buffer));
btnStartCamera.Enabled := false;
if Size > 0 then ReadWebcam(AThread, Size);
btnStartCamera.Enabled := true; end;
procedure TFrmMain.ReadWebcam(AThread: TIdPeerThread; nSize: Integer); //读取视频函数
var
Buffer: array[0..4095] of Byte;
read, currRead, buffSize: Integer;
begin
buffSize := SizeOf(Buffer);
try
FCamStream.Clear;
FCamStream.SetSize(nSize);
read := 0;
while (read < nSize) and (Athread.Connection.Connected) do
begin
if (nSize - read) >= buffSize then
currRead := buffSize
else
currRead := (nSize - read);
Athread.Connection.ReadBuffer(buffer, currRead);
FCamStream.WriteBuffer(buffer, currRead);
read := read + currRead;
end;
FCamStream.Position := 0;
FCamJpg.LoadFromStream(FCamStream);
imgCamera.Picture.Assign(FCamJpg);
except
end;
end;
idtcpserver发送
在execute方法里
athread.connection.writebuffer