APIs - Duvida - SOLUCIONADO!

Preciso abrir a WebCam do meu PC utilizando a API do windows avicap.dll com programação java.
Obs: Não quero utilizar a API JMF do java, assim é muito fácil e ja fiz isto. Estudo outras linguagens como a .NET e há diversos exemplos na internet para esta LP. Portanto preciso abrir a webcam com a avicap.dll em LP Java.

Informações adicionais que estou usando: Windows Vista Ultimate, NetBeans 7.0 e JNA.jar

Criei 2 classes, 3 interfaces e 1 JFrame:

Interface 1: Avicap32.

[i]/* Referências:
MICROSOFT (Org.). Acessar imagem da WebCam. Disponível em: <http://social.msdn.microsoft.com/Forums/pt-BR/vscsharppt/thread/4df4fc93-a2d5-401b-ab4a- 056e00f47ec7>. Acesso em: 10 jan. 2010.

MICROSOFT (Org.). CapCreateCaptureWindow function. Disponível em: <http://msdn.microsoft.com/en-us/library/windows/desktop/dd756879(v=vs.85).aspx>. Acesso em: 10 jan. 2010.

ORACLE (Org.). Class System. Disponível em: <http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/System.html>. Acesso em: 10 jan. 2010.*/

[/i]

[code]public interface Avicap32 extends StdCallLibrary{

public int capCreateCaptureWindowA(
        String lpszWindowName,
        int dwStye,
        int x,
        int y,
        int nWidth,
        int nHeight,
        int hWndParent,
        int nID);    

 public static final int WM_CAP_DRIVER_CONNECT = 0x40a;
 public static final int WM_CAP_DRIVER_DISCONNECT = 0x40b;
 public static final int WM_CAP_EDIT_COPY = 0x41e;
 public static final int WM_CAP_SET_PREVIEW = 0x432;
 public static final int WM_CAP_SET_OVERLAY = 0x433;
 public static final int WM_CAP_SET_PREVIEWRATE = 0x434;
 public static final int WM_CAP_SET_SCALE = 0x435;
 public static final int WS_CHILD = 0x40000000;
 public static final int WS_VISIBLE = 0x10000000;
 public static final short SWP_NOMOVE = 0x2;
 public static final short SWP_NOZORDER = 0x4;
 public static final short HWND_BOTTOM = 1;
 public static final short WM_CAP = 0x400;

}[/code]

Classe 2: User32
Obs: A terceira classe MapHWND esta extendida na User32, devido ao Handle (identificador da janela), que preciso lançar, segundo referências da assinatura da API avicap.dll, como parâmetro ao utilizar o método capCreateCaptureWindowA. A terceira classe mapeia o que é necessario para identificar o HWND.

[code]public interface User32 extends StdCallLibrary, MapHWND{

public boolean DestroyWindow(int hndw);  

public boolean ShowWindow(HWND hWnd, int nCmdShow);

public HWND FindWindow(String winClass, String title);

public int SetWindowPos(
        int hwnd, 
        int hWndInsertAfter, 
        int x, 
        int y, 
        int cx, 
        int cy, 
        int wFlags);  

public int SendMessageA(
        int hwnd, 
        int wMsg, 
        int wParam, 
        Object lParam);    

}[/code]

Classe 3: MapHWND

[code]public interface MapHWND extends StdCallLibrary{
Map UNICODE_OPTIONS = new HashMap() {
{
put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
}
};

Map ASCII_OPTIONS = new HashMap() {

    {
        put(OPTION_TYPE_MAPPER, W32APITypeMapper.ASCII);
        put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.ASCII);
    }
};

Map DEFAULT_OPTIONS = Boolean.getBoolean("w32.ascii") ? ASCII_OPTIONS
        : UNICODE_OPTIONS;


public static class HANDLE extends PointerType {

    @Override
    public Object fromNative(Object nativeValue, FromNativeContext context) {
        Object o = super.fromNative(nativeValue, context);
        if (INVALID_HANDLE_VALUE.equals(o)) {
            return INVALID_HANDLE_VALUE;
        }
        return o;
    }
}

//---------------------------------------------------------------

public static class HWND extends HANDLE {
}

//public static class HWNDInsertAfter extends HANDLE{        
//}
//----------------------------------------------------------------

HANDLE INVALID_HANDLE_VALUE = new HANDLE() {

    {
        super.setPointer(Pointer.createConstant(-1));
    }

    @Override
    public void setPointer(Pointer p) {
        throw new UnsupportedOperationException("Immutable reference");
    }
};    

}[/code]

Classe 4: FrameWebCam

Objetos: um JPanel nomeado de jpIm e um botão.

No evento onclick (ou Action performace) do Botão esta o código:

[code]private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {

//Tento objter o HWND do FRAME        
WComponentPeer cpp = (WComponentPeer) this.getPeer();
long h = cpp.getHWnd();        
int id = (int)h; 

int hWnd = 0;
int DeviceID = 0;

//Teste: Mostro na tela o valor.
la.setText(String.valueOf(id));

//Abro as APIs
Avicap32 lib = (Avicap32) Native.loadLibrary("AviCap32", Avicap32.class);
User32 libU = (User32) Native.loadLibrary("User32", User32.class);

String DeviceIndex = String.valueOf(DeviceID);
   
try{  
    //Obtenho valor segundo a assinatura
    hWnd = lib.capCreateCaptureWindowA(DeviceIndex, Avicap32.WS_VISIBLE | Avicap32.WS_CHILD, 0, 0, 320, 240, id, 0);
}catch(Exception ex){JOptionPane.showMessageDialog(null, ex.toString());}    

//Connecto o drive
if (libU.SendMessageA(hWnd, Avicap32.WM_CAP_DRIVER_CONNECT, DeviceID, 0) != 0){            
   
    //Escala
    libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_SCALE, -1, 0);

    //Taxa em milisegundos
    libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_PREVIEWRATE, 66, 0);

    //Preview da cam
    libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_PREVIEW, -1, 0);

    //Setando valores de apresentação
    libU.SetWindowPos(hWnd, Avicap32.HWND_BOTTOM, 0, 0, jpIm.WIDTH, jpIm.HEIGHT, Avicap32.SWP_NOMOVE | Avicap32.SWP_NOZORDER);
 
    //NÃO SEI O QUE FAÇO COM ISSO
    //jpIm.setVisible(true);

}else{
    //Error connecting to device close window
    libU.DestroyWindow(hWnd);
    JOptionPane.showMessageDialog(null, "Fora do SendMessageA");
}

}[/code]

Portanto, a Câmera chega a ligar mas, não há imagem nenhuma!

Ja tentei:

  1. Criar um Component para adicionar ao jpIm.add(component()). O maior problema que encontro nesta situação é um valor nulo devido ao código necessitar que eu instancie o Component com null ou new.

[size=24]Por favor me ajudem. Alguém tem alguma solução? Se possível, por favor, ao encontrar o problema me explique porque. Obrigada.
[/size]

[b]Todo o código acima escrito em JAVA (NetBeans) foi baseado no código, TESTADO E VI QUE FUNCIONA, abaixo em C# (.NET):

