Webcam lib, video for java, api java jna pour avicap.dll, msvfw.dll, vfw.h

5/5 (14 avis)

Vue 26 197 fois - Téléchargée 2 166 fois

Description

"Certaines webcams (Philips SPC520NC...) ne fonctionnent pas avec JMF", dont la mienne, d'après ce constat j'ai réalisé une librairie utilisant du code natif via JNA basée sur avicap.dll et vfw.h.

Cette librairie fonctionnant exclusivement sous win32 permet d'accéder et de communiquer avec le driver d'une ou plusieurs webcam.
Aussi pas moyen à l'heure actuelle de l'intégrer avec AWT ou Swing, seulement avec la SWT.
Le développement continue...

Je me suis basé sur la description de Video For Window dont la doc est disponible ici : http://msdn2.microsoft.com/en-us/library/ms712699%28VS.85%29.aspx

La classe org.hypik.webcamlib.DeviceManager permet de lister tous les drivers installés en renvoyant des instances de org.hypik.webcamlib.device.Device.
Cette dernière propose une API permettant de:
- Créer la fenêtre de la webcam avec les différents styles possibles,
- Se connecter à la webcam,
- Demander à la webcam de copier la frame courante dans le presse-papier,
- Se déconnecter,
- De s'aboner aux erreurs renvoyées par la webcam,
- De s'abonner aux messages de status,
- De s'abonner à chaque frame affichées,
- De récupérer une frame,
- Détruire la fenêtre,
- D'ouvrir les boites de dialogues de configuration proposées par le driver,
- De dispatcher les messages du système vers la fenêtre de la webcam si on utilise pas la SWT ( marche pas avec AWT/Swing)

Le package org.hypik.webcam.compressor permet de décompresser une frame dans un certain format vers un autre. L'api permet de:
-Lister tous les décompresseurs disponible,
-Recherche un décompresseur pour un format d'entrée vers un format de sortie,
-Bien sur de décompresser une frame,

Je vous propose trois classes de tests (Simple, SWT et AWT) pour bien prendre en main la librairie.
Elles peuvent être lancées directement en renommant les fichiers contenu dans bin en .bat.
Pour le test utilisant la swt il vous faut la librairie disponible sur http://www.eclipse.org/swt/

Ci-dessous le code du simple test.

J'espère pouvoir faire évoluer cette librairie rapidement.
Vos retours/suggestions sont les bienvenus.
NB: Toutes mes excuses au pingouin mais j'ai pas le courage de me pencher sur video4linux.
Pierrick Hymbert

Source / Exemple :


