Tag d'archives : Java

J’ai finalement réussi à afficher le flux vidéo de la caméra dans mon application. J’ai effectué quelques tests et tout à l’air de bien fonctionner.

J’ai également trouvé comment me servir de gstrtpbin avec une caméra IP. Il faut en réalité toujours se servir de rtspsrc, comme le montre la ligne de commande suivante, qui permet de streamer le flux vidéo de la caméra vers deux clients différents :

./gst-launch -v gstrtpbin name=rtpbin rtspsrc location=rtsp://(adresse IP de la caméra):554/mpeg4/media.amp ! queue ! decodebin ! ffenc_h263 ! rtph263pay ! rtpbin.send_rtp_sink_0 gstrtpsession name=session rtpbin.send_rtp_src_0 ! udpsink port=5000 host=(adresse IP su premier client) rtpbin.send_rtcp_src_0 ! udpsink port=5001 host=(adresse IP su premier client) sync=false async=false udpsrc port=5005 ! rtpbin.recv_rtcp_sink_0 rtspsrc location=rtsp://(adresse IP de la caméra):554/mpeg4/media.amp ! queue ! decodebin ! ffenc_h263 ! rtph263pay ! rtpbin.send_rtp_sink_1 gstrtpsession name=sessiontwo rtpbin.send_rtp_src_1 ! udpsink port=5002 host=(adresse IP du second client) sessiontwo.send_rtcp_src_1 ! udpsink port=5003 host=(adresse IP du second client) sync=false async=false udpsrc port=5007 ! rtpbin.recv_rtcp_sink_1

Toutefois, je me pose encore quelques questions car il est probable que cette ligne de commande ne soit pas la plus simple pour streamer un même flux vers deux clients différents.

J’ai également implémenté la partie de l’interface graphique permettant de rentrer les informations des différents clients dans le cas où l’on veut streamer le flux vidéo vers plusieurs clients. Pour cela, j’ai utilisé un ScrolledComposite, c’est-à-dire un composite possédant une liste déroulante contenant tous les contrôles que l’on insère dedans.

Ayant un peu mieux cerné SWT, j’ai pu commencer aujourd’hui à implémenter une petite interface affichant le flux d’une caméra IP, en me servant de gstreamer-java et bien évidemment de SWT. Cela a tout de suite bien fonctionné. J’ai ensuite voulu implémenter une petite application de type client/serveur. La partie serveur n’est composée pour le moment que d’un bouton, qui envoie le flux vidéo de la caméra à une autre application lorsque l’on clique sur ce bouton. L’autre application est une application cliente, qui est composée, elle, d’un bouton et d’un composant de type conteneur vidéo, qui affichera le flux vidéo une fois qu’un serveur a été lancé et que l’on a cliqué sur le bouton. Malheureusement, cette partie-là ne fonctionne pas encore. Le pipeline Gstreamer est pourtant le bon (il fonctionne en ligne de commande), et l’application serveur envoie bien le flux (on peut le récupérer par ligne de commande, toujours). Mais la partie cliente semble incapable de récupérer ce flux.

Je rencontre également un autre problème : l’encodeur H.263, qui est celui que nous devrions utiliser dès à présent, n’est pas installé sur mon ordinateur. Pourtant, il ne me manque pas de paquets Gstreamer. Je crains que, à l’instar de l’encodeur H.264, il ne soit plus disponible dans les dernières versions des plug-in de Gstreamer.

Aujourd’hui, j’ai continué d’étudier un peu SWT, notamment réalisant quelques “exercices”. Ces derniers sont présentés dans le PDF que vous pouvez trouver ici. J’ai ainsi pu découvrir les différents contrôles ainsi que les différentes manières de traiter un évènement avec SWT, et les appels synchrones et asynchrones.

J’ai encore effectué quelques recherches à partir du code du projet que m’avait soumis Nicolas R., ainsi que la fameuse fonction sendMessage() de la DLL User32 qui permet d’ouvrir une boîte de dialogue contrôlant le flux vidéo d’un appareil connecté à l’ordinateur. Malheureusement, il semblerait bien qu’il n’y ait aucun moyen d’accéder aux informations de la webcam. On ne peut contrôler que le dispositif de capture du flux de la webcam, et toutes les manipulations sur le flux vidéo dans ce projet sont faites à partir des données transmises pas ce dispositif. De plus, on ne peut pas accéder aux informations contrôlées pas la boîte de dialogue affichée par sendMessage().

J’ai donc ensuite commencé à coder un exécutable qui permettrait d’afficher sur la console, la liste des périphériques audio et vidéo, ainsi que la liste des compresseurs. Pour cela, j’ai simplement repris le code de ma DLL. Cependant, je rencontre quelques soucis à l’affichage, car je n’arrive pas à trouver en quel type caster l’objet BSTR que je récupère, afin de l’afficher en entier sur la console. Pour le moment, seule l’initiale du nom du périphérique s’affiche.