[/b][code]
[i]using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

    public class WebCam : IDisposable
    {
        /* Those contants are used to overload the unmanaged code functions
         * each constant represent a state*/

        private const short WM_CAP = 0x400;
        private const int WM_CAP_DRIVER_CONNECT = 0x40a;
        private const int WM_CAP_DRIVER_DISCONNECT = 0x40b;
        private const int WM_CAP_EDIT_COPY = 0x41e;
        private const int WM_CAP_SET_PREVIEW = 0x432;
        private const int WM_CAP_SET_OVERLAY = 0x433;
        private const int WM_CAP_SET_PREVIEWRATE = 0x434;
        private const int WM_CAP_SET_SCALE = 0x435;
        private const int WS_CHILD = 0x40000000;
        private const int WS_VISIBLE = 0x10000000;
        private const short SWP_NOMOVE = 0x2;
        private short SWP_NOZORDER = 0x4;
        private short HWND_BOTTOM = 1;

        //This function enables enumerate the web cam devices
        [DllImport("avicap32.dll")]
        protected static extern bool capGetDriverDescriptionA(short wDriverIndex, String lpszName, int cbName,String lpszVer, int cbVer);
        //This function enables create a  window child with so that you can display it in a picturebox for example

        [DllImport("avicap32.dll")]
        protected static extern int capCreateCaptureWindowA(string lpszWindowName,int dwStyle, int x, int y, int nWidth, int nHeight, int hWndParent, int nID);
        //This function enables set changes to the size, position, and Z order of a child window

        [DllImport("user32")]
        protected static extern int SetWindowPos(int hwnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);
        //This function enables send the specified message to a window or windows

        [DllImport("user32")]
        protected static extern int SendMessage(int hwnd, int wMsg, int wParam, object lParam);
        //This function enable destroy the window child 

        [DllImport("user32")]
        protected static extern bool DestroyWindow(int hwnd);

        // Normal device ID
        int DeviceID = 0;
        // Handle value to preview window
        int hHwnd = 0;


       //The picture to be displayed.constrói um conteiner
        public PictureBox picbox { get; set; }


        public void OpenConnection()
        {
            string DeviceIndex = Convert.ToString(DeviceID);
            IntPtr oHandle = picbox.Handle;

            {
                MessageBox.Show(oHandle.ToString());
            }

            // Open Preview window in picturebox .
            // Create a child window with capCreateCaptureWindowA so you can display it in a picturebox.

            hHwnd = capCreateCaptureWindowA(DeviceIndex, WS_VISIBLE | WS_CHILD, 0, 0, 320, 240, oHandle.ToInt32(), 0);

            // Connect to device
            if (SendMessage(hHwnd, WM_CAP_DRIVER_CONNECT, DeviceID, 0) != 0)
            {

                // Set the preview scale
                SendMessage(hHwnd, WM_CAP_SET_SCALE, -1, 0);

                // Set the preview rate in terms of milliseconds
                SendMessage(hHwnd, WM_CAP_SET_PREVIEWRATE, 66, 0);

                // Start previewing the image from the camera
                SendMessage(hHwnd, WM_CAP_SET_PREVIEW, -1, 0);

                // Resize window to fit in picturebox
                SetWindowPos(hHwnd, HWND_BOTTOM, 0, 0, picbox.Height, picbox.Width, SWP_NOMOVE | SWP_NOZORDER);

            }
            else
            {
                // Error connecting to device close window
                DestroyWindow(hHwnd);
            }
        }

       /// <summary>
        /// This function is used to dispose the connection to the device
        /// </summary>
        #region IDisposable Members

        public void Dispose()
        {
            CloseConnection();
        }
        #endregion
    }


    private void Form1_Load(object sender, EventArgs e)
    {
        
        oWebCam = new WebCam();
        oWebCam.picbox = pictureBox1;
    }
    WebCam oWebCam;

    private void button1_Click(object sender, EventArgs e)
    {
        oWebCam.OpenConnection();
    }

[/i][/code]

Pelo amor de Deus, alguém me ajude

:roll:

Na verdade, nunca funcionaria, pois vc esta dando new em quê?Qual o componente eh o player(libU?)ele deve ser tacado no jPanel antes do setVisible.E ninguem usa mais JMF.Use DirectShow Java ou alguma API menos arcaica.

OBS.:Use as tags code quando for postar codigo pois fica muito mais facil para lermos. :wink:

Da uma lida aqui:

Pois é querido. Abrigada pelas dicas. JMF realmente é arcaico e muito fácil assim como a DIRECT SHOW, a diferença esta que a JMF foi desenvolvida ‘diretamente’ para java enquanto a Direct Show é desenvolvida pela Microsoft para prover de recurso para Linguagens de Programação, porém esta API, DirectShow não é nativa no Windows XX.XX, por ventura resolverão copiar as classes da DLL para uma versão em JAR e virou DirectShow Java.Ao contrário da AVICAP.DLL, no entanto dificilmente se encontra documentação como neste link http://www.andreavb.com/API_USER32.html. Se houvesse algo deste nível na internet, com certeza já haveria resolvido o problema. Dificilmente encontramos certas documentações do windows, nem na DEEP WEB encontrei, graças a deus existe JAVA e a politica GNU porém ainda falta detalhes.

O que realmente quero é abrir a CAM utilizando JNA e a API nativa do windows AVICAP.DLL, ou seja, não quero usar JMF e não usar outra API (alternativa) como a DirectShow para resolver isso, somente a API do java JNA e a API nativa do Windows AVICAP.DLL. Ja pesquisei neste site e não existe isso, somente o meu post. Este é um problema e quero resolve-lo, ja conheço a conexão com JMF, arcaica mas conheço. Também conheço com a nova API Direct Show, mas desconheço a “LIGAÇÃO DIRETA” (DIGAMOS ASSIM) com a API avicap.dll.

OBS: Se você me der a solução do problema, moderador, posso até migrar para outra opção menos arcaica, do contrário, não estarei resolvendo meu problema, apenas pulando para algo “mais fácil” como alternativa de algo que não resolvi, e não é isso que quero.

Mexi no meu código e olha como esta, porém ainda encontro dificuldades pois a imagem na CAM não abre, só há um fundo preto que é a responsabilidae deste código:

libU.SendMessageA(hWnd,Avicap32.WM_CAP_GET_FRAME , 0, 0);

libU é a abreviação de library User, e a libA library Apicap. Estas classes não podem ser instanciadas, como podemos ver não há CONSTRUTOR da classe, são INTERFACES: Elas só podem ser IMPLEMENTADAS e nunca INSTANCIADAS pelo fato serem a mais alta camada de abstração. Contudo, JAMAIS PODEREI USAR ‘NEW’, pois não existe construtor numa INTERFACE.

