Ir para conteúdo
Fórum Script Brasil
  • 0

Como escolher uma webcam entre várias?


Gabriel Cabral

Pergunta

Boa tarde, pessoal. Tudo bem?!
Estou precisando de uma grande ajuda para utilizar mais de uma webcam.

Preciso de algo que liste as webcams instaladas ou alguma outra forma que eu possa escolher qual webcam utilizar.

Já vi inúmeros tópicos relativos a webcam, mas nada que me ajudasse neste caso.

O programa está fazendo a captura de imagem da seguinte forma:

var
  frmCapturaImg: TfrmCapturaImg;
  hWndC: THandle = 0;
  rg: string;

implementation

uses U_frmCadMoradores;

{$R *.dfm}

const WM_CAP_START = WM_USER;
const WM_CAP_STOP = WM_CAP_START + 68;
const WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;
const WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;
const WM_CAP_SAVEDIB = WM_CAP_START + 25;
const WM_CAP_GRAB_FRAME = WM_CAP_START + 60;
const WM_CAP_SEQUENCE = WM_CAP_START + 62;
const WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20;
const WM_CAP_SEQUENCE_NOFILE =WM_CAP_START+ 63;
const WM_CAP_SET_OVERLAY =WM_CAP_START+ 51 ;
const WM_CAP_SET_PREVIEW =WM_CAP_START+ 50;
const WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_CAP_START +6;
const WM_CAP_SET_CALLBACK_ERROR=WM_CAP_START +2;
const WM_CAP_SET_CALLBACK_STATUSA= WM_CAP_START +3;
const WM_CAP_SET_CALLBACK_FRAME= WM_CAP_START +5;
const WM_CAP_SET_SCALE=WM_CAP_START+ 53 ;
const WM_CAP_SET_PREVIEWRATE=WM_CAP_START+ 52;

function capCreateCaptureWindowA(lpszWindowName : PCHAR; dwStyle : longint; x : integer; y : integer;nWidth : integer;nHeight : integer;ParentWin : HWND; nId : integer): HWND; STDCALL; EXTERNAL 'AVICAP32.DLL';

///// === CONECTA WEBCAM === /////

  if hWndC <> 0 then exit;

  hWndC := capCreateCaptureWindowA('WINACESSO',WS_CHILD or WS_VISIBLE ,image1.Left,image1.Top,image1.width,image1.height,frmCapturaImg.Handle,0);

  if hWndC <> 0 then
  begin
    SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);
    SendMessage(hWndC, WM_CAP_SET_CALLBACK_ERROR, 0, 0);
    SendMessage(hWndC, WM_CAP_SET_CALLBACK_STATUSA, 0, 0);
    SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);
    SendMessage(hWndC, WM_CAP_SET_SCALE, 1, 0);
    SendMessage(hWndC, WM_CAP_SET_PREVIEWRATE, 66, 0);
    SendMessage(hWndC, WM_CAP_SET_OVERLAY, 1, 0);
    SendMessage(hWndC, WM_CAP_SET_PREVIEW, 1, 0);
  end;

///// === CAPTURA IMAGEM === /////

rg := frmCadMoradores.txtCadMoradores_RG.Text;

  if hWndC <> 0 then
  begin
    SendMessage(hWndC,WM_CAP_SAVEDIB,0,longint(pchar('C:\WINACESSO\FOTOS\' + rg + '.bmp')));
  end;

///// === DESCONECTA WEBCAM === /////

if hWndC <> 0 then
begin
  SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0);
  hWndC := 0;
end;
Editado por Gabriel Cabral
Link para o comentário
Compartilhar em outros sites

7 respostass a esta questão

Posts Recomendados

  • 0

sugestão mais pratica

http://www.anunico.com.br/anuncio-de/placa_de_captura_gv_800_p_16_cameras_120_fps-844559.html

mas se quer algo para usar com o delphi, veja o componente TVideoGrabber

http://vlc-undf-codec-vlc.windows.novellshareware.com/info/tvideograbber-delphi-video-sdk.html

download do componente -- existe versão gratuita desse componente mas com limitações de recursos

http://www.google.com.br/search?q=componente+videograbber+delphi&hl=pt&gbv=2&prmd=ivns&source=lnms&sa=X&ei=Tc49U8v4BObE0gGwuoCoAg&ved=0CAQQ_AU

OBS: No menu desse componente voce pode escolher qual a webcam que quer visualizar e que esteja conectada ao pc

tem uma serie de recursos para esse componente, mas voce pode usar somente o que for necessario

exemplo : Demo http://www.datastead.com/_releases/vidgrab_8.8.4.1_MainDemo.zip

abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Bom dia, Jhonas.

Muito obrigado pelas dicas, mas não me dei bem com nenhum componente até agora.

Preciso mesmo fazer sem utilizar componentes.

Acredito que a linha onde escolho a webcam é esta

SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);

Onde o parâmetro 0 indica a webcam padrão.

E isso realmente funciona, pois num notebook ela liga a webcam acoplada em vez da webcam USB.

Mas tentando mudar o parâmetro para 1, nada acontece. Nenhuma das câmeras é ligada.

Link para o comentário
Compartilhar em outros sites

  • 0

ok amigo... eu utilizo esse componente sem problemas

Acredito que a linha onde escolho a webcam é esta

SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);

