Archives Mensuelles: juin 2009

Le redimensionnement des vidéos de mon module n’était pas toujours bien calculé. J’ai donc passé l’essentiel de la matinée à revoir la façon dont je calculais la taille de mes containers vidéos par défaut ainsi que la hauteur de mes vignettes vidéos. En ce qui concernait la façon dont je calculais la taille des containers par défaut, le problème venait du fait que la fonction Math.ceil, qui est censée renvoyer l’entier immédiatement supérieur à la valeur qu’on lui passe en paramètre ne fonctionnait pas tout à fait comme je le pensais. De même, j’ai mis en place une nouvelle façon de calculer la taille des vignettes vidéos, qui est maintenant uniquement basé sur la hauteur de l’interface principale, et sur le nombre de clients, mais la largeur totale de l’interface n’est plus prise en compte.

Aujourd’hui, Nicolas R. a corrigé et validé le protocole que j’ai établi pour les communications entre le serveur et les clients.

Puis j’ai voulu achever la partie de l’application qui permet de passer le l’interface par défaut à l’interface focus. J’y suis bien arrivée, mais une fois que j’avais effectué ces changements dans mon code, lorsqu’on cliquait plus de trois fois pour afficher une vidéo en mode focus, une exception se produisait, signalant un argument non valide. Il s’agissait en fait tout simplement d’un problème de redimensionnement de la liste des vignettes vidéos, mais le message d’erreur était tellement obscur que la solution ne m’est pas apparue immédiatement, et il m’a fallut un bon moment avant de régler le problème.

Je me suis aussi occupée du recalcul des dimensions des vignettes vidéos lors du redimensionnement de l’interface par défaut. Ainsi, à chaque redimensionnement de cette interface, la taille des vignettes ainsi que leur emplacement est recalculé de sorte à optimiser l’espace qu’elles occupent dans l’interface.

J’ai commencé à implémenter la partie “interface par défaut” de mon module. Elle vient s’ancrer directement dans le code que j’ai déjà implémenté, mais je dois réaliser pas mal de modifications dans les classes que j’ai réalisées pour le mode “focus”. Je dois notamment mettre en place un système permettant de passer de l’interface par défaut à l’interface focus, et par là même revoir la façon dont je gère l’évènement de clic sur une vidéo. Pour le moment, je me suis occupée d’afficher les vidéos en mode “par défaut”, c’est-à-dire que j’ai mis en place un système qui calcule le nombre de colonnes et de lignes qui permet de maximiser la taille des vignettes vidéos en fonction du nombre de flux affichés et de la taille de la fenêtre.

Parallèlement à cela, j’ai commencé à réfléchir au protocole de communication entre le serveur et les clients.

J’ai terminé la partie du code qui gère le redimensionnement. Ainsi, lorsque l’on réduit la hauteur de la fenêtre, la hauteur des vidéos en vignette se réduit proportionnellement, mais lorsqu’on réduit sa largeur, seule la vidéo en mode focus se redimensionne, et les vidéos de la liste se contentent de grignoter l’espace restant entre elles s’il y en a, de sorte à ce qu’un maximum de vidéos soient affichées.  De plus, j’ai modifié le calcul de la taille de la hauteur des vidéos de la liste, de sorte à ce qu’elles soient plus petites, mais elles ne peuvent toujours pas descendre en-dessous d’une certaine taille que j’ai fixée à un huitième de la hauteur totale de la fenêtre. Dans le cas où elles atteindraient cette valeur, elles ne seront plus toutes affichées, et il faudra utiliser la scrollbar pour toutes les voir. Sur les conseils de Nicolas H., j’ai également modifié un peu l’interface graphique générale de sorte à ce qu’elle soit plus présentable (couleur grise en fond pour les vidéos, ajout d’une bordure, etc…)

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.