Realmente esta difícil de achar DOCUMENTAÇÃO, FUI ENCONTRAR ALGUMA COISA SOMENTE NO BANDAI, na CHINA, rsrsrs (http://www.guj.com.br/java/263150-apis---duvida#1375763), veja como esta:

obs1: o system, é somente para saber o que esta acontecendo, testes.
obs2: A class APICAP32 foi incrementada:

import com.sun.jna.win32.StdCallLibrary;

public interface Avicap32 extends StdCallLibrary{
    
    public int capCreateCaptureWindowA(
            String lpszWindowName, //Cria a função da Janela captura
            int dwStye, //estilo da janela
            int x, //..
            int y, //..
            int nWidth, //..
            int nHeight, //posição janela e tamanhio
            int hWndParent, //identificador da janela pai
            int nID); //janela ID
    
     public static final int IDS_CAP_BEGIN = 300;
     public static final int IDS_CAP_END = 301;
     
     public static final short WM_USER = 1024;
     public static final int WM_CAP_START = WM_USER;
     public static final long WM_CAP_STOP = WM_CAP_START + 68;
     public static final int WM_CAP_FILE_SAVEAS = WM_CAP_START +23;
     public static final short HWND_BOTTOM = 1;
     public static final short WM_CAP  = 0x400;     
     public static final long WM_CAP_SEQUENCE = WM_CAP_START + 62;   
     public static final long WM_CAP_COPY = 1054;
     public static final int WM_CAP_EDIT_COPY = WM_CAP_START + 30;
     //public static final int WM_CAP_SINGLE_FRAME = WM_CAP_START;
     //public static final int WM_CAP_PAL_AUTOCREATE = WM_CAP_START;
     //public static final int WM_CAP_PAL_OPEN = WM_CAP_START;
     //public static final int WM_CAP_STOP = WM_USER + 68;
         
     //WS
     public static final int WS_CHILD = 0x40000000;
     public static final int WS_VISIBLE = 0x10000000;
     
     //SWP
     public static final int SWP_NOSIZE = 1;
     public static final short SWP_NOMOVE = 0x2;
     public static final short SWP_NOZORDER = 0x4;    
     
     //Setters
     public static final int WM_CAP_SET_SEQUENCE_SETUP = WM_CAP_START + 64;//long
     public static final int WM_CAP_SEQUENCE_NOFILE = WM_USER + 63;//long
     public static final int WM_CAP_SET_PREVIEW = 0x432;//WM_CAP_START + 50;//50
     public static final int WM_CAP_SET_PREVIEWRATE = 0x434;//WM_CAP_START + 52;//52
     public static final int CAP_SET_VIDEOFORMAT = WM_CAP_START + 45;
     public static final int WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START +20;//long
     public static final int WM_CAP_SET_OVERLAY = 0x433;     
     public static final int WM_CAP_SET_SCALE = 0x435;//WM_CAP_START + 53;     
    //public static final int WM_CAP_SET_CALLBACK_FRAME  = WM_CAP_START;
     //public static final int WM_CAP_FILE_SET_CAPTURE_FILE = WM_CAP_START;
     public static final int WM_CAP_SET_CALLBACK_STATUS  = WM_USER + 3;//long
     public static final int WM_CAP_SET_CALLBACK_ERROR = WM_USER + 2;
 
     //Getters
     public static final int WM_CAP_GET_VIDEOFORMAT = WM_CAP_START + 44;
     public static final int WM_CAP_GET_FRAME = 1084;//long
     //public static final int WM_CAP_DRIVER_GET_VERSION  = WM_USER;
     //public static final int WM_CAP_DRIVER_GET_CAPS = WM_CAP_START;
     public static final int WM_CAP_DRIVER_GET_NAME = WM_USER + 12;///long;
     //public static final int WM_CAP_GET_AUDIOFORMAT = WM_CAP_START;
     //public static final int WM_CAP_GET_MCI_DEVICE  = WM_CAP_START;
     
     //Driver
     public static final int WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;
     public static final int WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;
     
     //DLG
     public static final int WM_CAP_DLG_VIDEOFORMAT = WM_CAP_START + 41 ;
     public static final int WM_CAP_DLG_VIDEOSOURCE = WM_CAP_START + 42; //USBCAM
     public static final int WM_CAP_DLG_VIDEODISPLAY = WM_CAP_START + 43;
     public static final int WM_CAP_DLG_VIDEOCOMPRESSION = WM_CAP_START + 46;
}

[code]

Segue abaixo o código do botão, não há JPainel somente um botão e um JLabel, eu crio o frame:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {

 Frame = new JFrame();  
 Frame.setLayout(null);  
 Frame.setSize(400,400);  
 Frame.setLocation(100, 100);  
 Frame.setTitle("WebCam");  
 Frame.setVisible(true);  


WComponentPeer cpp = (WComponentPeer) Frame.getPeer();
System.out.println("cpp: "+cpp);    
long h = cpp.getHWnd();        
int id = (int)h; 

int hWnd = 0;
int DeviceID = 0;

la.setText(String.valueOf(id));
System.out.println("id(Frame): "+id);

Avicap32 lib = (Avicap32) Native.loadLibrary("AviCap32", Avicap32.class);
User32 libU = (User32) Native.loadLibrary("User32", User32.class);

String DeviceIndex = String.valueOf(DeviceID);
   
try{  
    
    hWnd = lib.capCreateCaptureWindowA(DeviceIndex, Avicap32.WS_VISIBLE | Avicap32.WS_CHILD, 0, 0, 400, 400, id, 0);
    System.out.println("hwnd(capCreateCaptureWinA): "+hWnd);       
}catch(Exception ex){JOptionPane.showMessageDialog(null, ex.toString());}    

if (libU.SendMessageA(hWnd, Avicap32.WM_CAP_DRIVER_CONNECT, DeviceID, 0) != 0){            
         
    libU.SendMessageA(hWnd,Avicap32.WM_CAP_DLG_VIDEOFORMAT, 0, 0);System.out.println("WM_CAP_DLG_VIDEOFORMAT: ");                
    libU.SendMessageA(hWnd,Avicap32.WM_CAP_DLG_VIDEOCOMPRESSION, 0, 0);System.out.println("WM_CAP_DLG_VIDEOFORMAT: "); 
   
    //Escala de visualização
    libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_SCALE, -1, 0);System.out.println("WM_CAP_SET_SCALE: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_SCALE, -1, 0));       
           
    //Configura a resolução da cam
    libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_PREVIEWRATE, 66667, 0);System.out.println("WM_CAP_SET_PREVIEWRATE: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_PREVIEWRATE, 100, 0));

    //Para visualização
    libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_PREVIEW, -1, 0);System.out.println("WM_CAP_SET_PREVIEW: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_PREVIEW, -1, 0));     

    //Paradimencionar janela
    //libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_OVERLAY, -1, 0);System.out.println("WM_CAP_SET_OVERLAY: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_OVERLAY, -1, 0));
    
    libU.SendMessageA(hWnd,Avicap32.WM_CAP_GET_FRAME , 0, 0);System.out.println("WM_CAP_GET_FRAME: "+libU.SendMessageA(hWnd,Avicap32.WM_CAP_GET_FRAME , -1, 0));       
    
    libU.SendMessageA(hWnd,Avicap32.IDS_CAP_BEGIN , 0, 0);
    libU.SendMessageA(hWnd,Avicap32.WS_CHILD , 0, 0);
    libU.SendMessageA(hWnd,Avicap32.WS_CHILD , 0, 0);
    libU.SendMessageA(hWnd,Avicap32.WM_CAP_SET_SEQUENCE_SETUP, 0, 0);
    // Resize window to fit in picturebox
    libU.SetWindowPos(hWnd, Avicap32.HWND_BOTTOM, 0, 0, 400, 400, Avicap32.SWP_NOMOVE | Avicap32.SWP_NOZORDER);                       
          
}else{
    libU.DestroyWindow(hWnd);
    JOptionPane.showMessageDialog(null, "Fora do SendMessageA");
}

}[/code]

To ficando louca JÁ, é BAIDU: http://wenku.baidu.com/view/5f2dc8fc04a1b0717fd5ddc1.html

obs: Desculpe minha ignorância, posso estar enganada por ser nova aqui, mas, neste site realmente não existe a opção para excluir posts no Notícias, artigos e o maior fórum brasileiro sobre Java.

E tem mais, no tópico esta JAVA AVANÇADO e não JAVA BÁSICO, acredito que há respostas para o meu problema.

Obrigada.

não mexo com nada relativo a isso há anos(audio e video no java), mas quando precisei, a própria JMF não me atendia.Sentei com um amigo e fizemos um workaround na JMF para tocar um video com um dado codec e foi um parto(funcionou, mas foi um parto de quintuplos!haha).Sugiro abrir o codigo da JMF e ver como ela faz o serviço.

[quote]libU é a abreviação de library User, e a libA library Apicap. Estas classes não podem ser instanciadas, como podemos ver não há CONSTRUTOR da classe,
são INTERFACES: Elas só podem ser IMPLEMENTADAS e nunca INSTANCIADAS pelo fato serem a mais alta camada de abstração. Contudo, JAMAIS PODEREI USAR ‘NEW’,
pois não existe construtor numa INTERFACE.[/quote]
Tenho plena consciencia dos poderes de uma interface, e o motivo principal de uma interface não ser instanciada é porque ela é um CONTRATO para com a classe de um
comportamento a ser seguido.Mas quando li isso:

libU.SendMessageA(...) pensei que libU era uma classe, ou que vc explicitamente implementaria essa interface em algum lugar.Eu carregaria as libs e
implementaria as interfaces na classe player da aplicação. Aliás, é o que parece que o exemplo que vc postou com o C# faz(não entendo picas de C#, apenas falo da sintaxe parecida)

E quanto a dar um NEW numa interface, tenha cuidado que isso funciona:

[code]
public interface LibU {
String sendMessage();
}

public class XXX{
public String testaLibu(LibU libU){
return libU.sendMessage();
}

public void teste(){
	testaLibu(new LibU(){@Override
	public String sendMessage() {
		return "Toda Classe que implementa uma dada interface pode ser instanciada, no caso uma classe anônima de XXX";
	}});
}

}[/code]

Mas conte-nos qualquer eventual progresso, o assunto é interessante. :slight_smile:

[quote=AmandaBuarqueLima]To ficando louca JÁ, é BAIDU: http://wenku.baidu.com/view/5f2dc8fc04a1b0717fd5ddc1.html

obs: Desculpe minha ignorância, posso estar enganada por ser nova aqui, mas, neste site realmente não existe a opção para excluir posts no Notícias, artigos e o maior fórum brasileiro sobre Java.

E tem mais, no tópico esta JAVA AVANÇADO e não JAVA BÁSICO, acredito que há respostas para o meu problema.

Obrigada.[/quote]

Eu não entendo porque as pessoas ainda insistem em soluções como jmf ou java para questões de multimídia. Usar java com multimídia é descabido porque em 100% dos casos você precisa criar uma interface para um assembly. Vai precisar escrever em c ou então usar c++ para poder controlar a nível de hardware(os drivers ) do dispositivo.

Se utilizar jmf em um projeto, não dou mais que 6 meses para que você tenha necessidade de refatorá-lo, pois a mesma utiliza a vfw para captura de vídeo. Esse modelo já morreu com windows xp. O medelo novo utiliza vmr que é acelerada a hardware com direct3d.

É melhor pagar a licença da dsj: http://www.humatic.de/htools/dsj.htm

Em suma, é muito mais fácil escrever um software em c++ para esse tipo de solução do que escrever um em java. Se precisar de uma linguagem mais moderna, o c# é uma ótima opção também.

O que mais me irrita é quando você pergunta alguma coisa, e pessoa vem com blábláblá… e não te dá nenhuma resposta convivente. O fórum acaba sendo um bate papo. E pior que nao acrescenta nada, e problema continua até que você mesmo insiste e por fim consegue alguma coisa que se caso fosse depender disto, esta ferrado(a)! rsrs

O tal GUI Expert acima escreveu:
Atenção: Expert em que? Foi eu quem acabo de resolver o problema que postei a algumas semanas atrá no fórum: GUJ.com.br - Noticias, artigos e o maior fórum brasileiro sobre java, ual o maior fórum brasileiro, isto faz de mim oque? rrss.

[quote]
Eu não entendo porque as pessoas ainda insistem em soluções como jmf ou java para questões de multimídia. Usar java com multimídia é descabido porque em 100% dos casos você precisa criar uma interface para um assembly. Vai precisar escrever em c ou então usar c++ para poder controlar a nível de hardware(os drivers ) do dispositivo.
[/quote]

Emprimeiro lugar, deixei em negrito acima nos posts, que QUERO UTILIZAR JNA PARA CHAMAR AVICAP.DLL e JÁ CONEÇO CONEXÕES COM JMF, DIRECTSHOW E BLÁBLÁBLA, eu não curto coisa fácil!

Eu também não entendo porque as pessoas se limitam tanto sobre questões que não há solução pronta na internet e rapidamente migram áquilo que encontraram de prontidão.

Certamente, os fóruns, como este, servem para auxiliarem no processo de pesquisa para uma solução. A maioria das pessoas, pelo que vejo, não estão familiarizadas com DOCUMENTAÇÃO. E justamente isso é uma tremenda ironia, visto que o fórum trata diretamente com programação Java, onde os usuários, pelo menos saibam porque estão aqui e fazem alguma coisa, fazem parte, do que meu grande Dr.Prf. sempre nos diz, a geração Y.

A maior causa da crise do Software é justamente a falta de documentação, ou a mania de sair programando qualquer coisa sem ao menos planejar o que ta fazendo, como pelo menos um algoritmo que seja ou por fim a UML.

Bom, parece que eu fui a unica que resolveu o problema então!

Vamos lá no post abaixo:

Objetivo: Abrir a WebCam utilizando JNA e a API nativa do windows avicap.dll[size=18] [/size]

Obs: O resultado abaixo é diretamente o que acabei de fazer, testes. Quando acabar tudo notifico em um pdf com explicações detalhadas sobre cada linha!
[b]Ferramentas que estou utilizando:

  1. Sistema Operativo Windows 7
  2. Netbeans 7.0.1. Pode ser baixado aqui: http://netbeans.org/downloads/
  3. API JNA. Baixe aqui: http://www.4shared.com/file/GmkHyM5v/jna.html
    [/b]

obs: Se você for implementar isso meu filho, pelo amor de Deus, leia antes,não deixe a preguiça lhe pegar!. E to referenciando Wikipedia pelo fato disto não ser artigo cientifico.

Introdução

Irei tratar sobre a conexão com uma webcam nativa(Geralmente para notebooks) ou USB com JNA em Linguagem de Programação Java.

O que é API?
Segundo a wikipedia (2012), é a abreviação para Application Programming Interface (Interface de programação para aplicações). Dentro de uma API contém rotinas, para serem utilizadas em algum aplicativo. Ex: .dll, .jar, etc, podemos chama-las também de bibliotecas.

O que é JNA?
Segundo a Wikipedia (2012), é a abreviação para Java Native Access (Acesso Nativo Java). É uma API do java que nos permite abrirmos outras API que não são nativas do Java como por exemplo dlls do windows.

Isto é bem interessante. Há soluções para este problema como JMF, e DirectShow, que nada mais são que APIs. Mas, eu não gosto de coisa fácil, eu irei utilizar a API Nativa do Windows chamada avicap.dll. Esta API esta localizada na pasta c:\windows\system32\avicap.dll.

Como venho dizendo, antes de sair programando é necessário: 1. Estabelecer um objetivo (O que você quer fazer?); 2. Fazer um levantamento Bibliográfico sobre o assunto, geralmente as monografias atestam o que alguém ja testou e funcionou além da documentação dos fabricantes; 3. Planejar o que irá fazer pode ser UML ou algum algoritmo e por fim 3. Comece a programar na linguagem escolhida.
O fato é que sem se basear em alguma coisa você não faz nada!

Então, o sistema politico da microsoft é complicado pois dificilmente você vê alguma documentação sem um preço a pagar, diferente da politica GNU.
Toda o sistema operacional windows xp até atual, possui a API avicap.dll. E então, o que há dentro dela? Sabemos que é uma Interface, então possuem métodos que se comunicam com o sistema operacional. Então precisamos saber que métodos são estes, afinal ninguém é adivinho. É aqui que precisamos da documentação!
Primeiramente quem a desenvolveu? Se esta no Windows, provavelmente a Microsoft… Procurando na maravilhosa internet chego a isto: http://social.msdn.microsoft.com/Forums/pt-BR/vscsharppt/thread/4df4fc93-a2d5-401b-ab4a- 056e00f47ec7

Muito escasso para o meu caso, não tenho conhecimentos específicos do sistema operacional Windows. Para isso deveria pesquisar sobre o assunto e mesmo assim a documentação seria paga. Pra quem quer investir compensa, porém meu tempo é curto. Então, passamos a auxiliar nosso conhecimento em fóruns e na vasta internet. Por fim cheguei a isto: http://wenku.baidu.com/view/5f2dc8fc04a1b0717fd5ddc1.html . Pode acreditar, fui encontrar alguma implementação com explicação na China! E valeu, passei a entender melhor o tratamento das assinaturas pelo que fato de ser em uma linguagem que entendo a C.

Com isso, consegui mapear a avicap.dll chamando com JNA em programação Java na IDE Netbeans (eu odeio Eclipse). Vamos lá, passo-a-passo:

Obs: O teste foi realizado com uma WebCam USB e na CAM do meu noteboock! Certifique-se de que a USB que você vai plugar no seu computador não tenha drive nenhum!

Para este caso USB, vamos criar um aplicativo que receberá a imagem da cam. Será um pequeno Software Universal, provavelmente irá funcionar para todos os dispositivos de imagem USB que poderão ser plugados em seu computador. Isso eu não testei ainda, mas vou dar uma de profeta. Porque será hein?! rs

  1. Plug a WebCam USB no seu computador.
  2. Abra Painel de controles/Gerenciador de Dispositivos

Se você não instalou o Drive, o sinal de dependência marcada por um simbolo de “!” exclamação irá aparecer. Clique com o Direito e deixe pesquisar automaticamente na internet o drive de conexão USB. No meu caso é o EZCam III, é uma merda, mas tudo bem.

  1. Abra o netbeans

  2. Crie um novo projeto e nomei. O meu é WebCamU

  3. Gosto de programar em Camadas. Vamos criar 2 pacotes: webcamu.interfaces e webcamu.view

  4. Pacote webcamu.interfaces
    Vamos criar as interfaces necessárias para a aplicação. A primeira delas chamo de MapHWND. Esta contém o mapeamento necessário do HENDLE para a janela. Pesquise sobre isto, nada mais é que o identificador da janela no ambiente windows:

A partir daqui, salve o JNA dentro do projeto e importe para o projeto. No pacote Bibliotecas clique com o direito em AdicionarJar/Pasta… e busque a JNA.jar

[code]import com.sun.jna.FromNativeContext;
import com.sun.jna.Pointer;
import com.sun.jna.PointerType;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIFunctionMapper;
import com.sun.jna.win32.W32APITypeMapper;
import java.util.HashMap;
import java.util.Map;

public interface MapHWND extends StdCallLibrary{
Map UNICODE_OPTIONS = new HashMap() {
{
put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
}
};

Map ASCII_OPTIONS = new HashMap() {

    {
        put(OPTION_TYPE_MAPPER, W32APITypeMapper.ASCII);
        put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.ASCII);
    }
};

Map DEFAULT_OPTIONS = Boolean.getBoolean("w32.ascii") ? ASCII_OPTIONS
        : UNICODE_OPTIONS;


public static class HANDLE extends PointerType {

    @Override
    public Object fromNative(Object nativeValue, FromNativeContext context) {
        Object o = super.fromNative(nativeValue, context);
        if (INVALID_HANDLE_VALUE.equals(o)) {
            return INVALID_HANDLE_VALUE;
        }
        return o;
    }
}

public static class HWND extends HANDLE {
}

HANDLE INVALID_HANDLE_VALUE = new HANDLE() {

    {
        super.setPointer(Pointer.createConstant(-1));
    }

    @Override
    public void setPointer(Pointer p) {
        throw new UnsupportedOperationException("Immutable reference");
    }
};    

}[/code]