/**

  • Webcam Library, version 1.2
  • The easiest way to manage webcam devices in java.
  • (c) 2008 Pierrick HYMBERT <pierrick.hymbert@gmail.com>
  • This library is "PROVIDED AS IS" without guaranty of any kinds.
  • Webcam Library is freely distribuable under the terms of an MIT-style license.
  • Visit www.hypik.fr
  • /
package org.hypik.webcamlib.test.sample; import java.util.List; import org.hypik.webcamlib.DeviceManager; import org.hypik.webcamlib.device.Device; import org.hypik.webcamlib.device.IWS; import org.hypik.webcamlib.device.listener.DeviceErrorListener; import org.hypik.webcamlib.device.listener.DeviceStatusListener; import com.sun.jna.Native; /**
  • This class have only a main method to start all webcam devices found in a webcam preview window.
  • @author Pierrick Hymbert <a href="mailto:pierrick.hymbert@gmail.com">Contact</a>
*
  • /
public class SimpleTest { /**
  • Start all webcam devices found in a webcam preview window
  • @param args N/A
  • /
public static void main(String[] args){ // Prevent VM crash Native.setProtected(true); // List all devices List<Device> devices = DeviceManager.getAllDevices(); try { // Print all device driver name and version for (Device device : devices) { System.out.println("Found: " + device); } } catch (Exception e) { e.printStackTrace(); } // Check if at least one device is found if( devices.size() == 0 ){ System.err.println("No device found."); System.exit(0); } // Start all webcam preview int x = 0, y = 0; for (Device device : devices) { // Add the listeners device.addDeviceErrorListener(errorListener); device.addDeviceStatusListener(statusListener); // Show preview device.showPreview(x, y, 300, 300, IWS.WS_OVERLAPPEDWINDOW | IWS.WS_VISIBLE, device.getName(), 0, 0); x += 320; if( x > 800 ){ x = 0; y += 320; } } // Run all devices loop int deviceDisposed = 0; while( deviceDisposed < devices.size()){ deviceDisposed = 0; for (Device device : devices) { if( !device.isDisposed() ){ device.readAndDispatch(); }else{ deviceDisposed++; } } } System.exit(0); } /**
  • The device error listener.
  • /
private static DeviceErrorListener errorListener = new DeviceErrorListener(){ /**
  • Fire the listener that the device throws an error message.
  • @param device
  • The device in error state.
  • @param errorId
  • The error id is one of the constants below.
  • @param errorMessage
  • The error message.
  • /
public void deviceError(Device device, int errorId, String errorMessage) { System.err.println(device + "->" + errorId + ": " + errorMessage); } }; /**
  • The device error listener.
  • /
private static DeviceStatusListener statusListener = new DeviceStatusListener(){ /**
  • Fire the listener that the device fire a status message.
  • @param device
  • The device in error state.
  • @param statusId
  • The status id is one of the constants below.
  • @param statusMessage
  • The status message.
  • /
public void deviceStatus(Device device, int statusId, String statusMessage){ System.out.println(device + "->" + statusId + ": " + statusMessage); } }; }

Conclusion :


A oui... Il vous faut au moins une webcam!!!

Codes Sources

A voir également

Ajouter un commentaire Commentaires
plgarciafr Messages postés 1 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 30 mars 2011
30 mars 2011 à 08:33
Bonjour,
Merci d'avoir mis à disposition ce code.
Je l'ai fait fonctionner sur une machines Windows 7 64 bits, sans grande difficultés en mettant le bon jar jna et les bonnes dll. En fait j'ai trouvé à cette adresse http://java.net/downloads/jna/3.2.7/jna.jar un jar jna qui traite de toutes les plateformes (win 32 et 64, linux etc)
J'ai eu un petit souci dans le code du callback dans lequel la taille du buffer n'était pas correcte. J'ai contourné le problème en trafiquant cette taille ainsi "videoHDR.dwBufferLength &= 0x00000000ffffffffL;" La taille est répétée sur le mot de proid fort et le mot de poids faible, je masque celle sur le mot de poids fort. J'aurais préféré trouver la cause mais je manque encore de compétences sur les libs user32, avicap et JNA.
J'ai aussi eu un souci sur la compilation de la classe test dans laquelle IDevice.WS_SHELL_TRIM n'existe pas, la classe device mise à disposition n'est peut-être pas la dernière.

Encore une fois merci pour ces sources.
Pascal Garcia
zibo3 Messages postés 57 Date d'inscription mercredi 18 juin 2003 Statut Membre Dernière intervention 7 octobre 2009
7 oct. 2009 à 16:15
Bonjour je suis intéressé par une partie de ton code. Dans la class User32Native, tu déclare une fonction :
public int SendMessageA(HWND hWnd, int wMsg, WPARAM wParam, String lParam);

or quand j'utilise cette fonction il semblerait que le string passer en paramètre soit mal reçu par la fenêtre et que ce soit le pointeur du string et non son contenu qui soit envoyé.
As tu une solution ???

Merci
yep666 Messages postés 3 Date d'inscription dimanche 2 janvier 2005 Statut Membre Dernière intervention 6 mai 2009
6 mai 2009 à 16:37
Amenophis, il te suffit de modifier le code de la classe de test pour obtenir ce que tu veux. C'est pas un problème lié à son API à proprement parler.
En revanche dommage que l'enregistrement d'une vidéo ne fonctionne pas. Si un jour j'ai le temps je me pencherais sur la question.
Pour le reste ça fait le job.
Amenophis77 Messages postés 4 Date d'inscription samedi 15 décembre 2007 Statut Membre Dernière intervention 23 avril 2009
23 avril 2009 à 19:40
C'est marrant, car quand on lance 2 programmes. Sa passe nickel. mais c'est pas le but.
Merci lol
the_wwt Messages postés 177 Date d'inscription jeudi 5 octobre 2006 Statut Membre Dernière intervention 16 janvier 2009 1
23 avril 2009 à 19:34
Alors génial!

Essaye de gérer les devices dans des threads séparés...

Cordialement :P

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.