realmente é nessa linha que voce escolhe a webcam

SendMessage(mCapHwnd, WM_CAP_CONNECT, DeviceID, 0);

voce deve pegar o nome ou o numero da webcam instalada e colocar no lugar do parametro DeviceID

Para enumerar os webcams, você pode usar o Enumerador de dispositivos do sistema, passando a CLSID_VideoInputDeviceCategory GUID que irá obter todos os dispositivos de captura de vídeo.

exemplo

{$APPTYPE CONSOLE}

uses
SysUtils,
Windows,
ActiveX,
DirectShow9,
ComObj;

procedure EnumerateVideoInputDevices;
const
IID_IPropertyBag : TGUID = '{55272A00-42CB-11CE-8135-00AA004BB851}';
var
LDevEnum : ICreateDevEnum;
ppEnumMoniker : IEnumMoniker;
pceltFetched : ULONG;
Moniker : IMoniker;
PropBag : IPropertyBag;
pvar : olevariant;
hr : HRESULT;
i : integer;
begin
CocreateInstance(CLSID_SystemDeviceEnum, nil, CLSCTX_INPROC, IID_ICreateDevEnum, LDevEnum);
hr := LDevEnum.CreateClassEnumerator(CLSID_VideoInputDeviceCategory, ppEnumMoniker, 0);
if (hr = S_OK) then
begin
while(ppEnumMoniker.Next(1, Moniker, @pceltFetched) = S_OK) do
begin
Moniker.BindToStorage(nil, nil, IID_IPropertyBag, PropBag);
if PropBag.Read('Description', pvar, nil) = S_OK then
Writeln(Format('Description %s',[String(pvar)]));
if PropBag.Read('FriendlyName', pvar, nil) = S_OK then
Writeln(Format('Friendly Name %s',[String(pvar)]));
if PropBag.Read('DevicePath', pvar, nil) = S_OK then
Writeln(Format('Device Path %s',[String(pvar)]));
if PropBag.Read('CLSID', pvar, nil) = S_OK then
Writeln(Format('CLSID %s',[String(pvar)]));
PropBag := nil;
Moniker := nil;
end;
end;
ppEnumMoniker :=nil;
LDevEnum :=nil;
end;



begin
try
CoInitialize(nil);
try
EnumerateVideoInputDevices;
finally
CoUninitialize;
end;
except
on E:EOleException do
Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
on E:Exception do
Writeln(E.Classname, ':', E.Message);
end;
Writeln('Press Enter to exit');
Readln;
end.

===============================================================================

outro exemplo util que voce podera usar

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

type
TForm1 = class(TForm)
Panel1: TPanel;
SaveDialog1: TSaveDialog;
Panel2: TPanel;
OpenVideo: TButton;
CloseVideo: TButton;
SaveBMP: TButton;
StartAVI: TButton;
StopAVI: TButton;
procedure FormCreate(Sender: TObject);
procedure OpenVideoClick(Sender: TObject);
procedure CloseVideoClick(Sender: TObject);
procedure SaveBMPClick(Sender: TObject);
procedure StartAVIClick(Sender: TObject);
procedure StopAVIClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
hWndC : THandle;
CapturingAVI : bool;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

const WM_CAP_START = WM_USER;
const WM_CAP_STOP = WM_CAP_START + 68;
const WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;
const WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;
const WM_CAP_SAVEDIB = WM_CAP_START + 25;
const WM_CAP_GRAB_FRAME = WM_CAP_START + 60;
const WM_CAP_SEQUENCE = WM_CAP_START + 62;
const WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20;
const WM_CAP_SEQUENCE_NOFILE =WM_CAP_START+ 63 ;
const WM_CAP_SET_OVERLAY =WM_CAP_START+ 51 ;
const WM_CAP_SET_PREVIEW =WM_CAP_START+ 50 ;
const WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_CAP_START +6;
const WM_CAP_SET_CALLBACK_ERROR=WM_CAP_START +2;
const WM_CAP_SET_CALLBACK_STATUSA= WM_CAP_START +3;
const WM_CAP_SET_CALLBACK_FRAME= WM_CAP_START +5;
const WM_CAP_SET_SCALE=WM_CAP_START+ 53 ;
const WM_CAP_SET_PREVIEWRATE=WM_CAP_START+ 52 ;
function capCreateCaptureWindowA(lpszWindowName : PCHAR;
dwStyle : longint;
x : integer;
y : integer;
nWidth : integer;
nHeight : integer;
ParentWin : HWND;
nId : integer): HWND;
STDCALL EXTERNAL 'AVICAP32.DLL';