A segunda interface chamo de Avicap32. Nela esta o mapeamento, não esta completo, do que há dentro da DLL:

[code]import com.sun.jna.win32.StdCallLibrary;

public interface Avicap32 extends StdCallLibrary, MapHWND{

//Métodos
public int capCreateCaptureWindowA(
        String lpszWindowName, //Cria a função da Janela captura
        int dwStye, //estilo da janela
        int x, //..
        int y, //..
        int nWidth, //..
        int nHeight, //posição janela e tamanhio
        int hWndParent, //identificador da janela pai
        int nID); //janela ID

public boolean capGetDriverDescription (
            int wDriverIndex,
            String lpszName,
            int cbName,
            String lpszVer,
            int cbVer);

/*        
public int capSetCallbackOnError (int hwnd, int fpProc);
public int capSetCallbackOnStatus(int hwnd, int fpProc);
public int capSetCallbackOnYield (int hwnd, int fpProc);
public int capSetCallbackOnFrame (int hwnd, int fpProc);

public int capSetCallbackOnVideoStream(int hwnd, int fpProc);
public int capSetCallbackOnWaveStream (int hwnd, int fpProc);
public int capSetCallbackOnCapControl (int hwnd, int fpProc);
public int capSetUserData(int hwnd, int lUser);
public int capGetUserData(int hwnd);
public int capDriverConnect(int hwnd, int I);//I é do tipo Word

public int capDriverDisconnect(int hwnd);
public int capDriverGetName(int hwnd, int szName, int wSize);//wSize é fo tipo Word
public int capDriverGetVersion(int hwnd, int szVer, int wSize);//""
public int capDriverGetCaps(int hwnd, int s, int wSize);//""

public int capFileSetCaptureFile(int hwnd, int szName);
public int capFileGetCaptureFile(int hwnd, int szName, int wSize);//""
public int capFileAlloc(int hwnd, int dwSize);
public int capFileSaveAs(int hwnd, int szName);
public int capFileSetInfoChunk(int hwnd, int lpInfoChunk);
public int capFileSaveDIB(int hwnd, int szName);

public int capEditCopy(int hwnd);

public int capSetAudioFormat(int hwnd, int s, int wSize);//""
public int capGetAudioFormat(int hwnd, int s, int wSize);//""
public int capGetAudioFormatSize(int hwnd);

public int capDlgVideoFormat(int hwnd);
public int capDlgVideoSource(int hwnd);
public int capDlgVideoDisplay(int hwnd);
public int capDlgVideoCompression(int hwnd);

public int capGetVideoFormat(int hwnd, int s, int wSize);//""
public int capGetVideoFormatSize(int hwnd);
public int capSetVideoFormat(int hwnd, int s, int wSize);//""

public int capPreview(int hwnd, int f);//""
public int capPreviewRate(int hwnd, int wMS);//""
public int capOverlay(int hwnd, int f);//""
public int capPreviewScale(int hwnd, int f);//""
public int capGetStatus(int hwnd, int s, int wSize);//""
public int capSetScrollPos(int hwnd, int lpP);

public int capGrabFrame(int hwnd);
public int capGrabFrameNoStop(int hwnd);

public int capCaptureSequence(int hwnd);
public int capCaptureSequenceNoFile(int hwnd);
public int capCaptureStop(int hwnd);
public int capCaptureAbort(int hwnd);

public int capCaptureSingleFrameOpen(int hwnd);
public int capCaptureSingleFrameClose(int hwnd);
public int capCaptureSingleFrame(int hwnd);

public int capCaptureGetSetup(int hwnd, int s, int wSize);//""
public int capCaptureSetSetup(int hwnd, int s, int wSize);//""

public int capSetMCIDeviceName(int hwnd, int szName);
public int capGetMCIDeviceName(int hwnd, int szName, int wSize);//""

public int capPaletteOpen(int hwnd, int szName);
public int capPaletteSave(int hwnd, int szName);
public int capPalettePaste(int hwnd);
public int capPaletteAuto(int hwnd, int iFrames, int iColors);//iFrames é Word
public int capPaletteManual(int hwnd, int fGrab, int iColors);//fGrab é word
*/


//********************************* Constantes ********************************
/******************************************************************************/
public static final short WM_USER                       = 1024;
public static final int WM_CAP_START                    = WM_USER;
public static int WS_CHILD                              = 0x40000000;
public static int WS_VISIBLE                            = 0x10000000;
public static int SWP_NOZORDER                          = 0x4;
public static int HWND_BOTTOM                           = 1;
public static int SWP_NOMOVE                            = 0x2;
        

// Defines start of the message range
public static final int WM_CAP_GET_CAPSTREAMPTR         = (WM_CAP_START+  1);
public static final int WM_CAP_SET_CALLBACK_ERROR       = (WM_CAP_START+  2);
public static final int WM_CAP_SET_CALLBACK_STATUS      = (WM_CAP_START+  3);
public static final int WM_CAP_SET_CALLBACK_YIELD       = (WM_CAP_START+  4);
public static final int WM_CAP_SET_CALLBACK_FRAME       = (WM_CAP_START+  5);
public static final int WM_CAP_SET_CALLBACK_VIDEOSTREAM = (WM_CAP_START+  6);
public static final int WM_CAP_SET_CALLBACK_WAVESTREAM  = (WM_CAP_START+  7);  
public static final int WM_CAP_GET_USER_DATA            = (WM_CAP_START+  8);  
public static final int WM_CAP_SET_USER_DATA            = (WM_CAP_START+  9);


public static final int WM_CAP_DRIVER_CONNECT           = 0x40a;//(WM_CAP_START+  10);  
public static final int WM_CAP_DRIVER_DISCONNECT        = (WM_CAP_START+  11);  
public static final int WM_CAP_DRIVER_GET_NAME          = (WM_CAP_START+  12);
public static final int WM_CAP_DRIVER_GET_VERSION       = (WM_CAP_START+  13);  
public static final int WM_CAP_DRIVER_GET_CAPS          = (WM_CAP_START+  14);  


public static final int WM_CAP_FILE_SET_CAPTURE_FILE    = (WM_CAP_START+  20);  
public static final int WM_CAP_FILE_GET_CAPTURE_FILE    = (WM_CAP_START+  21);
public static final int WM_CAP_FILE_ALLOCATE            = (WM_CAP_START+  22);  
public static final int WM_CAP_FILE_SAVEAS              = (WM_CAP_START+  23);  
public static final int WM_CAP_FILE_SET_INFOCHUNK       = (WM_CAP_START+  24);  
public static final int WM_CAP_FILE_SAVEDIB             = (WM_CAP_START+  25);  

public static final int WM_CAP_EDIT_COPY                = (WM_CAP_START+  30);

public static final int WM_CAP_SET_AUDIOFORMAT          = (WM_CAP_START+  35);
public static final int WM_CAP_GET_AUDIOFORMAT          = (WM_CAP_START+  36);

public static final int WM_CAP_DLG_VIDEOFORMAT          = (WM_CAP_START+  41);
public static final int WM_CAP_DLG_VIDEOSOURCE          = (WM_CAP_START+  42);
public static final int WM_CAP_DLG_VIDEODISPLAY         = (WM_CAP_START+  43);
public static final int WM_CAP_GET_VIDEOFORMAT          = (WM_CAP_START+  44);
public static final int WM_CAP_SET_VIDEOFORMAT          = (WM_CAP_START+  45);
public static final int WM_CAP_DLG_VIDEOCOMPRESSION     = (WM_CAP_START+  46);

public static final int WM_CAP_SET_PREVIEW              = 0x432;//(WM_CAP_START+  50);  
public static final int WM_CAP_SET_OVERLAY              = (WM_CAP_START+  51);  
public static final int WM_CAP_SET_PREVIEWRATE          = 0x434;//(WM_CAP_START+  52);  
public static final int WM_CAP_SET_SCALE                = 0x435;//(WM_CAP_START+  53);  
public static final int WM_CAP_GET_STATUS               = (WM_CAP_START+  54);  
public static final int WM_CAP_SET_SCROLL               = (WM_CAP_START+  55);  

public static final int WM_CAP_GRAB_FRAME               = (WM_CAP_START+  60);
public static final int WM_CAP_GRAB_FRAME_NOSTOP        = (WM_CAP_START+  61);

public static final int WM_CAP_SEQUENCE                 = (WM_CAP_START+  62);
public static final int WM_CAP_SEQUENCE_NOFILE          = (WM_CAP_START+  63);
public static final int WM_CAP_SET_SEQUENCE_SETUP       = (WM_CAP_START+  64);
public static final int WM_CAP_GET_SEQUENCE_SETUP       = (WM_CAP_START+  65);
public static final int WM_CAP_SET_MCI_DEVICE           = (WM_CAP_START+  66);
public static final int WM_CAP_GET_MCI_DEVICE           = (WM_CAP_START+  67);
public static final int WM_CAP_STOP                     = (WM_CAP_START+  68);
public static final int WM_CAP_ABORT                    = (WM_CAP_START+  69);

public static final int WM_CAP_SINGLE_FRAME_OPEN        = (WM_CAP_START+  70);
public static final int WM_CAP_SINGLE_FRAME_CLOSE       = (WM_CAP_START+  71);
public static final int WM_CAP_SINGLE_FRAME             = (WM_CAP_START+  72);

public static final int WM_CAP_PAL_OPEN                 = (WM_CAP_START+  80);
public static final int WM_CAP_PAL_SAVE                 = (WM_CAP_START+  81);
public static final int WM_CAP_PAL_PASTE                = (WM_CAP_START+  82);
public static final int WM_CAP_PAL_AUTOCREATE           = (WM_CAP_START+  83);
public static final int WM_CAP_PAL_MANUALCREATE         = (WM_CAP_START+  84);

// Following added post VFW 1.1
public static final int WM_CAP_SET_CALLBACK_CAPCONTROL  = (WM_CAP_START+  90);

// Defines end of the message range
public static final int WM_CAP_END                      = WM_CAP_SET_CALLBACK_CAPCONTROL;


public static final int IDS_CAP_BEGIN               = 300; //(* "Capture Start" *)
public static final int IDS_CAP_END                 = 301; //(* "Capture End" *) 

public static final int IDS_CAP_INFO = 401; //(* “%s” )
public static final int IDS_CAP_OUTOFMEM = 402; //(
“Out of memory” )
public static final int IDS_CAP_FILEEXISTS = 403; //(
“File ‘%s’ exists – overwrite it?” )
public static final int IDS_CAP_ERRORPALOPEN = 404; //(
“Error opening palette ‘%s’” )
public static final int IDS_CAP_ERRORPALSAVE = 405; //(
“Error saving palette ‘%s’” )
public static final int IDS_CAP_ERRORDIBSAVE = 406; //(
“Error saving frame ‘%s’” )
public static final int IDS_CAP_DEFAVIEXT = 407; //(
“avi” )
public static final int IDS_CAP_DEFPALEXT = 408; //(
“pal” )
public static final int IDS_CAP_CANTOPEN = 409; //(
“Cannot open ‘%s’” )
public static final int IDS_CAP_SEQ_MSGSTART = 410; //(
“Select OK to start capture\nof video sequence\nto %s.” )
public static final int IDS_CAP_SEQ_MSGSTOP = 411; //(
“Hit ESCAPE or click to end capture” *)