J’ai réussi à trouver comment redimensionner correctement les éléments en cas d’ajout ou de suppression. Mais comme jusqu’alors je me contentait de supprimer uniquement le dernier élément, il fallait que je mette en place un système permettant de supprimer n’importe quelle vidéo souhaitée par l’utilisateur. Nicolas R. m’a donc suggéré de créer un petit cadre autour de chaque vidéo de la liste, qui contiendrait, entre autres choses, un bouton de suppression. Cela fut assez simple à mettre en place, mais il faut maintenant gérer le redimensionnement et la mise à jour des données internes au module un peu différemment, et cela me pose problème. J’ai implémenté des listeners dans ma classe ScrolledVideos et dans ma classe principale, de sorte à ce qu’elles puissent détecter la suppression ou la mise à l’arrêt du mediaPlayer. Si la classe principale repère bien cet arrêt, elle semble rester bloquée lorsqu’elle recalcule les nouvelles dimensions de la liste de vidéos.

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 implémenté une classe ThumbnailGstreamerMediaPlayer, qui représente une vignette vidéo. Elle étend la classe GstreamerMediaPlayer mais possède en plus un composite et un MediaPlayerSWTVideoOutput qui lui sont propres. J’ai également terminé d’implémenter la classe ScrolledVideos, qui affiche les vignettes vidéo que l’on crée à l’intérieur au fur et à mesure. Elle est attachée à un StackLayout qui possède un deuxième composite qui sera donc ainsi “invisible”. Un listener est attaché au DirectDisplayer de chaque vignette vidéo afin de pouvoir détecter si l’on a cliqué dessus. Si tel est le cas, on échange le mediaPlayer cliqué avec celui affiché dans le conteneur principal du module, et on place sa sortie vidéo dans le composite dit “invisible”. Le media player qui se trouvait dans le conteneur principal du module va, lui, rejoindre sa sortie vidéo d’origine et être ré-affiché (cette partie doit encore être codée).

J’ai recodé mon écouteur de vidéo afin qu’il soit plus propre. J’ai également recherché des solutions à mon problème d’arrêt de vidéo et d’espace dans les conteneurs. En testant, je me suis rendue compte d’une chose : les deux problèmes étaient liés à la même cause. En effet, lorsque je cliquais sur la première vidéo que je voulais échanger, elle venait bien se placer dans le container de focus, mais elle se stoppait, tandis que la vidéo qui était précédemment en focus continuait bien de tourner, mais elle ne se plaçait que dans la moitié droite du container. En relisant mon code, j’ai compris à quoi était probablement dû le problème : dans un premier temps, j’affectais la vidéo en focus à la sortie vidéo de celle qui venait d’être cliqué, et ensuite je déplaçais cette dernière dans le conteneur de focus. Il y avait donc un moment où les deux flux vidéo étaient joués dans le même container. C’était cela qui stoppait la première vidéo, et cela expliquait l’espace laissé vide dans son container par la suite.

Afin de résoudre le problème, il y a trois solutions : reloader le flux dans le container après l’échange (mais cela est un peu lourd), détruire le container vidéo de la vidéo sur laquelle on a cliqué avant de la recréer (mais cela est également un peu lourd et difficile à mettre en place) ou encore créer un composite invisible qui va servir de “pivot”. Cela signifie que l’on va affecter la vidéo sur laquelle on a cliqué à cette sortie vidéo (qui ne sera pas affiché), et ensuite seulement opérer l’échange, un peu à la manière dont on échange deux valeurs en lignes de code. Certes, cela force à créer un composite en plus, mais cela évite les temps d’attente de chargement de flux ainsi que la création et la destruction inutile d’objets.

Par ailleurs, Nicolas H. m’a expliqué que les différents flux vidéos auraient un nom, et qu’ils seraient donc classés par ordre alphabétique dans la liste des vidéos du bas. Échanger les flux n’est donc pas suffisant, il faut les trier. J’ai donc commencé à implémenter une classe représentant un ScrolledComposite de conteneurs vidéos.

Aujourd’hui, je me suis surtout penchée sur les problèmes que me posaient l’interface focus. Le premier problème que j’ai rencontré était le fait qu’en cliquant sur une vidéo de la liste du bas, elle s’ajoutait au container sur haut sans que la vidéo qui y était déjà prenne sa place dans la liste du bas. Au final, on finissait par se retrouver avec toute la liste de vidéos du bas dans le container du haut, et la vidéo qui était initialement en focus se retrouvait en bas, changeant de container selon la vidéo du haut sur laquelle on cliquait. J’ai donc remédié à cela, mais j’ai alors commencé à rencontrer un autre problème : selon la vidéo sur laquelle je cliquais, le vidéo qui était en mode focus avant elle ne prenait pas sa place au bon endroit dans la liste des vidéos du bas. J’ai donc demandé de l’aide à Nicolas R., et mon erreur m’est apparue : le container que je désignais dans mon listener n’était pas celui contenant la vidéo au moment du clic, mais celui qui la contenait à l’initialisation. C’est pourquoi lorsqu’on échangeait une vidéo quelconque avec celle du haut, elle finissait par se placer dans le composite qui possédait la vidéo du haut au moment du lancement de l’application.

J’ai donc pu régler ce problème, mais l’implémentation n’est pas très propre et doit être revue. Qui-plus-est, je rencontre encore d’autres problème : dès le premier échange d’emplacements, le composite du bas se divise en deux et seule une de ses moitié contient la vidéo. D’autre part, le flux vidéo s’arrête lorsqu’on clique dessus et reste figé par la suite.