procedure TForm1.FormCreate(Sender: TObject);
begin
CapturingAVI := false;
hWndC := 0;
SaveDialog1.Options :=
[ofHideReadOnly, ofNoChangeDir, ofPathMustExist]
end;





procedure TForm1.OpenVideoClick(Sender: TObject);
begin
hWndC := capCreateCaptureWindowA('My Own Capture Window',
WS_CHILD or WS_VISIBLE ,
Panel1.Left,
Panel1.Top,
Panel1.Width,
Panel1.Height,
Form1.Handle,
0);
if hWndC <> 0 then
SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);
SendMessage(hWndC, WM_CAP_SET_CALLBACK_ERROR, 0, 0);
SendMessage(hWndC, WM_CAP_SET_CALLBACK_STATUSA, 0, 0);
SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);
SendMessage(hWndC, WM_CAP_SET_SCALE, 1, 0);
SendMessage(hWndC, WM_CAP_SET_PREVIEWRATE, 66, 0);
//SendMessage(hWndC, WM_CAP_SEQUENCE_NOFILE, 1, 0);
SendMessage(hWndC, WM_CAP_SET_OVERLAY, 1, 0);
SendMessage(hWndC, WM_CAP_SET_PREVIEW, 1, 0);
OpenVideo.Enabled :=false;
end;

procedure TForm1.CloseVideoClick(Sender: TObject);
begin
if hWndC <> 0 then begin
SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0);
hWndC := 0;
OpenVideo.Enabled :=true;
end;
end;

procedure TForm1.SaveBMPClick(Sender: TObject);
begin
if hWndC <> 0 then begin
SaveDialog1.DefaultExt := 'bmp';
SaveDialog1.Filter := 'Bitmap files (*.bmp)|*.bmp';
if SaveDialog1.Execute then
SendMessage(hWndC,
WM_CAP_SAVEDIB,
0,
longint(pchar(SaveDialog1.FileName)));
end;
end;

procedure TForm1.StartAVIClick(Sender: TObject);
begin
if hWndC <> 0 then begin
SaveDialog1.DefaultExt := 'avi';
SaveDialog1.Filter := 'AVI files (*.avi)|*.avi';
if SaveDialog1.Execute then begin
CapturingAVI := true;
SendMessage(hWndC,
WM_CAP_FILE_SET_CAPTURE_FILEA,
0,
Longint(pchar(SaveDialog1.FileName)));
SendMessage(hWndC, WM_CAP_SEQUENCE, 0, 0);
end;
end;
end;

procedure TForm1.StopAVIClick(Sender: TObject);
begin
if hWndC <> 0 then begin
SendMessage(hWndC, WM_CAP_STOP, 0, 0);
CapturingAVI := false;
end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseVideoClick(Sender);
end;

end.

abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Boa tarde, Jhonas.

Fiz o teste com o exemplo que você passou. Fiz num notebook que tem uma câmera acoplada e mais uma webcam USB.

Obtive o seguinte retorno:

FriendlyName: CyberLink Webcam Splitter
DevicePath: \\?\root#media#0000#{65e8773d-8f56-11d0-a3b9-00a0...\global

CLSID: {17CCA71B-ECD7-11D0-B908-00A0C9223196}

FriendlyName: HP Webcam-50
DevicePath: \\?\usb#vid_05c8&pid_0223&mi00#7&1d1c0389&0&0...\global

CLSID: {17CCA71B-ECD7-11D0-B908-00A0C9223196}

FriendlyName: U2 EE Cam
DevicePath: \\?\usb#vid_05e3&pid_0512&mi_00#6&1374dce8&0&0...\global

CLSID: {17CCA71B-ECD7-11D0-B908-00A0C9223196}

O que devo colocar no lugar do parametro DeviceID, para conectar a câmera?

SendMessage(mCapHwnd, WM_CAP_CONNECT, DeviceID, 0);

Tentei passar o FriendlyName, mas acusa erro, dizendo que precisa ser um Integer.

Também tentei colocar 1, 2... mas a tela fica preta e não conecta nenhuma câmera.

Só está conectando quando coloco 0. Nesse caso, conecta a câmera acoplada.

