Puce et Média

Recherche et développement en multimédia

  • Augmenter la taille
  • Taille par défaut
  • Diminuer la taille
Puce et Média > Flash plate-forme > Flash Vidéo > Gestion de fichiers FLV par Action Script

Gestion de fichiers FLV par Action Script

Envoyer Imprimer PDF

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é 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 quii transite dans les tuyaux, Sound et Vidéo. Et enfin les deux dernières s'ocuppent d'établir et gérer la connection 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 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 click 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, il n'y ait 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 controlée par ActionScript.

Enfin placez une occurence 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ère accentués. Nommez le calque qui contient cette occurence video.

Mise en place de la connection 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 connection et établir un stream sur cette connection

  var nc = new NetConnection()
  nc.connect(null)
  var ns = new NetStream(nc)

Du fait que les fichiers sont 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 trouverait 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'occurence 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 brancher 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 actionet 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 interompt la lecture, les autres procèdent au basculement de l'état.

Récupérer les métadonnées (video_04.fla)

Cahque fichier vidéo contient un ensemble de métadonnées qui sont envoyées dès que le serveur recoit 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 depusi Flash et de les intercepter au moment où elles sont accessible. Un gestionnaire d'évènement 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 placant sur l'instance du stream le gestionnaire, on récupère cet objet. Une simple boucle d'itération d'objet (voir le tutorial sur les bases de la programmation ActionScript) permet de pasrer 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 dansl'image ci-dessous. Il existe une propriété cuePoints, que nous explorerons un peu plus bas dans ce tutorial. Cette propriété est elle même un objet, et 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 video, voici dans le tableau ci-dessous leur correspondance. 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 valeur numériques mais de chaine 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éta données (video_05.fla)

Parmi les paramètres envoyés avec les métadonnées, on voit trois informations que nous allons mettre à profit. Dans un premier temps la largeur (width) et la hauteur (height), et dans le prochain chapitre de ce tutorial la durée (duration).

Lorsque nous avons déposé sur la scène l'occurence de l'objet Vidéo, nous ne nous sommes pas soucié de ses dimensions. Nous l'avons juste glissé sur la scène. Hors la vidéo maintenant se joue et s'adapte à ces dimensions. Du fait que les méta données sont les premières informations reçues par le player, donc avant les premières informations vidéos images, nous allons pouvoir corriger ceci et adapter les dimensions de l'instance video 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'occurence de clip possède un undescore comme premier caractère (_width) et pas les propriétés de l'objet recu 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'occurence correspond à la dimension de la vidéo lu en flux continu. Vous pouvez éventuellement redimentionner l'occurence à 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, puis dans un second temps pour permettre à l'utilisateur de se déplacer dans la progression du film.

Pour réaliser la barre de progression, commencons 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 contientbarre_fond et déponsez y 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 placer à 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à lu, 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 progession. Cette initialisation devrait :

  • S'assurer que la barre de progression soit positionné en dessous à gauche de la vidéo
  • Ajuster la largeur de la barre de fond à la largeur de la video
  • Initialiser le clip qui est placé dessus (barre_active) à une largeur de 0

Le code est simple et parle par 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 bleu 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.

Rafraichissement 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. Donc 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 et moins gourmande en ressource donc meilleure (setInterval()). Bien que ce tutorial 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);
}

Donc préparons la fonction barre_progresse() qui va être appelée de manière récurante, toute les 100 millisecondes, et qui permettra le rafraichissement 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 video * le temps actuel de la vidéo / durée totale de la video. 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 (la 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 l'inverse.

Le pilotage du setInterval() sera affecté à la pression sur la barre_active et son annulation au relachement. 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 rafraichissement 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 rafraichissment 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 video, 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 forcement le quoique ce soit si quoique ce soit est positif, sinon cela sera 0... on obtient ainsi une limite gauche à 0. Justement le fameux quoique ce soit et lui même le minimum entre la position de la souris et la largeur de la video. Donc si la souris se trouve en deca 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 video on en restera à cette largeur.... la Math.max(Limitegauche ,Math.min(position souris, Limitedroite) à fait son effet.

Regardons maintenant la règle de troie 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 troie 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 tutorial, 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ènement 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 chque fois que la tête de lecture rencontre un point de repère, elle émétra un objet contenant toute les information à la fonction. Pour le mettre en évidence, ajoutez simplement ces quelques lignes de code qui utilise 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ées 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 retestons

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 utilisation 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é au défilement de la tête de lecture de la vidéo. Il existe donc une multitude d'utilités liés à 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 tutorial, 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

 

 


Puce et Média > Flash plate-forme > Flash Vidéo > Gestion de fichiers FLV par Action Script