Manipuler les tags des fichiers Ogg et FLAC

Sylvain Rougeaux

L'assemblage Luminescence.Xiph permet la lecture et l'écriture des tags au format Vorbis Comment dans les fichiers Ogg Vorbis, Ogg FLAC, FLAC natif et Speex. Les sources C# 3 sont sous LGPL.

- Titre : Manipuler les tags des fichiers Ogg et FLAC

- Auteur : Sylvain Rougeaux

- Parution : 14 mai 2009

- Licence : Copyright ® 2009 Sylvain Rougeaux. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. Un peu de théorie

- II-A. Le format de tags des fichiers Ogg et FLAC natifs : Vorbis Comment

- II-B. Le support des tags binaires

- III. L'implémentation du standard Vorbis Comment

- III-A. La lecture des tags textuels

- III-B. La prise en charge des tags "images"

- III-C. Le lecture des informations techniques

- III-D. La gestion du bloc "padding" dans les fichiers FLAC natifs

- III-E. Diagrammes des classes OggTagger et FlacTagger

- IV. Exemple d'utilisation de la librairie

- V. Téléchargements et liens

- VI. Conclusions

- VII. Remerciements

I - Introduction

Je développe depuis 2005 maintenant un éditeur de tag gratuit du nom de MetatOGGer. Comme son nom l'indique, il a été conçu à la base pour prendre en charge les fichiers Ogg et contribuer ainsi aux efforts de la fondation Xiph visant à développer un ensemble de briques multimédias gratuites et exempt de brevet (codec, conteneur, etc.). Le support des fichiers MP3 (tags ID3), Musepack, Windows Media, WavPack et Monkey's Audio a été ajouté par la suite. En fait, n'importe quel format peut être ajouté par le biais de plugin.

MetatOGGer est développé en C# (l'interface utilise l'API WPF depuis la version 3). Il me fallait donc une librairie .NET pour gérer les tags au format Vorbis Comment des fichiers Ogg. Ne trouvant pas ce qu'il me fallait sur internet, j'ai décidé de développer ma propre librairie.

II - Un peu de théorie

II-A - Le format de tags des fichiers Ogg et FLAC natifs : Vorbis Comment

Les tags des fichiers Ogg (Vorbis, FLAC et Speex), ainsi que des fichiers FLAC natifs sont stockés au format Vorbis Comment. Les spécifications(1) de ce format sont disponibles ici. Chaque tag au format Vorbis Comment est composé d'une paire clef-valeur sous la forme "TAG_NAME=Tag Value". La clef est une chaîne de caractère codée en ASCII (à l'exception du caractère "=", exclu car il sert à délimiter le nom du tag de sa valeur) et insensible à la casse (même si le nom du tag est souvent formaté en majuscule par convention). La valeur du tag est une chaîne de caractère codée en UTF8.

Le format Vorbis Comment définit quinze tags standards :

Nom du tag

Description

TITLE

Le titre du morceau

VERSION

Permet de distinguer plusieurs versions d'un même morceau : remix, live, etc.

ALBUM

Le titre de l'album

TRACKNUMBER

Le numéro de piste dans un album

ARTIST

Le nom de l'artiste ou de l'auteur

PERFORMER

Le nom de l'interprète, orchestre, etc.

COPYRIGHT

Les informations de copyright

LICENSE

La licence applicable au morceau : Creative Commons, tous droits réservés, etc.

ORGANIZATION

Organisation ayant produit le morceau comme le nom de la maison de disque

DESCRIPTION

Une description ou un commentaire quelconque sur le contenu

GENRE

Le genre du morceau : rock, pop, etc.

DATE

La date ou l'année d'enregistrement du morceau

LOCATION

Le lieu où le morceau a été enregistré

CONTACT

Une information de contact de l'auteur ou du distributeur

ISRC

Numéro ISRC du morceau

Au-delà de ces tags standards, tout tag arbitraire peut bien évidemment être ajouté. Le risque étant que les lecteurs audio ne sachent comment interpréter ces tags non standards.

Les tags Vorbis Comment peuvent être définis un nombre de fois illimité. Par exemple, il est tout à fait possible de définir plusieurs fois le tag ARTIST : "ARTIST=John Lennon" et "ARTIST=Paul McCartney".

II-B - Le support des tags binaires

Le standard Vorbis Comment ne prévoit pas le stockage de contenu autre que textuel. Ceci est problématique pour le stockage de contenu binaire comme les images.

Le développeur du codec FLAC ayant souhaité ajouter le support des images dans son format, il a prévu la possibilité d'ajouter un "bloc image" comparable à la frame APIC du standard ID3v2 du format MP3.