public static final int IDS_CAP_VIDEDITERR = 412; //(* “An error occurred while trying to run VidEdit.” )
public static final int IDS_CAP_READONLYFILE = 413; //(
“The file ‘%s’ is a read-only file.” )
public static final int IDS_CAP_WRITEERROR = 414; //(
“Unable to write to file ‘%s’.\nDisk may be full.” )
public static final int IDS_CAP_NODISKSPACE = 415; //(
“There is no space to create a capture file on the specified device.” )
public static final int IDS_CAP_SETFILESIZE = 416; //(
“Set File Size” )
public static final int IDS_CAP_SAVEASPERCENT = 417; //(
“SaveAs: %2ld%% Hit Escape to abort.” *)

public static final int IDS_CAP_DRIVER_ERROR = 418; //(* Driver specific error message *)

public static final int IDS_CAP_WAVE_OPEN_ERROR = 419; //(* “Error: Cannot open the wave input device.\nCheck sample size, frequency, and channels.” )
public static final int IDS_CAP_WAVE_ALLOC_ERROR = 420; //(
“Error: Out of memory for wave buffers.” )
public static final int IDS_CAP_WAVE_PREPARE_ERROR = 421; //(
“Error: Cannot prepare wave buffers.” )
public static final int IDS_CAP_WAVE_ADD_ERROR = 422; //(
“Error: Cannot add wave buffers.” )
public static final int IDS_CAP_WAVE_SIZE_ERROR = 423; //(
“Error: Bad wave size.” *)

