Gestion de fichiers FLV par Action Script
Les classes médias :
Il existe 6 classes natives qui permettent de gérer les médias Audio / Vidéo.
Deux sont proprement dédiées au matériel, Caméra et Microphone. Elles possèdent les méthodes, propriétés et gestion d’évènements nécessaires. Deux autres s’occupent du contenu qui transite dans les tuyaux, Sound et Vidéo. Enfin, les deux dernières s’occupent d’établir et gérer la connexion entre le player et le serveur, NetConnection qui connecte et NetStream qui gère le flux.
Lancer et lire la vidéo
Préparation des fichiers
Une fois le fichier FLV réalisé, placez-le dans votre dossier de travail et créez une nouveau fichier Flash (AS2.0), que vous enregistrerez au même niveau que le fichier FLV. Ou alors, utilisez les fichiers fournis en téléchargement.
Préparation de l’objet Video (video_01.fla)
Il faut préparer l’accueil du fichier vidéo externe au sein du fichier FLA. Jusqu’à Flash 8, ActionScript 2.0, il n’existe pas de manière directe du type new Video(). Donc, il nous faut le faire manuellement. Ouvrez la bibliothèque et, soit depuis le menu contextuel (en haut à droite de la palette), soit depuis un clic droit à l’intérieur de la bibliothèque, sélectionnez Nouvelle Vidéo.
Une boite de dialogue s’ouvre et vous invite à nommer ce nouveau symbole et à préciser si vous souhaitez l’intégrer à la TilmeLine ou bien le piloter, depuis ActionScript. Bien que pour l’instant, cela ne soit pas de grande importance, utilisez de préférence un nom de symbole qui ne contienne pas d’espace, de trait d’union ou de caractères accentués. Optez pour vidéo contrôlée par ActionScript.
Enfin, placez une occurrence de ce symbole sur la scène et nommez-le par exemple, video_mc. Encore une fois pas d’accents, de trait d’union, ou de caractères accentués. Nommez le calque qui contient cette occurrence video.
Mise en place de la connexion et de son stream (video_02.fla)
Ajoutez un calque. Nommez le action. Ouvrez la fenêtre de script et assurez-vous de bien obtenir un script d’image. Nous allons créer une connexion et établir un stream sur cette connexion :
var nc = new NetConnection() nc.connect(null) var ns = new NetStream(nc)
Du fait que les fichiers soient tous les deux à la même racine, il n’est pas nécessaire de les connecter en rapport à un serveur web (HTTP) ou FMS (RTMP). Nous pouvons utiliser la constante null. Si votre fichier FLV se trouvait sur un serveur (web ou stream), il aurait fallu utiliser les adresses absolues vers ces serveurs, du style :
nc.connect("http://www.serveur.com/dossier/")
Lecture de la vidéo
Nous allons maintenant mettre en relation ce flux vidéo, avec l’occurrence du symbole vidéo qui se trouve sur la scène. Une fois les deux en relation, nous n’aurons plus qu’à activer le flux, en indiquant comme paramètre, directement le nom du fichier FLV à lire.
video_mc.attachVideo(ns) ns.play("fichier.flv")
C’est un peu comme si nous avions branché un tuyau d’arrosage (NetConnection), à un robinet qui peut débiter de l’eau (NetStream). Connecter l’autre embout du tuyau à un sceau (attachVideo) … il ne reste plus qu’à ouvrir le robinet (ns.play()).
Ajouter une commande play / pause (video_03.fla)
Une fois la vidéo en lecture il est possible de jouer sur play / pause, en utilisant la commande unique, conjointement au stream utilisé. Ajoutez un calque sur l’animation, nommez-le commandes. Placez un bouton sur la scène, et nommez cette instance pause_bt. Ouvrez l’action du calque action, et ajoutez les lignes de codes suivantes :
this.pause_bt.onPress = function(){ ns.pause() }
Cette commande peut recevoir (ou pas) un argument. L’argument est de type booléen (true ou false). S’il est précisé, true permet de reprendre la lecture, false l’arrête. S’il est omis, par défaut le premier appel interrompt la lecture, les autres procèdent au basculement de l’état.
Récupérer les métadonnées (video_04.fla)
Chaque fichier vidéo contient un ensemble de métadonnées qui sont envoyées, dès que le serveur reçoit une demande sur la lecture d’un fichier. En fait, se sont les premières données envoyées au player. Il est donc possible de les lire depuis Flash et de les intercepter au moment où elles sont accessibles. Un gestionnaire d’évènements est prévu à cet effet sur le stream.
Ouvrez le calque action, et ajoutez les lignes suivantes :
ns.onMetaData = function(obj){ for (var i in obj){ trace(i + " = " + obj[i]); } }
Explications et détails
Pour la classe NetStream(), il existe le gestionnaire d’évènement onMetaData(), qui est émis dès la réception des métadonnées du fichier. Un objet est reçu comme argument à cette fonction et contient l’ensemble des informations. De ce fait, en plaçant sur l’instance du stream le gestionnaire, on récupère cet objet. Une simple boucle d’itération d’objet (voir le tutoriel sur les bases de la programmation ActionScript), permet de parser cet objet. Durant la boucle, on demande à Flash d’afficher l’élément parsé et son contenu.
Si vous utilisez la vidéo fournie en téléchargement, le résultat donne les informations présentent dans l’image ci-dessous. Il existe une propriété cuePoints, que nous explorerons un peu plus bas dans ce tutoriel. Cette propriété est elle-même un objet, donc, dans cet appel, on ne reçoit que des valeurs undefined. Par contre, nous constatons toute une série de paires propriétés / valeurs, qui sont assez riches en type d’informations :
audio / video codecid
L’identifiant de codec est une valeur numérique autant pour l’audio que pour la vidéo. Vous trouverez dans le tableau ci-dessous leurs correspondances. Pour en savoir plus, reportez-vous à l’aide en ligne. Pour les deux dernières données propres au H.264 et AAC, il ne s’agit plus de valeurs numériques, mais de chaînes de caractères.
videocodecid | Nom du codec |
---|---|
2 | Sorenson H.263 |
3 | Screen video (SWF versions 7 et ultérieures uniquement) |
4 | VP6 (SWF versions 8 et ultérieures uniquement) |
5 | VP6 avec canal alpha (SWF versions 8 et ultérieures uniquement) |
avc1 | H.264 |
audiocodecid | Nom du codec |
---|---|
0 | non compressé |
1 | ADPCM |
2 | mp3 |
5 | Nellymoser 8kHz mono |
6 | Nellymoser |
mp4a | AAC |
Utiliser les métadonnées (video_05.fla)
Parmi les paramètres envoyés avec les métadonnées, nous allons mettre à profit trois informations. Dans un premier temps, la largeur (width) et la hauteur (height), et dans le prochain chapitre de ce tutoriel, la durée (duration).
Lorsque nous avons déposé sur la scène l’occurrence de l’objet Vidéo, nous ne nous sommes pas soucié de ses dimensions. Nous l’avons juste glissé sur la scène. Or, la vidéo maintenant se joue et s’adapte à ces dimensions. Du fait que les méta données soient les premières informations reçues par le player (avant les premières informations vidéos images), nous allons pouvoir corriger ceci et adapter les dimensions de l’instance vidéo, aux dimensions réelles de la vidéo. Il suffit de remplacer le contenu de l’évènementiel onMetaData(), par les lignes de code suivantes :
ns.onMetaData = function(obj){ video_mc._width = obj.width video_mc._height = obj.height }
Notez que les propriétés de l’occurrence de clip, possède un underscore comme premier caractère (_width) contrairement aux propriétés de l’objet reçues par l’évènementiel (width).
Si vous testez l’animation, vous ne devriez pas remarquer grande différence. En fait, la dimension par défaut de l’occurrence, correspond à la dimension de la vidéo lue en flux continu. Vous pouvez éventuellement redimensionner l’occurrence à une taille plus importante et relancer votre animation. Là, vous constaterez l’adaptation à la taille de la vidéo.
Ajouter une barre de progression interactive
Travail de préparation (video_06.fla)
Cette partie en fait se rapporte plus à de l’ActionScript qu’à du Flash Video. Nous allons utiliser la propriété duration (dont nous parlions au chapitre précédent), afin de mettre en place dans un premier temps, une barre de progression, qui dans un second temps, permettra à l’utilisateur de se déplacer dans la progression du film.
Pour réaliser la barre de progression, commençons par dessiner sur la scène un rectangle blanc, sans contour, de 100 pixels par 20 pixels. Convertissez-le en symbole de type clip (F8). Assurez-vous que le point d’alignement soit situé en haut à gauche, puis nommez-le barre_base.
Créez un nouveau symbole (Ctrl – F8), appelez-le barre_progression, nommez le calque qu’il contient barre_fond et déposez une instance du symbole barre_base précédemment créé. Nommez l’instance barre_fond. Avec l’aide de la palette d’alignement (Fenêtre > Aligner ou Ctrl – K), assurez-vous que ce clip soit placé à droite et en dessous du point d’alignement.
Dupliquez ce calque. Si vous ne l’avez pas déjà installé, regardez de plus près l’extension Duplicate Layer. Assez intéressante. Donc, une fois le calque dupliqué, nommez celui placé au dessus, ainsi que l’instance qu’il contient, barre_active. Le clip de dessus barre_active, marquera la portion de vidéo déjà lue, et celui dessous barre_fond, donnera un aperçu du temps global (durée) de la vidéo.
Pour permettre de distinguer les deux clips barre_active et barre_fond, il faut les colorer. En vous aidant des cadenas et des yeux de visibilité de chaque calque, sélectionnez tour à tour les deux objets que contient ce clip et attribuez à celui de dessous un effet de couleur – teinte #33CCFF à 65% et celui de dessus un effet de couleur – teinte #CC3333 toujours à 65%.
Le travail de préparation est maintenant terminé, vous pouvez revenir sur la séquence (time line principale) et y déposer une instance du symbole barre_progression. Nommez cette instance barre_progression.
Codage de la mise en place de la barre (video_07.fla)
Au moment de la réception des métadonnées, il faut initialiser la barre de progression. Cette initialisation devrait :
- S’assurer que la barre de progression soit positionnée en dessous à gauche de la vidéo
- Ajuster la largeur de la barre de fond à la largeur de la vidéo
- Initialiser le clip qui est placé dessus (barre_active) à une largeur de 0
Le code est simple et parle de lui-même. Chaque ligne de code ci-dessous, suit l’objectif établi par la liste ci-dessus. Il faut le placer dans le gestionnaire onMetaData() :
barre_progression._y = video_mc._y + video_mc._height + 10 barre_progression.barre_fond._width = video_mc._width barre_progression.barre_active._width = 0
Lorsque vous testez, vous devriez obtenir une barre bleue positionnée à 10 pixels en dessous de la vidéo, et faisant la largeur de la vidéo. Si vous travaillez avec Flash CS3 et si vous ne voyez rien, assurez-vous que vos calques ne soient pas masqués. C’est une nouveauté de la CS3 qui fait que le compilateur tient compte de vos choix de visibilité de calque.
Rafraîchissement de la barre (video_08.fla)
Bon, une barre de progression… cela doit progresser… et là, bien que la vidéo se joue, rien ne progresse. Ajoutons la progression. Pour cela, il existe deux approches, une rapide et efficace mais pas optimale (ajouter un évènementiel onEnterFrame()), et une autre plus évoluée, moins gourmande en ressources et donc meilleure (setInterval()). Bien que ce tutoriel ne soit pas orienté ActionScript mais vidéo, optons pour la seconde, afin de laisser le maximum de cycle processeur à jouer de la vidéo, plutôt que de faire progresser une barre…. La mise en place de l’appel de la fonction setInterval peut se faire dans une fonction autonome prévue à cet effet :
function activeBarre() { pointeurBarre = setInterval(barre_progresse, 100); }
Préparons la fonction barre_progresse() qui va être appelée de manière récurrente, toutes les 100 millisecondes, et qui permettra le rafraîchissement de la largeur de la barre active, en fonction de la position de la tête de lecture. Au sein de cette fonction, nous allons mettre en place une simple règle de trois. En gros, la largeur de la barre active devra faire la largeur du clip vidéo * le temps actuel de la vidéo / durée totale de la vidéo. Soit :
function barre_progresse() { var coef = ns.time*video_mc._width/video_mc.duree; barre_progression.barre_active._width = coef; }
Notes
Le Temps de la vidéo (position de la tête de lecture) est connu, c’est la propriété time de la classe NetStream(). Par contre, la durée de la vidéo est une inconnue, il nous faudra donc ponctionner la propriété duration, lors de la réception des données. Profitons-en également, pour interpeler le lancement du setInterval :
ns.onMetaData = function(obj) { ... video_mc.duree = obj.duration; activeBarre(); };
Interaction sur la barre (video_09.fla)
L’idée de cette interaction est de permettre à l’utilisateur de cliquer et déplacer la barre_active. En faisant cela, il déplacera également la tête de lecture en fonction, au sein de la vidéo. En fait, il nous faut appliquer la même mécanique et la même logique de Troie que précédemment, mais dans le sens inverse : ce n’est plus la tête de lecture qui pilote la barre mais le contraire.
Le pilotage du setInterval() sera affecté à la pression sur la barre_active et son annulation au relâchement. Il faut également prévoir à ce moment-là, d’une part de désactiver / activer la lecture de la vidéo et d’autre part, de désactiver / réactiver le rafraîchissement de la barre_active, puisque c’est l’utilisateur qui en prend le contrôle. Le code est donc le suivant :
this.barre_progression.barre_active.onPress = function() { adapteBarre = setInterval(video_recale, 100); ns.pause(true); clearInterval(pointeurBarre); }; this.barre_progression.barre_active.onRelease = function() { pointeurBarre = setInterval(barre_progresse, 100); ns.pause(false); clearInterval(adapteBarre); };
Il ne reste plus qu’à définir la fonction video_recale(), qui prend en charge le rafraîchissement du positionnement de la tête de lecture, appelée par le setInterval(). Afin de limiter la modification de largeur de la barre active entre 0 et la largeur de la vidéo, il suffit de jongler entre un Math.max(), Math.min(), de la manière suivante :
largeur = Math.max(0, Math.min(barre_progression._xmouse, video_mc.width));
Le maximum entre 0 et « quoique ce soit »… sera forcément le « quoique ce soit » si celui-ci est positif, sinon cela sera 0… on obtient ainsi une limite gauche à 0. Justement, le fameux « quoique ce soit » est lui-même le minimum entre la position de la souris et la largeur de la vidéo. Donc, si la souris se trouve en deçà de la largeur de la vidéo, le minimum sera la position de la souris… si par contre, la souris part à droite plus loin que la largeur de la vidéo, on en restera à cette largeur…. la Math.max(Limitegauche ,Math.min(position souris, Limitedroite) à fait son effet.
Regardons maintenant la règle de trois, pour positionner la tête de lecture en fonction de la largeur de la barre active. Cette fois-ci le coefficient issue de la règle de trois est :
function video_recale() { barre_progression.barre_active._width = Math.max(0, Math.min(barre_progression._xmouse, video_mc.width)); coef = barre_progression.barre_active._width * video_mc.duree / video_mc._width ns.seek(coef) }
Intercepter les points de repères
Les points de repères
Un peu plus tôt dans ce tutoriel, lors de la réalisation du fichier FLV avec Flash Video Encoder, nous avons pris le temps d’ajouter quelques points de repères. Nous allons explorer maintenant, la manière de les intercepter, de les utiliser et quels sont les principales utilités qui peuvent en découler.
Evenementiel onCuePoints() – (video_10.fla)
De la même manière qu’il existe un gestionnaire d’évènements pour les méta données, il en existe un pour les points de repères, onCuePoint(). Il suffit de l’adjoindre à l’instance du stream et chaque fois que la tête de lecture rencontre un point de repère, elle émettra un objet, contenant toutes les informations à la fonction. Pour le mettre en évidence, ajoutez simplement ces quelques lignes de code, qui utilisent le même principe que ce que nous avons vu précédemment :
ns.onCuePoint = function(obj) { for (var i in obj) { trace(i+" = "+obj[i]); } trace("---------------------------"); };
Première fenêtre de sortie
Le résultat obtenu dans la fenêtre de sortie, présente une donnée parameter, qui en fait est un objet, du fait quelle affiche deux valeurs undefined.
Ajoutons quelques lignes de code pour filtrer ce paramètre et le gérer lui-même en tant qu’objet, et re-testons :
Remaniement du code (video_11.fla)
ns.onCuePoint = function(obj) { for (var i in obj) { if (i != "parameters") { trace(i+" = "+obj[i]); } else { trace("parameters :"); for (var j in obj[i]) { trace("\t"+j+" = "+obj[i][j]); } } } trace("---------------------------"); };
Nouvelle fenêtre de sortie
Cette fois-ci, l’objet parameters est parsé et la boucle explore les diverses propriétés qu’il contient.
On peut donc constater que la première boucle parse l’objet lui-même, ce que nous avions dans la fenêtre de gauche lors de l’ajout des point de repère (dans Flash Video Encoder) et l’objet parameters représente lui, ce que nous avions pour chaque point de repère dans la fenêtre de droite.
Utilisation des points de repères dans notre animation
Les principales utilisations des points de repères, sont de synchroniser le défilement de la vidéo avec le reste de l’animation Flash. Peu importe la cadence (nombre d’images par seconde), ou que des images de la vidéo soient sautées. Les points de repères sont directement liés au défilement de la tête de lecture de la vidéo. Il existe donc une multitude d’utilités liées à la synchronisation de l’animation. Nous allons en explorer deux principales : gérer le déclenchement d’animations tierces, et appliquer des sous-titrages.
Lors de la compression du fichier FLV, si vous avez suivi l’étape précédente de ce tutoriel, vous avez entré des points de repères dans ces deux objectifs… des sous-titre et des écrans publicitaires… ou mieux… vous avez importé le fichier XML prévu à cet effet.
Connecter une web cam
1 réponse
[…] de la vidéo avec Flash), ou alors d’intégralement gérer le flux FLV depuis Action Script (Gestion de fichiers FLV par Action Script). Dans les deux cas, il suffit d’ajouter la balise après la dernière balise […]