Editado por Gabriel Cabral
Link para o comentário
Compartilhar em outros sites

  • 0

use esse codigo e me informe o nome que aparece no combobox

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
ComboBox1: TComboBox;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

Uses ActiveX, ComObj;
Type
ICreateDevEnum = interface(IUnknown)
['{29840822-5B84-11D0-BD3B-00A0C911CE86}']
(*** ICreateDevEnum methods ***)
function CreateClassEnumerator(const clsidDeviceClass: TGUID;
out ppEnumMoniker: IEnumMoniker; dwFlags: DWORD): HResult; stdcall;
end;

procedure EnumerateVideoInputDevices( Liste:TStrings );
const
IID_ICreateDevEnum : TGUID = '{29840822-5B84-11D0-BD3B-00A0C911CE86}';
CLSID_SystemDeviceEnum : TGUID = (D1:$62BE5D10;D2:$60EB;D3:$11D0;D4:($BD,$3B,$00,$A0,$C9,$11,$CE,$86));
CLSID_VideoInputDeviceCategory: TGUID = (D1:$860BB310;D2:$5D01;D3:$11D0;D4:($BD,$3B,$00,$A0,$C9,$11,$CE,$86));
IID_IPropertyBag : TGUID = '{55272A00-42CB-11CE-8135-00AA004BB851}';
var
LDevEnum : ICreateDevEnum;
ppEnumMoniker : IEnumMoniker;
pceltFetched : ULONG;
Moniker : IMoniker;
PropBag : IPropertyBag;
pvar : olevariant;
hr : HRESULT;
strDescription, strFriendlyName, strDevicePath, strCLSID : String;
begin
CocreateInstance(CLSID_SystemDeviceEnum, nil, CLSCTX_INPROC, IID_ICreateDevEnum, LDevEnum);
hr := LDevEnum.CreateClassEnumerator(CLSID_VideoInputDeviceCategory, ppEnumMoniker, 0);
if (hr = S_OK) then
begin
while(ppEnumMoniker.Next(1, Moniker, @pceltFetched) = S_OK) do
begin
strDescription := '';
strFriendlyName := '';
strDevicePath := '';
strCLSID := '';
Moniker.BindToStorage(nil, nil, IID_IPropertyBag, PropBag);
if PropBag.Read('Description', pvar, nil) = S_OK then
strDescription := String(pvar);
if PropBag.Read('FriendlyName', pvar, nil) = S_OK then
strFriendlyName := String(pvar);
if PropBag.Read('DevicePath', pvar, nil) = S_OK then
strDevicePath := (pvar);
if PropBag.Read('CLSID', pvar, nil) = S_OK then
strCLSID := String(pvar);
PropBag := nil;
Moniker := nil;
Liste.Add( strFriendlyName );
end;
end;
ppEnumMoniker :=nil;
LDevEnum :=nil;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
EnumerateVideoInputDevices( ComboBox1.Items );
end;

end.

=====================================================================

OBS: olhando as funções da api, realmente não é o nome mas um numero da camera que voce ira usar

SendMessage(_windowHandle, WM_CAP_CONNECT, _videoSourceIndex, 0)

então nesse código que passei, não utilze o nome que esta no combobox e sim o indice dele

tente 0,1,2,3,..5

outra detalhe, ao selecionar um numero acima de zero ( padrão ) voce deve esperar alguns segundos para a imagem aparecer e dependendo pode demorar até um pouco mais.

abraço

Link para o comentário
Compartilhar em outros sites

  • 0

Os nomes que aparecem no combobox são:

CyberLink Webcam Splitter

HP Webcam-50

U2 EE Cam

Então, se eu quiser conectar a webcam USB (U2 EE Cam), devo usar SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 2, 0);, certo?!

Pois fiz o teste e não conecta. Já esperei mais de três minutos e não conectou.

Link para o comentário
Compartilhar em outros sites

  • 0

amigo, creio então que voce deverá recorrer ao componente TVideoGrabber, o qual, lhe falei ... uso sem problemas

os componentes que utilizo fazem parte do pacote de componentes do TVideoGrabber

FilterGraph: TFilterGraph;

SampleGrabber: TSampleGrabber;

VideoWindow: TVideoWindow;

nesses componentes é possivel selecionar a webcam pelo nome

tem um exemplo muito bom nesse link ... veja todas ( 12 ) as paginas sobre esse assunto

http://www.vwlowen.co.uk/directshow/page03.htm

http://www.vwlowen.co.uk/directshow/page05.htm

http://www.vwlowen.co.uk/directshow/page06.htm

abraço

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152k
    • Posts
      651,8k
×
×
  • Criar Novo...