public static final int IDS_CAP_VIDEO_OPEN_ERROR = 424; //(* “Error: Cannot open the video input device.” )
public static final int IDS_CAP_VIDEO_ALLOC_ERROR = 425; //(
“Error: Out of memory for video buffers.” )
public static final int IDS_CAP_VIDEO_PREPARE_ERROR = 426; //(
“Error: Cannot prepare video buffers.” )
public static final int IDS_CAP_VIDEO_ADD_ERROR = 427; //(
“Error: Cannot add video buffers.” )
public static final int IDS_CAP_VIDEO_SIZE_ERROR = 428; //(
“Error: Bad video size.” *)

public static final int IDS_CAP_FILE_OPEN_ERROR = 429; //(* “Error: Cannot open capture file.” )
public static final int IDS_CAP_FILE_WRITE_ERROR = 430; //(
“Error: Cannot write to capture file. Disk may be full.” )
public static final int IDS_CAP_RECORDING_ERROR = 431; //(
“Error: Cannot write to capture file. Data rate too high or disk full.” )
public static final int IDS_CAP_RECORDING_ERROR2 = 432; //(
“Error while recording” )
public static final int IDS_CAP_AVI_INIT_ERROR = 433; //(
“Error: Unable to initialize for capture.” )
public static final int IDS_CAP_NO_FRAME_CAP_ERROR = 434; //(
“Warning: No frames captured.\nConfirm that vertical sync interrupts\nare configured and enabled.” )
public static final int IDS_CAP_NO_PALETTE_WARN = 435; //(
“Warning: Using default palette.” )
public static final int IDS_CAP_MCI_CONTROL_ERROR = 436; //(
“Error: Unable to access MCI device.” )
public static final int IDS_CAP_MCI_CANT_STEP_ERROR = 437; //(
“Error: Unable to step MCI device.” )
public static final int IDS_CAP_NO_AUDIO_CAP_ERROR = 438; //(
“Error: No audio data captured.\nCheck audio card settings.” )
public static final int IDS_CAP_AVI_DRAWDIB_ERROR = 439; //(
“Error: Unable to draw this data format.” )
public static final int IDS_CAP_COMPRESSOR_ERROR = 440; //(
“Error: Unable to initialize compressor.” )
public static final int IDS_CAP_AUDIO_DROP_ERROR = 441; //(
“Error: Audio data was lost during capture, reduce capture rate.” *)