Une coupure d’Internet dans la matinée nous a fait perdre un peu de temps.

La solution proposée par la JMF n’étant pas très concluante, Nicolas R. m’a montré le code Java qu’il avait réalisé permettant de récupérer le nom des périphériques audio. Ce code fonctionne très bien et renvoie bien la même liste de périphériques audio que le faisait ma DLL. J’ai donc tenté de partir de ce code et de voir s’il existait quelque chose d’équivalent pour les périphériques vidéo. Malheureusement, il semblerait bien que non. La JMF reste la seule alternative, mais afin de l’utiliser correctement, il faut utiliser parallèlement une application appelée la JMFRegistery. Tant qu’un périphérique vidéo n’est pas enregistré dans la JMFRegistery, il ne pourra pas être détecté par la JMF. Par ailleurs, sur Internet, quelques personnes conseillent, dans ce genre de situation, de créer une DLL en C qui sera ensuite appelée par Java. Retour à la case départ.

Sur les conseils d’un Internaute, j’ai téléchargé et installé Dependency Walker, un logiciel qui permet de tracer le graphe de dépendance d’une DLL à toutes les autres DLL qu’elle utilise. Ma DLL dépend d’un nombre très important d’autres DLL, et il est difficile de déterminer lesquelles appartiennent au framework .NET. Nous avons cependant tout de même tenté d’en installer quelques-unes sur l’ordinateur de Lorenzo, mai rien n’y fait, Eclipse ne réussit toujours pas à utiliser ma DLL.

J’ai ensuite jeté un coup d’œil au code dont Nicolas R. s’est inspiré, que vous pouvez trouver ici. En le testant, il ne m’a renvoyé qu’un seul périphérique : celui permettant la capture des images de la webcam, tout comme le faisait la JMF. Pour permettre le choix de la webcam, l’auteur de ce code a simplement appelé une fonction de la DLL User32 qui affiche un boîte de dialogue contenant la liste déroulante des webcams connectées.

Après avoir quelque peut “fignolé” ma dll et avoir écrit des fonctions Java permettant de récupérer les périphériques audio et vidéo, ainsi que leurs codecs, j’ai fourni à Lorenzo le .jar et la dll dont il aurait besoin pour son projet. Malheureusement, après les avoir installés et après avoir reconfiguré le projet de sorte à ce qu’il prenne ces deux fichiers en compte, lorsqu’il a essayé d’utiliser une des fonctions java dans son code, cela lui renvoyait l’erreur suivante :

java.lang.UnsatisfiedLinkError: Unable to load library ‘DShowUtil’: The specified module could not be found.

À travers ce que nous avons compris dans certains forums, il semblerait que problème vienne du fait que ma dll utilise elle-même d’autres librairies que ne sont pas installées, ou que le projet n’arrive pas à trouver. Nous avons alors entrepris d’installer le SDK de Windows fournissant DirectShow, mais cela n’a rien changé. Nous avons ensuite installé Visual C++ 2008 Express, dans le but de compiler les BaseClasses de DirectShow, mais même sans compiler ces classes, le code a soudain fonctionné. Lorsque  nous avons désinstallé le SDK de Microsoft, le code fonctionnait toujours, mais plus après avoir désinstallé Visual Studio. Pour que Eclipse puisse utiliser cette dll, Visual C++, et donc le Framework .NET doivent donc nécessairement être installés sur l’ordinateur. Ceci pose un gros problème, car on ne peut pas demander aux utilisateurs d’installer un framework aussi lourd pour une seule petite fonctionnalité. J’ai donc jeté un coup d’œil, parallèlement, à ce qui était possible de faire avec la JMF, mais il semblerait que ça ne soit pas les bons périphériques qui sont retournés. Je vais cependant tenter de creuser encore un peu de ce côté-là.

Voici à présent un petit tutoriel expliquant comment compiler la DLL :

- Téléchargez et installez Visual C++ 2008 Express

-Téléchargez et installez Windows SDK for Windows Server 2008 and .NET Framework 3.5

- Sous Visual, ouvrez le projet contenant la DLL (Ouvrir > Projet, puis ouvrez le dossier DShowUtils et sélectionnez le ficher DshowUtils)

- Dans les propriétés de l’éditeur de liens (Projet > Propriétés > Propriétés de configuration > Editeur de liens > Entrée > Dépendances supplémentaires) , ajoutez les librairies suivantes : user32.lib, ole32.lib, oleaut32.lib, quartz.lib, strmiids.lib.