III - L'implémentation du standard Vorbis Comment

Les deux classes principales de la librairie sont les classes OggTagger et FlacTagger. Elles permettent respectivement la lecture des informations dans les fichiers Ogg (.ogg, .oga) et FLAC natifs (.flac, .fla).

III-A - La lecture des tags textuels

Le constructeur des classes OggTagger et FlacTagger prend en paramètre une chaîne de caractère correspondant au chemin du fichier. Les tags du fichier sont alors immédiatement lus.

Il est possible de forcer la lecture des tags d'un autre fichier sans avoir à instancier un nouvel objet en utilisant la méthode ReadMetadata.

Lecture des fichiers Ogg

OggTagger ogg = new OggTagger(@"C:\Song.ogg");
ogg.ReadMetadata(@"C:\Song2.ogg");

Les tags sont stockés dans un objet de type SortedList<string, List<string>> pour gérer les tags multiples. Il est possible de récupérer l'intégralité des tags du fichier avec la méthode GetAllTags.

Lecture des tags

string artist = ogg.Artist; // == tags["ARTIST"][0] || null
ReadOnlyCollection<string> artists = tags["ARTIST"];
ogg.Title = "My Immortal";
ogg.AddTag("LYRICS", "I am singing in the rain...");
ogg.SetTag("LYRICS", "I am not singing in the rain...");
ogg.RemoveTag("LYRICS");

Pour enregistrer les tags dans le fichier, il suffit d'appeler la méthode SaveMetadata.

Enregistrement des tags

ogg.SaveMetadata();

III-B - La prise en charge des tags "images"

Les tags "images" ne sont prises en charge que dans les fichiers Ogg FLAC ou FLAC natifs. Les images sont encapsulées dans des objets de type System.Windows.Media.Imaging.BitmapFrame (classe disponible dans l'assemblage PresentationCore.dll de l'API WPF).

Lecture de la pochette du disque

OggTagger ogg = new OggTagger(@"C:\SongFLAC.ogg");
Collection<ID3PictureFrame> arts = ogg.FlacArts;
BitmapFrame cover = null;
foreach (ID3PictureFrame picture in arts)
{
if (picture.PictureType == ID3PictureType.FrontCover)
cover = picture.Picture;
}

III-C - Le lecture des informations techniques

La librairie ne se limite pas à l'accès aux tags mais permet de récupérer de nombreuses informations techniques sur les fichiers.

Voici la liste des informations auxquelles la classe OggTagger permet d'accéder :

Propriétés

Type de retour

Commentaire

Codec

OggCodec (énumération)

Codec du fichier Ogg : Vorbis, Speex ou FLAC

SpeexBand

SpeexBand (énumération)

Largeur de bande utilisée pour le fichier Speex : Narrowband (8 000 Hz), WideBand (16 000 Hz) ou UltraWideband (32 000 Hz)

Channels

byte

Nombre de canaux

MinimumVorbisBitrate

int

Bitrate minimum du fichier Ogg Vorbis

SampleRate

int

Taux d'échantillonnage

MaximumVorbisBitrate

int

Bitrate maximum du fichier Ogg Vorbis

VorbisSpeexNominalBitrate

int

Bitrate nominal du fichier Ogg Vorbis et Speex

IsVariableBitrate

bool

Indique si le fichier est encodé en débit variable

VorbisQuality

float

Niveau de qualité du fichier Ogg Vorbis, de 0 (64 kb/s) à 1 (500 kb/s)

CodecVersion

string

Version du codec utilisé

Samples

long

Nombre d'échantillons

Duration

float

Durée du morceau en secondes

AverageBitrate

int

Débit moyen calculé

Ratio

float

Taux de compression du fichier

FlacBitsPerSample

byte

Taille de l'échantillon du fichier Ogg Flac

UncompressedFileLength

long

Taille calculé du fichier sans compression

Voici la liste des informations auxquelles la classe FlacTagger permet d'accéder :

Propriétés

Type de retour

Commentaire

Channels

byte

Nombre de canaux

SampleRate

int

Taux d'échantillonnage

CodecVersion

string

Version du codec utilisé

Samples

long

Nombre d'échantillons

Duration

float

Durée du morceau en secondes

AverageBitrate

int

Débit moyen calculé

Ratio

float

Taux de compression du fichier

BitsPerSample

byte

Taille de l'échantillon

UncompressedFileLength

long

Taille calculée du fichier sans compression

III-D - La gestion du bloc "padding" dans les fichiers FLAC natifs

