P
'
t
i
t
e
C
h
a
t
t
e
 
spacer~ "K SS MY SS" ... WOULD YOU LIKE TO BUY A VOWEL ? Articles | Connexion
 
~Gestion des fichiers

Précédent  
  Python  
  Suivant
 Présentation

Les fichiers au format vidéo AVI (Audio Video Interleave) abondent sur nos machines. Le récent succès du compresseur DivX n'a que fait accroître leur nombre. Nous verrons dans ces pages comment lire un fichier AVI pour en déterminer le nombre de trames par seconde.
 Sommaire


 Introduction

Le format Audio Video Interleave se révèle relativement simple, notamment dans sa forme non compressée, soit lorsque aucun codec particulier ne se voit employé, et abondamment documenté. Le calcul du nombre de trames par seconde nécessite la lecture de deux informations au sein de l'en-tête du fichier AVI. L'en-tête accueille les valeurs concernant l'échelle temporelle (le "time scale") et le débit de données (le "data rate"). En divisant la seconde valeur par la première, nous obtenons le nombre de trames par seconde (ou FPS en anglais). Ces deux valeurs se voient codées sur 4 octets chacune à partir du 128-ième octet de l'en-tête.


 Lire un fichier

L'ouverture d'un fichier en Python se réalise par l'intermédiaire de la fonction native open(). Sa forme exacte nécessite un paramètre obligatoire, le nom du fichier, et deux paramètres optionnels pour le mode d'ouverture et la taille du tampon mémoire. Ouvrir un fichier en lecture simple se réalise ainsi :

f = open("fichier")
f.close()
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
La seconde instruction provoque la fermeture du fichier. Le second paramètre possible de la fonction open() sert à préciser le mode de fonctionnement qui incarne par défaut une lecture. Nous pouvons ainsi préciser une lecture (valeur "r", par défaut), une écriture ("w") et une mise à jour ("a"). En ajoutant la lettre "b" au mode, nous définissons une méthode de lecture/écriture binaire. Enfin, le dernier paramètre prend la taille du tampon mémoire : 0 signifie que le tampon ne sera pas utilisé, 1 désigne un tampon contenant une ligne entière et tout autre nombre positif désigne la taille en octets du tampon. Pour ouvrir un fichier en mode mise-à-jour avec un tampon d'environ 80 octets, nous exécuterons :

f = open("file", "a", 80)
f.close()
       
      
JextCopier dans Jext
Après avoir ouvert votre fichier, vous devez le manipuler. Lire un fichier nécessite la méthode read() de l'objet f. Cette méthode retourne la valeur d'un octet (ou caractère) lu dans le fichier sous forme d'une chaîne de caractères. Vous pouvez préciser en paramètre le nombre d'octets à lire. Pour écrire, invoquez la méthode write(str).

Notez que l'utilisation d'un fichier peut provoquer une levée d'exception de type IOException. Nous sommes en mesure d'intercepter une exception grâce à la structure try/catch.

try:
  f = open("boum ", "w")
  f..write("BOUM ! V'LA L'REMOULEUR !")
  f.close()
catch IOException:
  print "Une erreur est survenue"
       
      
JextCopier dans Jext

 Lecture des informations

Le listing numéro un présente le code source relatif au calcul du débit de trames d'un fichier AVI. Nous constatons que ce code emploie la méthode seek(position) de l'objet fichier pour atteindre directement le 128-ième octet. Ceci se révèle bien plus efficace que la lecture directe de 128 octets. Nous savons que les informations qui nous intéressent se trouvent présentes sous la forme de quatre octets consécutifs. Le programme les obtient par l'appel de fsock.read(4). Néanmoins, nous possédons alors les informations sous forme d'une chaîne. La méthode unpack() importée du module struct octroie la possibilité de traduire la chaîne en un entier. Le premier paramètre de la fonction précise le type de conversion, ici "i" pour "integer". En seconde position se trouve les données à convertir. Pour terminer, la fonction renvoie un tuple dont le premier élément désigne le résultat attendu.


 Le programme

