Tag d'archives : SWT

Sur demande de Nicolas R., j’ai rajouté des scrollbar à l’interface de mon plug-in afin qu’il ne soit plus possible de réduire les flux vidéo en-dessous d’une certaine taille. Suite à cela, j’ai apporté de petites modifications au code de mon client et de mon serveur, ainsi qu’a celui de toutes les classes qu’ils utilisent, afin qu’il soit plus propre et plus lisible.

Nous avons terminé d’installer Debian sur ma machine Windows ce matin. Par la même occasion, nous avons installé Java, Eclipse, ainsi que les classes dont j’aurais besoin pour le projet. Nicolas R. nous a un peu présenté le projet, à Lorenzo et moi, et il m’a également expliqué comment développer un plug-in. J’ai passé le reste de la journée à étudier SWT et à tester de petits exemples.

Je me suis occupée aujourd’hui de l’ajout et de la suppression dynamique de vidéos. Afin de simuler l’ajout d’une vidéo, j’ai inséré temporairement un bouton d’ajout dans l’interface. Pour la suppression, j’ai fait réagir l’interface à un roulement de la molette de la souris sur un mediaPlayer.

L’ajout a été assez simple à réaliser, mais j’ai rencontré quelques problèmes assez mineurs lors de la suppression. Il fallait notamment penser au fait que l’index de la vidéo en mode focus diminuait lorsqu’une vidéo la précédant dans l’ordre des mediaPlayer étant supprimée. De plus, je n’avais pas tout de suite réalisé qu’effectuer un “dispose” sur un élément d’une liste ne le supprimait pas proprement de la liste, et cela pouvait provoquer des décalages dans les indices de mes vidéos. J’ai également dû légèrement revoir mes fonctions de redimensionnement afin qu’elles soient utilisables lors de la suppression d’une vidéo sur l’interface. Il fallait également veiller, en mode focus, à prendre garde à ce qu’il se passait lorsqu’il ne restait plus qu’une seule vidéo sur l’interface. En effet, dans ce cas-là, la conteneur de focus était réduit à une hauteur nulle, il fallait donc prendre garde à ce que, au contraire, il prenne toute la place de la fenêtre.

Enfin, j’ai demandé à Nicolas H. s’il était possible de passer de l’interface focus à l’interface par défaut, et cette fonctionnalité doit également être possible. Je suis donc actuellement en train de faire en sorte que lorsque l’utilisateur clique sur le vidéo en mode focus, cela le fasse revenir à l’interface par défaut. Je dois encore gérer un éventuel retour à l’interface focus. De plus, je me pose quelques questions. Je ne sais pas si je dois supprimer tous les conteneurs vidéo et en créer de nouveaux à chaque fois, ou si je dois les conserver pour les réutiliser, et éventuellement en ajouter ou en retirer selon le nombre de mediaPlayer à afficher?

Après discussion avec Nicolas H., il s’avère qu’il n’est pas utile d’ajouter ou de supprimer dynamiquement des clients. J’ai donc supprimé toute la partie du code qui permettait de réaliser ces opérations. En revanche, Nicolas H. m’a fait savoir qu’il serait préférable qu’une icône ou un symbole indique, dans le conteneur vidéo, lorsque la vidéo n’est pas disponible. Malheureusement, il n’est pas possible de savoir si la vidéo est disponible ou non, je ne peux donc, pour le moment, pas m’occuper de cette partie.

J’ai donc entrepris de terminer la partie du code effectuant le calcul de la taille des vignettes vidéos. Je me suis également occupée de faire en sorte que ces dimensions soient recalculées aussi lorsque l’utilisateur redimensionne la fenêtre d’affichage. J’ai rencontré une petite difficulté à ce moment-là, due au fait que j’utilisais un la fonction createHeightOnlyGridData() du WGridLayoutHelper. En effet, cette fonction fixe la hauteur des vignettes, et il n’est plus possible de la modifier par la suite, je ne pouvais donc par recalculer une nouvelle hauteur et l’attribuer au composite à chaque redimensionnement. Je pensais utiliser une autre fonction du WGridLayoutHelper pour créer mon GridData, mais malheureusement, aucune de ces fonctions ne permet de créer un GridData dont on pourrait modifier dynamiquement la hauteur. Pour le moment, je crée un nouveau GridData à chaque évènement resize afin de pouvoir fixer la hauteur que je veux à mon GridData.

Ce matin, j’ai terminé l’interface focus. Ainsi, lorsqu’on clique sur une vidéo de la liste du dessous, elle est affichée dans le composite de focus. En même temps, le conteneur vidéo qui lui est associé est déplacé sur le composite invisible, c’est-à-dire le deuxième composite du StackLayout. Mais avant cela, vidéo qui était auparavant dans le conteneur de focus est déplacée dans son conteneur associé, et celui-ci, qui se trouvait sur le composite invisible, va alors rejoindre la liste des conteneurs vidéos du bas. Étant donné que les vidéos doivent être placées dans l’ordre alphabétique, un index est associé à chacune d’elles, et la vidéo est alors placée dans la liste en concordance avec cet indice.

Comme je n’avais, jusqu’à présent, effectué mes tests qu’en local, j’ai demandé à Lorenzo de réaliser quelques tests avec moi afin de vérifier que je pouvais bien récupérer des flux d’une autre machine. Cela a parfaitement fonctionné.

Puis j’ai réalisé quelques tests afin de voir s’il est possible de rajouter ou de retirer des clients dynamiquement. J’ai donc ajouté un bouton d’ajout et un bouton de suppression, et lorsque l’utilisateur clique sur le bouton d’ajout, il n’a qu’à entrer les données du client dans la boîte de dialogue qui s’ouvre alors à lui, tandis que le bouton de suppression permet de supprimer le dernier élément vidéo de la liste. Cela fut vite réalisé. Mais je rencontre à présent quelques soucis avec le redimensionnement le liste des vidéos lors de la mise à jour de cette liste. J’arrive bien à lui faire récupérer sa taille initiale lors de la suppression ou d’un ajout, mais le conteneur vidéo de focus garde sa taille précédente, un bout de la liste vidéo est donc coupé. Je cherche donc une solution à ce problème.

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.