Une bibliothèque Delphi pour les fichiers audio.
Lisez et écrivez des tags Meta (comme l'artiste, le titre, l'album, le genre, ...) de nombreux formats audio différents, et recueillent des informations sur le fichier audio (comme durée, débit binaire, samplerate). Audiowerkzeugebibliothek est livré avec une utilisation très simple pour les informations de base, mais elle contient également des fonctionnalités puissantes pour un accès approfondi à presque toutes les méta-données.
Formats de balise pris en charge ( gras: nouveau dans v3.0 ):
Limites:
Propriété TTagItem.DataSize .
Ajout de cadres URL et de commentaires à TID3v2Tag.GetUnusedTextTags .
Méthode TOggContainer.ReadPackets(Target: TObjectList) pour obtenir tous les paquets à partir du OggStream.
Propriété TOpusFile.VBR (ce qui devrait être True dans presque tous les cas) *
Méthodes pour lire / écrire des atomes entiers dans les fichiers M4A. Remarque: utilisez avec prudence. J'en ai besoin dans mon projet principal "NEMP" pour l'atome "TMPO" (alias BPM, bat par minute), mais cela n'est pas largement testé pour d'autres atomes. La documentation n'est pas très utile, et il y a des incohérences concernant les entiers signés / non signés et la taille des valeurs (8, 16, 24, 32 bits).
TagType dans TApeTag.GetUnusedTextTags était ttVorbis , correct est ttApev2 .
Getter et Setter pour TApeTag.EAN ont utilisé différentes touches.
Correction de l'encombrement avec un type cardinal / entier pour SerialNumber dans les pages OGG.
Fichiers FLAC: fonction dépréciée supprimée fisvalid
Correction d'une erreur d'analyse concernant les pages ogg et les paquets ogg (qui n'avaient en fait aucun effet sur les fichiers ogg / opus, mais sur la nouvelle méthode ReadPackets).
La bibliothèque Audiowerkzeugebibliothek est originaire de plusieurs bibliothèques spécifiques au format pour MP3, Flag, Ogg et autres. Pour cette raison, il y avait beaucoup de fardeau du passé contenu dans le code. Certains doublons, aucune cohérence dans l'ordre des paramètres, le type ou la dénomination, et quelques autres inconvénients.
Avec la version 3.0, j'essaie d'améliorer la cohérence globale et la convivialité des méthodes fournies. Cependant, il n'est pas possible de faire cela compatible à la baisse.
Il y a beaucoup, beaucoup de modifications, et vous devrez apporter des modifications correspondantes dans votre code.
Voir Changelog pour certains détails.
Vous pouvez utiliser cette bibliothèque à différents "niveaux", mais il n'y a pas de différenciation réelle entre ces niveaux. Vous pouvez simplement utiliser plus ou moins à partir des fonctionnalités de cette bibliothèque. Selon ce que vous voulez faire, il est recommandé de savoir plus ou moins sur la structure intérieure des "fichiers audio".
TTagItem . Beaucoup de ces objets contiennent des informations de texte, mais des images ou d'autres données binaires sont également possibles.Voir les projets de démonstration pour des exemples.
TBaseAudioFile (unit audiofiles.base.pas): une classe abstraite qui déclare certaines propriétés de base comme le titre, l'artiste, l'album, la durée et d'autres, qui sont ensuite implémentés dans les classes TxxxFile suivantes.TMP3File , TOggVorbisFile , TFlacFile , ... (unités séparées): classes pour plusieurs filetypes, qui mettent en œuvre les méthodes abstraites déclarées dans tbaseAudiofile, et peuvent définir d'autres méthodes. Si vous souhaitez plus d'informations sur un fichier, vous devrez peut-être accéder explicitement aux propriétés et aux méthodes de ces classes dérivées. Il existe également des "classes intermédiaires" comme TBaseApeFile ou TBaseVorbisFile pour plusieurs types de fichiers contenant des commentaires APEV2-Tags ou Vorbis.TAudioFileFactory (unit audiofiles.factory.pas): la classe d'usine pour créer les instances de fichiers audio correctes basées sur l'extension de fichier.TTagItem (unit audiofiles.basetags.pas): la classe de base abstraite pour tous les éléments individuels dans un conteneur de métadonnées. Essentiellement, une "clé" et une "valeur" sont fournies, complétées par quelques autres informations sur l'élément de données. Les classes TID3v2Frame , TApeTagItem , TCommentVector et quelques autres.TID3v1Tag , TID3V2Tag , TApeTag , TVorbisComments ... (Unités distinctes, pas d'ancêtre commun): mise en œuvre des conteneurs de métadonnées individuels. Extrêmement simplifié: une liste de ttagitems. Pour les débutants, l'utilisation de cette bibliothèque est super facile. Utilisez simplement l'usine pour créer un objet de type TBaseAudioFile pour afficher certaines des propriétés, permettez à l'utilisateur de modifier certaines valeurs et de mettre à jour le fichier. C'est tout. Fonctionne sur tous les formats de fichiers pris en charge - MP3, OGG, FLAC, M4A, cela n'a pas d'importance. Même code pour tous.
var
MainAudioFile: TBaseAudioFile;
// ...
MainAudioFile := AudioFileFactory.CreateAudioFile(aFileName);
MainAudioFile.ReadFromFile(aFileName);
EditTitle.Text := MainAudioFile.Title;
// ... and for editing the file:
MainAudioFile.Title := EditTitle.Text;
MainAudioFile.UpdateFile; Notez que vous n'avez pas besoin de créer (ou gratuitement) le Object de AudioFileFactory. Ceci est géré par l'unité AudioFiles.Factory.pas automatiquement.
Voir démo "Demosimple" pour plus de détails.
Remarque importante: L'usine n'est probablement pas un filetage. Si vous souhaitez l'utiliser dans un thread secondaire, vous devez créer une autre usine dans le contexte du fil.
Si les propriétés nommées fournies (telles que l'artiste, le titre et autres) ne sont pas suffisantes, il existe la méthode AudioFile.gettagList (nouveau dans la version 3 de cette bibliothèque). Cela vous permet de répertorier et de modifier tous les éléments de données d'un fichier.
lvMetaTags.Clear; // a ListView on the Form
TagItems := TTagItemList.Create;
try
AudioFile.GetTagList(TagItems);
for i := 0 to TagItems.Count - 1 do begin
newListItem := lvMetaTags.Items.Add;
newListItem.Data := TagItems[i];
newListItem.Caption := cTagTypes[TagItems[i].TagType];
newListItem.SubItems.Add(TagItems[i].Key);
newListItem.SubItems.Add(TagItems[i].Description);
newListItem.SubItems.Add(TagItems[i].GetText(tmReasonable));
end ;
finally
TagItems.Free;
end ;Pour modifier un élément de cette liste, vous pouvez utiliser le code suivant:
editItem := TTagItem(lvMetaTags.Selected.Data);
editValue := editItem.GetText(tmReasonable);
if InputQuery( ' Edit Item ' , ' New value: ' , editValue) then begin
if editValue = ' ' then
AudioFile.DeleteTagItem(editItem)
else
TTagItem(editItem).SetText(editValue, tmReasonable);
end ; Bien que la plupart des métadonnées dans les fichiers audio contiennent du texte, il existe des données qui ont une structure plus complexe ou qui contient même des données binaires pures. La façon dont le type de données peut être reconnu diffère du format à un format. Les types possibles sont également parfois plus et parfois moins différenciés. Et il y a aussi certaines subtilités à considérer avec les "textes", en particulier avec la balise ID3V2. Là, par exemple, les "paroles" contiennent non seulement le texte lui-même, mais aussi quelques données supplémentaires - par exemple la langue. À cette fin, l'audio Werkzeuge Bibliothek fournit les types d'énumération teTagContentType et teTextMode . Le TagContentType fournit des informations sur le type de contenu. En plus de quelques types généralement valides ( tctText, tctPicture, tctBinary ), il existe différents types spécifiques au format tels que tctLyrics ou tctUserText pour ID3V2, tctExternal pour APEV2 ou tctGenre pour les fichiers M4A. Pour certains de ces types, il est raisonnable de les considérer comme du texte, même s'ils ont une structure interne différente et doivent être traités séparément. Le paramètre TextMode peut être défini sur tmReasonable à cet effet. Lors de la lecture des données, tmForced est également disponible. Les données binaires sont ensuite également affichées sous forme de texte (les caractères non imprimables sont remplacés par des points ".").
La méthode AudioFile.GetTagList(TagItems); A un paramètre facultatif, où vous pouvez définir le type de balises que vous souhaitez inclure dans la liste Tagitems.
procedure GetTagList(Dest: TTagItemList; ContentTypes: TTagContentTypes = cDefaultTagContentTypes);
La valeur par défaut renvoie toutes sortes de balises qui peuvent être interprétées comme du texte, c'est-à-dire
cDefaultTagContentTypes = [tctText, tctComment, tctLyrics, tctURL, tctUserText, tctUserURL, tctExternal, tctTrackOrDiskNumber, tctGenre, tctSpecialText];
La plupart des conteneurs de métadonnées permettent plus d'une image, alias "Cover Art". Si vous souhaitez afficher la couverture, vous devez d'abord obtenir une liste de tous les éléments de balise d'image.
picList := TTagItemList.Create;
try
AudioFile.GetTagList(picList, [tctPicture]);
if picList.Count > 0 then begin
// show first picture in the list, or try to get the "Front Cover"
// here: Just diplay the first one in the list (which ist often
// the only one)
stream := TMemoryStream.Create;
try
if picList[ 0 ].GetPicture(stream, Mime, PicType, Description)
then begin
Stream.Position := 0 ;
// Modern versions of Delphi also recognize the graphic type when
// using LoadFromStream
// For older versions, you may have to adapt the code depending
// on the mimetype.
Image1.Picture.LoadFromStream(Stream);
end ;
finally
stream.Free;
end ;
end ;
finally
picList.Free;
end ;Voir démo "Deoextend" pour plus de détails.
Au niveau expert, vous n'utilisez plus souvent la classe de base TBaseAudioFile . Au lieu de cela, vous travaillez directement avec les classes dérivées et les conteneurs de métadonnées spécifiques.
Comme cela vous donne un accès très basique aux fichiers et à leur structure interne, vous pouvez également faire beaucoup de bêtises avec eux, ce qui peut entraîner des problèmes avec d'autres programmes. Que ce soit parce que vous n'adhérez pas à la norme documentée ou parce que vous enfreignez les règles non officielles généralement reconnues. L'écriture d'une balise ID3V2 dans un fichier OGG est possible, mais certainement pas une bonne idée. Écrit non plus un commentaire Vorbis dans un fichier MP3.
Utilisez les options fournies avec prudence - en particulier avec l'accès en écriture.
Voir la démo "Demomp3" pour plus de détails sur ce qui est possible (mais pas toujours recommandé, certains joueurs peuvent alors trébucher sur ces fichiers).
Plusieurs formats audio peuvent contenir différents types de méta-données dans le fichier. Cette bibliothèque utilise les hypothèses suivantes
Les fichiers MP3 contiennent généralement des tags ID3V1 et ID3v2. Lorsque vous utilisez la classe TMP3File , il est généralement assuré que les deux versions restent cohérentes dans le fichier.
Les fichiers MP3 contiennent parfois également un APEV2-Tag. Cette balise est désormais également entièrement traitée par la classe TMP3File . La définition des propriétés de base garantira que toutes les balises de méta restent cohérentes. Assurez-vous que la propriété TagsToBeWritten contient mt_Existing (qui est la valeur par défaut).
Il n'y a pas de clé standard définie pour les "paroles" dans les commentaires Vorbis et les balises APEV2. Selon mes recherches, les variantes suivantes sont utilisées: UNSYNCEDLYRICS , UNSYNCED LYRICS (avec un espace) et LYRICS . Ces trois clés sont prises en compte lors de la lecture des «paroles». Lors de l'écriture, la clé existante est utilisée. Si aucune des trois variantes n'est disponible, l'ensemble des clés de la variable globale AWB_DefaultLyricsKey est utilisé. La valeur par défaut n'est UNSYNCEDLYRICS .
Tous les formats audio utilisant des tags APEV2 par défaut (singe, wavpack, musipack, optimfrog, trueAudio) peuvent également contenir des tags id3v1- et id3v2. Les classes TxxxFile pour ces formats traitent désormais entièrement le tag ID3v1. L'existence d'une tag ID3V2 est détectée (et sa taille est prise en compte pour le calcul de la durée, si nécessaire), mais autrement ignoré.
Pour les fichiers MP3 et les fichiers basés sur les singes, vous pouvez utiliser des propriétés TagsToBeWritten , TagsToBeDeleted et DefaultTags pour décider quelles balises META sont écrites / supprimées dans / du fichier lors de l'utilisation du méthode UpdateFile ou RemoveFromFile . Les paramètres par défaut sont
// for mp3 files
TagsToBeWritten := [mt_Existing];
DefaultTags := [mt_ID3v1, mt_ID3v2]; // **
TagsToBeDeleted := [mt_Existing];
// for ApeV2-based file formats
TagsToBeWritten := [mt_Existing];
DefaultTags := [mt_ID3v1, mt_APE]; // **
TagsToBeDeleted := [mt_Existing];
// ** used when there are no meta tags at all Si vous numérisez plusieurs fichiers pour Meta Data (par exemple pour stocker les données dans une bibliothèque de médias), vous ne voudrez peut-être que le "titre", mais vous ne vous souciez pas de savoir s'il provient de l'ID3V2- ou du-Tag ID3V1. Pour accélérer le balayage (au moins c'est l'espoir), la propriété TagScanMode est introduite. Les valeurs possibles sont
TTagScanMode = (id3_read_complete, id3_read_smart, id3_read_v2_only ); La valeur par défaut est id3_read_complete , où toutes les balises contenues sont traitées. L'option id3_read_smart vérifiera d'abord le tag id3v2. Cette balise Meta est plus complexe, mais elle doit quand même être lue pour accéder aux méta-données audio comme le débit, la durée et d'autres choses. En mode intelligent, le tag ID3v1 n'est lu que dans le fichier, s'il n'y a pas de bon artiste, de titre, d'album, de piste, d'année et de genre. Si vous souhaitez également que le champ "Commentaire" inclus, définissez fSmartRead_IgnoreComment sur False .
Si vous modifiez l'une de ces propriétés via les setters de la classe TMP3File , la propriété fSmartRead_AvoidInconsistentData (par défaut: True ) garantira que le-Tag ID3V1 est également correctement traité, de sorte que UpdateFile écriture à la fois ID3V1-- et ID3V2-Tag avec des données cohérentes (selon le paramètre de TagWriteMode ).
Remarque: Pour les fichiers basés sur des singes, cela n'est pas nécessaire. La détection des APE-Tags nécessite toujours la vérification (et la lecture) des tags ID3V1, il n'y a donc pas de vitesse significative possible.
Habituellement, les fichiers MP3 codés avec un débit de binaire variable contiennent un soi-disant t-header (ou quelque chose de similaire) contenant des données supplémentaires nécessaires pour un calcul rapide de la durée du fichier. Récemment, j'ai trouvé des fichiers sans un tel tête de xing, ce qui entraîne des durées calculées beaucoup plus longues et des débits binaires beaucoup trop bas (c'est-à-dire 32 kbit / s). Ce n'était pas un problème uniquement pour cette bibliothèque, mais c'est toujours pour de nombreuses autres bibliothèques.
Pour de tels fichiers, la nouvelle propriété TMP3File.MpegScanMode est introduite. Les valeurs possibles sont
TMpegScanMode = (MPEG_SCAN_Fast, MPEG_SCAN_Smart, MPEG_SCAN_Complete);MPEG_SCAN_Fast analyse le fichier comme avant, de bonne foi qu'un fichier VBR contient un barreur Xing (ou quelque chose d'équivalent). Cela fonctionne très bien dans la plupart des cas.MPEG_SCAN_Smart CHECKS, si le résultat de l'analyse rapide est logique. Si le débit binaire calculé est de 32 kbit / s (ou même plus bas, ce qui serait en fait invalide), il y a probablement quelque chose de mal. Par conséquent, le fichier est entièrement traité, numérisant chaque mPEG-Frame. Notez que la plupart des fichiers MP3 commencent par un petit moment de silence. Un encodeur réglé sur "VBR" utilisera probablement la quantité minimale possible d'espace pour encoder celle - qui est de 32 kbit / s.MPEG_SCAN_Complete sans toujours le fichier complet. Cela conduit aux durées les plus précises, mais nécessite également beaucoup plus de temps. Le mode par défaut est MPEG_SCAN_Smart .
Cette bibliothèque devrait fonctionner avec toutes les versions Delphi de Delphi 7 à Delphi 12 . Cependant, il y a certaines choses à garder à l'esprit avec les anciennes versions sans support Unicode intégré (= avant Delphi 2009).
Remarque : j'utilise "Unicode" ici dans le sens de "plus qu'ANSI". Ce n'est pas précis à 100%, mais j'espère que vous savez ce que je dis. ;-)
Avant Delphi 2009, le VCL était ANSI uniquement et ne prenait pas en charge Unicode. Cela inclut l'affichage des chaînes avec des caractères Unicode et les fichiers d'ouverture avec des caractères Unicode dans leurs noms de fichiers. Pour cela, il y a eu une collection de composants appelés "tnUnicodeControls". Les versions plus anciennes de cette collection étaient disponibles sous une licence Creative Commons et devraient toujours être trouvées quelque part.
Cette bibliothèque peut utiliser ces contrôles en activant un commutateur de compilateur dans le fichier config.inc . Supprimez simplement le "." Dans la ligne {.$DEFINE USE_TNT_COMPOS} .
Au sein de la bibliothèque elle-même, les TNT sont utilisés pour la classe TNTFileStream . Bien sûr, vous pouvez également utiliser d'autres classes FileStream capables Unicode. Ajustez simplement ces lignes de code en fonction de vos besoins: (Fichier: AudioFiles.declarations.pas)
{ $IFDEF USE_TNT_COMPOS }
TAudioFileStream = TTNTFileStream;
{ $ELSE }
TAudioFileStream = TFileStream;
{ $ENDIF }Si vous utilisez une ancienne version de Delphi sans tnUnicodeControls, cette bibliothèque fonctionnera toujours, mais vous ne pouvez pas ouvrir de fichiers avec des noms de fichiers comme "จักรพรรณ์ อาบครบุรี - 10 เท่านี้ก็ตรม. Mp3". Lorsque vous essayez d'afficher des informations sur le titre et l'artiste à partir d'un tel fichier (après les avoir renommé), vous ne verrez que des "?????" au lieu du titre réel. Notez que la réécriture des balises de méta dans de telles conditions pourrait entraîner une perte de données.
Remarque : Les exemples de projets n'utilisent pas les TNTControls (comme tttedit au lieu de fedit). Soyez prudent là-bas avec des Delphis plus anciens. ;-)
Les versions Delphi plus récentes (2009 et plus tard) ont une prise en charge intégrée Unicode, et donc l'utilisation de ces tntunicodeControls n'est pas nécessaire. De plus, la définition du type UnicodeString n'y est pas nécessaire. C'est la raison de cet interrupteur de compilateur:
{$IFNDEF UNICODE}
UnicodeString = WideString;
{$ENDIF}
Dans la version 2.0 de cette bibliothèque, j'utilise un motif d'usine pour les différents types d'audiodiles. Une classe pour un format de fichier audio spécifique est enregistrée dans la classe d'usine. Pour gérer toutes les classes enregistrées, la classe d'usine utilise une tdictionnaire par défaut. Si votre version Delphi ne prend pas en charge Tdictionary, indemente son utilisation dans le confic.inc . Dans ce cas, une liste de tobject ordinaire sera utilisée pour cela.
{$DEFINE USE_DICTIONARY}
Pour augmenter la vitesse d'accès dans le TobjectList, il est implémenté comme une liste d'auto-organisation, en utilisant la "méthode de transposition". Si un fichier audio avec une extension de nom de fichier spécifique est créé via l'usine, cette extension / classe sera déplacée vers le haut dans la liste, ce qui réduit le temps de le retrouver.
Cette bibliothèque doit lire correctement les informations de tous les types de fichiers audio dans la plupart des cas. Cependant, il existe des fichiers audio étranges "dans la nature", en utilisant des méthodes ou des variantes qui ne sont pas correctement gérés par cette bibliothèque. Je pense qu'après des années de séparation, je fais face à presque tout en ce moment, mais il pourrait y avoir encore de rares cas qui me manquent.
Si vous avez trouvé un bogue, ou si vous avez des fichiers audio (en particulier les fichiers MP3!), Lorsque les méthodes de cette bibliothèque fournissent de mauvaises données, veuillez me contacter et / ou envoyer des exemples de fichiers à [email protected].
Mais je ne peux pas (et je ne vais pas) réparer tout. La chose la plus plus folle que j'aie jamais vue a été un id3v2tag avec le codage suivant: UTF-16 (très), terminal nul (plus ou moins standard), en commençant par une nomenclature (OK ...), caractéristique par personnage (WTF ...?) - Oui, pas de plaisanterie. Un total de 6 octets par caractère ...