//(* status string IDs )
public static final int IDS_CAP_STAT_LIVE_MODE = 500; //(
“Live window” )
public static final int IDS_CAP_STAT_OVERLAY_MODE = 501; //(
“Overlay window” )
public static final int IDS_CAP_STAT_CAP_INIT = 502; //(
“Setting up for capture - Please wait” )
public static final int IDS_CAP_STAT_CAP_FINI = 503; //(
“Finished capture, now writing frame %ld” )
public static final int IDS_CAP_STAT_PALETTE_BUILD = 504; //(
“Building palette map” )
public static final int IDS_CAP_STAT_OPTPAL_BUILD = 505; //(
“Computing optimal palette” )
public static final int IDS_CAP_STAT_I_FRAMES = 506; //(
“%d frames” )
public static final int IDS_CAP_STAT_L_FRAMES = 507; //(
“%ld frames” )
public static final int IDS_CAP_STAT_CAP_L_FRAMES = 508; //(
“Captured %ld frames” )
public static final int IDS_CAP_STAT_CAP_AUDIO = 509; //(
“Capturing audio” )
public static final int IDS_CAP_STAT_VIDEOCURRENT = 510; //(
“Captured %ld frames (%ld dropped) %d.%03d sec.” )
public static final int IDS_CAP_STAT_VIDEOAUDIO = 511; //(
“Captured %d.%03d sec. %ld frames (%ld dropped) (%d.%03d fps). %ld audio bytes (%d,%03d sps)” )
public static final int IDS_CAP_STAT_VIDEOONLY = 512; //(
“Captured %d.%03d sec. %ld frames (%ld dropped) (%d.%03d fps)” )
public static final int IDS_CAP_STAT_FRAMESDROPPED = 513; //(
“Dropped %ld of %ld frames (%d.%02d%%) during capture.” *)

}[/code]

A outra interface é a USER32 que mapeia a dll user32.dll que irei usar para setar as configurações, porque estou usando as constantes da interface e não os métodos:

[code]import com.sun.jna.win32.StdCallLibrary;

public interface User32 extends StdCallLibrary, MapHWND{

public boolean DestroyWindow(int hndw);  

public boolean ShowWindow(long hWnd, int nCmdShow);

public HWND FindWindow(String winClass, String title);

public int SetWindowPos(
        int hwnd, 
        int hWndInsertAfter, 
        int x, 
        int y, 
        int cx, 
        int cy, 
        int wFlags);  

public int SendMessageA(
        int hwnd, 
        int wMsg, 
        int wParam, 
        Object lParam);    

}
[/code]

As três interfaces estão prontas.

No pacote webcamu.views, adicione um Formulário JFrame, iremos trabalhar com GUI. Adicione um botão e um rótulo da paleta Controles Swing.

Dê dois clique no botão ou se preferir, na paleta propriedade do Botão, clique em eventos e acione ActionPerformed.
Adicione este código:

[code] Frame = new JFrame();
Frame.setLayout(null);
Frame.setSize(320,240);
Frame.setLocation(100, 100);
Frame.setTitle(“WebCam”);
//Frame.setContentPane(getJContentPane());
Frame.setVisible(true);

WComponentPeer cpp = (WComponentPeer) Frame.getPeer();
//cpp.setEnabled(true);
//cpp.setVisible(true);    
System.out.println("cpp: "+cpp);    
long h = cpp.getHWnd();        
int id = (int)h; 

int hWnd = 0;
int DeviceID = 0;

la.setText(String.valueOf(id));
System.out.println("id(Frame): "+id);

Avicap32 libA = (Avicap32) Native.loadLibrary("AviCap32", Avicap32.class);
User32 libU = (User32) Native.loadLibrary("User32", User32.class);

String DeviceIndex = String.valueOf(DeviceID);
   