Les tags Vorbis Comment sont enregistrés au début du fichier ce qui suppose la réécriture complète du fichier en cas de modification. Toutefois, les développeurs du format FLAC ont prévu la possibilité d'insérer un bloc "padding" au début de fichier pour servir de variable d'ajustement pour l'écriture des métadonnées. Ainsi, ce bloc peut être réduit pour laisser plus de place aux tags ou au contraire agrandit pour prendre la place des tags supprimés. Il est alors possible d'éviter la longue reconstruction du fichier, très lente dans le cas du FLAC, un format de compression sans perte dont les fichiers font souvent plusieurs dizaines de mégaoctets par morceaux.

La librairie gère le bloc "padding". Par défaut, ce bloc servira donc autant que faire se peut de variable d'ajustement pour accélérer la sauvegarde des modifications sur les tags. Il est toutefois possible de placer la propriété OptimizeFileSizeWhenSaving à vraie, ce qui aura pour effet de mettre la taille du bloc "padding" à 0 et de récupérer l'espace disque éventuellement laissé vacant par la suppression des tags.

Lorsque que la reconstruction du fichier est nécessaire parce que la taille du bloc "padding" n'est pas suffisante pour enregistrer les tags, ou lorsque la propriété OptimizeFileSizeWhenSaving est vraie, le développeur a la possibilité d'indiquer la taille du bloc "padding" qu'il souhaite voir insérer dans le fichier à l'occasion de sa reconstruction. Pour cela, il convient de définir la propriété DesiredPaddingSize (la valeur par défaut est fixée à 4 Ko).

III-E - Diagrammes des classes OggTagger et FlacTagger

IV - Exemple d'utilisation de la librairie

Le code source de la librairie est livré avec un projet WPF montrant comment utiliser la classe FlacTagger dans le cadre d'une application cliente.

Après avoir choisi un fichier FLAC en cliquant sur l'unique bouton, un objet FlacTagger est instancié et passé à la propriété DataContext de ma fenêtre WPF.

Ouverture du fihcier FLAC

OpenFileDialog open = new OpenFileDialog();
open.Filter = "Fichiers FLAC (*.flac)|*.flac";
if (!open.ShowDialog().Value) return;

FlacTagger flac = new FlacTagger(open.FileName);
DataContext = flac;

Il suffit ensuite d'utiliser les capacités avancées de Data Binding de WPF pour récupérer les valeurs des tags côté interface.

Binding des informations de tags

<TextBlock Text="{Binding Artist}" />
<TextBlock Text="{Binding Title}" Grid.Row="1" />
<TextBlock Text="{Binding Album}" Grid.Row="2" />
<TextBlock Text="{Binding TrackNumber}" Grid.Row="3" />
<TextBlock Text="{Binding Genre}" Grid.Row="4" />
<TextBlock Text="{Binding Date}" Grid.Row="5" />
<Image Source="{Binding Arts[0].Picture}"
MaxWidth="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Source.PixelWidth}"
MaxHeight="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Source.PixelHeight}"
Stretch="Uniform" Grid.Row="6" Grid.Column="1" />

Voici le code XAML pour "binder" les informations techniques du fichier FLAC. Remarquez l'utilisation de la propriété StringFormat de la classe Binding (disponible dans le Framework .NET 3.5 SP1) pour formater la chaîne.

Binding des informations techniques

<TextBlock Text="{Binding Channels}" />
<TextBlock Text="{Binding SampleRate, StringFormat={}{0:N0} Hertz}" Grid.Row="1" />
<TextBlock Text="{Binding CodecVersion, StringFormat={}FLAC {0}}" Grid.Row="2" />
<TextBlock Text="{Binding Duration, StringFormat={}{0:N0} secondes}" Grid.Row="3" />
<TextBlock Text="{Binding AverageBitrate, StringFormat={}{0:N0} bits par seconde}" Grid.Row="4" />
<TextBlock Text="{Binding Ratio, StringFormat={}{0:P}}" Grid.Row="5" />
<TextBlock Text="{Binding BitsPerSample, StringFormat={}{0} bits}" Grid.Row="6" />

V - Téléchargements et liens

Codes sources de l'assemblage Luminescence.Xiph

Site officiel Luminescence Software

VI - Conclusions

La librairie Luminescence.Xiph permet d'accéder facilement aux tags des fichiers Ogg et FLAC natifs. Le code est entièrement documenté et livré avec une batterie de tests unitaires. Les sources sont sous LGPL, ce qui permet à l'assemblage d'être utilisé dans des applications propriétaires.

VII - Remerciements

Je remercie l'équipe .NET pour leurs relectures de ce document.