"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!!!
30 mars 2011 à 08:33
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
7 oct. 2009 à 16:15
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
6 mai 2009 à 16:37
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.
23 avril 2009 à 19:40
Merci lol
23 avril 2009 à 19:34
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.