try{  
    
    hWnd = libA.capCreateCaptureWindowA(DeviceIndex, Avicap32.WS_VISIBLE | Avicap32.WS_CHILD, 0, 0, 320, 240, id, 0);
    System.out.println("hwnd(capCreateCaptureWinA): "+hWnd);       
}catch(Exception ex){JOptionPane.showMessageDialog(null, ex.toString());}    

    
//Connect to device
if (libU.SendMessageA(hWnd, Avicap32.WM_CAP_DRIVER_CONNECT, DeviceID, 0) != 0){            
                  
    //libU.SendMessageA(hWnd, Avicap32.WM_CAP_GET_VIDEOFORMAT, -1, 0);System.out.println("WM_CAP_SEQUENCE_SETUP: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_SEQUENCE_SETUP, 0, 0));
    
    libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_SCALE, -1, 0);System.out.println("WM_CAP_SET_SCALE: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_SCALE, -1, 0));       
   
    libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_OVERLAY, -1, 0);System.out.println("WM_CAP_SET_OVERLAY: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_OVERLAY, -1, 0));
    //libU.SendMessageA(hWnd, Avicap32.WM_CAP_DLG_VIDEOFORMAT, 0, 0);System.out.println("WM_CAP_DLG_VIDEOFORMAT: ");                
    //ibU.SendMessageA(hWnd, Avicap32.WM_CAP_DLG_VIDEOCOMPRESSION, 0, 0);System.out.println("WM_CAP_DLG_VIDEOCOMPRESSION: "); 
    //libU.SendMessageA(hWnd, Avicap32.IDS_CAP_BEGIN , 0, 0);
    
    //libU.SendMessageA(hWnd, Avicap32.WM_CAP_SEQUENCE , -1, 0);System.out.println("WM_CAP_SEQUENCE: "+libU.SendMessageA(hWnd,Avicap32.WM_CAP_SEQUENCE , 0, 0));       
   while(true){
    libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_PREVIEWRATE, 66, 0);System.out.println("WM_CAP_SET_PREVIEWRATE: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_PREVIEWRATE, 100, 0));
    libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_PREVIEW, -1, 0);System.out.println("WM_CAP_SET_PREVIEW: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_PREVIEW, -1, 0));     
    
    //libU.SendMessageA(hWnd, Avicap32.WM_CAP_SET_OVERLAY, 1, 0);System.out.println("WM_CAP_SET_OVERLAY: "+libU.SendMessageA(hWnd,Avicap32.WM_CAP_SET_OVERLAY, 1, 0));
    libU.SendMessageA(hWnd, Avicap32.WM_CAP_GRAB_FRAME, -1, 0);System.out.println("WM_CAP_GRAB_FRAME: "+libU.SendMessageA(hWnd, Avicap32.WM_CAP_GRAB_FRAME , -1, 0));       
    libU.SetWindowPos(hWnd, Avicap32.HWND_BOTTOM, 0, 0, 320, 240, Avicap32.SWP_NOMOVE | Avicap32.SWP_NOZORDER);
    System.out.println("SetWindowPos: "+libU.SetWindowPos(hWnd, 0, 0, 0, 320, 240, Avicap32.SWP_NOMOVE | Avicap32.SWP_NOZORDER));
   }
          
}else{
    //Error connecting to device close window
    libU.DestroyWindow(hWnd);
    JOptionPane.showMessageDialog(null, "Fora do SendMessageA");
}
[/code]

Note o seguinte, a constante WM_CAP_DLG_VIDEOSOURCE, trata do dispositivo USB. Automaticamente, se não identificado a precença nativa da Webcam (como o caso do notebook), será aberto uma janela para especificar o drive existente. Caso prefira podera cliar uma rotina identificando tais configurações como deixei comentado o formato do video e a compressão. Interessante isso.

Acerte as dependências que faltarem e VOILÁ.

  1. Dê o RUN da aplicação.
  2. Clique no botão
  3. No meu caso é a USB, especifiquei o drive que instalei no Gerenciador de Dispositivos e funcionou.

Não utilizei JMF nem DirectShow para isso, foi mapeamento da API Nativa do windows avicap.dll para abrir imagem. Como você pode perceber, com ela tratamos de audio e video.

Além disso, existe a User32 e muitas outras, que com a documentações, você poderá fazer coisas impressionantes com o sistema operativo, neste caso Windows.
Sobre algumas informações adicionais sobre algumas dll poderá encontrar neste site: http://www.andreavb.com digite a API que vc quer, não há muitas (http://www.andreavb.com/API_USER32.html), porém ajudou-me muito. A linguagem existente de mapeamento estão em VB, super facil de entender.

Problema Solucionado!

É isso. Estou agora na Opencv.

Referência

MICROSOFT (Org.). Acessar imagem da WebCam. Disponível em: <http://social.msdn.microsoft.com/Forums/pt-BR/vscsharppt/thread/4df4fc93-a2d5-401b-ab4a- 056e00f47ec7>. Acesso em: 10 jan. 2010.

WIKIPEDIA (Org.). API. Disponível em: http://pt.wikipedia.org/wiki/API. Acesso em: 29 jan. 2012.

WIKIPEDIA (Org.). JNA. Disponível em: http://en.wikipedia.org/wiki/Java_Native_Access. Acesso em: 29 jan. 2012.

Uma vez usei a AviCap para capturar vídeo numa aplicação para engenharia. A idéia era fotografar buracos e automaticamente obter suas coordenadas GPS.
Hoje em dia isso poderia ser facilmente feito com um celular, mas na época, tivemos que usar uma placa de GPS dedicada e um notebook com uma webcam.
Uma das grandes vantagens dessa API é que é muito fácil.

Outra opção que eu gosto é a do DirectShow, e já até existe binding para ela com Java:
http://www.humatic.de/htools/dsj.htm

O DirectShow também é nativo do Windows, e é usado pela AviCap.
Ele era parte do DirectX, que é a principal tecnologia multimídia da MS, mas devido a sua importância, agora é parte da Windows API.

Na verdade, a idéia do AviCap era tornar a captura da webcam mais fácil do que com DirectShow.
Se você não curte coisa fácil, está indo para o lado errado, hehehhehehe.

Se quiser algo realmente difícil, estude um hardware específico e escreva um driver para uma webcam genérica.

Bom saber de mais gente usando a OpenCV. Estou usando ela com meu mestrado.
Para a captura, uso os drivers da PrimeSense e a OpenNI, assim capturo as imagens e a profundidade diretamente do Kinect. :slight_smile:

Já tenho um conjunto de métodos para integrar com a OpenCV, se alguém tiver interesse, é só entrar em contato.

E, PS: Eu concordo com o Julio. É uma completa perda de tempo escrever aplicações assim para Java. Vão ficar difíceis de manter e você provavelmente fará tudo com mais tranquilidade usando diretamente o C++. Se você gosta de coisas difíceis, o que ainda está fazendo com o Java? Pegue uma linguagem não gerenciada, e você terá que lidar com ponteiros, em compensação, fará programas com performance sem precendentes.

Não precisa reclamar do fórum. Lembre-se que:
a) Esse era um problema extremamente específico, que era só seu. É natural que ninguém queira baixar todo seu código, entender todo seu ambiente, e começar a trabalhar no seu projeto.
b) As pessoas te ajudam no fórum porque querem, de boa vontade. Não porque elas precisem.
c) O julio te orientou que usar multimídia em Java é o caminho errado, e ele tem direito a opinião dele;
d) Ninguém deveria depender de uma resposta de fórum;
e) Para alguém cobrando uma ajuda com tanta vêemencia, você tem poucas postagens ajudando outros usuários.

Não tem necessidade de ser rude. O post no final acabou ótimo, sua solução ficou interessante. Pena que só funcione em Windows, o que vai totalmente contra o propósito de usar Java, na opinião da comunidade em geral (eu mesmo não tenho nada contra, vivo sonhando com um binding Direct X em Java).