Le logiciel présenté se décompose en deux modules exécutables séparément. Le module "aviFps.py" recèle le code source relatif au calcul du débit de trames. Vous pouvez l'employer directement en commande en ligne en tapant "./aviFps.py fichier.avi". Le second module, intitulé "AviGUI.py", contient une interface graphique pour le premier module. Le toolkit graphique employé s'avère Tkinter. Nous étudierons à ce propos le mois prochain la même interface programmée à l'aide du toolkit wxPython (dérivé de wxWindow).

L'interface graphique proposée ne contient que deux boutons ainsi qu'une barre de statut. La réalisation d'une application Tkinter débute avec la création d'une fenêtre racine qui acceuillera l'application :

root = Tk()
root.mainloop()
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
La seconde ligne déclenche l'exécution de l'application. L'interprétation de ces deux lignes provoque l'affiche d'une fenêtre vide. Essayons à présent de lui adjoindre une étiquette.

label = Label(root, text="BOUM !")
       
      
JextCopier dans Jext
Tout composant graphique en Tkinter connaît dans l'ordre les paramètres de son parent puis de ses options. Le composant sera intégrée à la hiérarchie de son parent. Toutefois, vous ne verrez pas apparaître notre étiquette. Pour remédier à ce problème, le programmeur doit "compiler" le composant par la méthode pack(). Le code complet devient :

root = Tk()
l = Label(root, text="BOUM !")
l.pack()
root.mainloop()
       
      
JextCopier dans Jext
Une méthode pack() permet de définir la position et l'espace d'un composant. Si nous invoquons par exemple composant.pack(side=LEFT, padx=2, pady=2), nous positionnons le composant sur la gauche de son conteneur et lui ajoutons un espace libre de 2 pixels en hauteur et en largeur. En suivant l'exemple précédent, ajoutez deux étiquettes à la fenêtre, l'une à gauche, l'autre à droite. Lorsque vous jouerez sur la taille de la fenêtre à la souris, vous découvrirez l'effet du paramètre side.


 Plus de composants

Un composant indispensable à la réalisation d'interfaces complexes s'intitule Frame. Ce composant correspond à un simple conteneur. En jouant sur une hiérarchie complexe de composants, vous pourrez réaliser des mises en pages professionnelles. Voici par exemple la méthode à empployer pour placer une étiquette sous deux boutons :

frame = Frame(root)
frame.pack(side=TOP)
b = Button(frame, text="B1", command=bonjour)
b.pack(side=LEFT)
b1 = Button(frame, text="B2", command=aurevoir)
b1.pack(side=RIGHT)
l = Label(root, text="Hello !")
l.pack(side=BOTTOM)
       
      
JextCopier dans Jext | Jext | Plugin Codegeek
Remarquez le parameter optionnel "command" des boutons. Ce paramètre pointe sur une méthode Python qui sera invoquée lors de la pression sur le bouton de la part de l'utilisateur. Outre ces quelques composants, le programme d'exemple AviGUI.py propose l'utilisation des boîtes de messages et d'entrée. L'affichage d'un message d'erreur nécessite l'importation du module tkMessageBox :

import tkMessageBox
tkMessageBox.showwarning("titre", "message")
       
      
JextCopier dans Jext
Vous êtes également en mesure d'invoquer un message d'information par la méthode showinfo(). Les exemples de l'article se trouvent sur le CD-Rom au sein des fichiers etiquettes.py et frame.py. Reportez-vous également aux modules du calculateur de débit de trames AVI pour découvrir Tkinter. La prochaine étape de notre voyage sera wxPython, un toolkit graphique bien plus riche et évolué que Tkinter.

try:
  fsock = open(fileName, "rb", 0)
  fsock.seek(128)

  movieScale = struct.unpack("i", fsock.read(4))[0]
  movieRate = struct.unpack("i", fsock.read(4))[0]
  framerate = movieRate / movieScale

  fsock.close()
except IOError:
  print "Could not open", fileName
       
      
JextCopier dans Jext


par Romain Guy
romain.guy@jext.org
http://www.jext.org
Dernière mise à jour : 14/10/2006


Précédent  
  Python  
  Suivant

 
#ProgX©2005 Mathieu GINOD - Romain GUY - Erik LOUISE