Eine Delphi -Bibliothek für Audiodateien.
Lesen und schreiben Sie Meta -Tags (wie Künstler, Titel, Album, Genre, ...) aus vielen verschiedenen Audioformaten und sammeln Sie Informationen über die Audio -Datei (wie Dauer, Bitrate, Sample). AudiowerKiegebibliothek ist mit einer sehr einfachen Verwendung für grundlegende Informationen ausgestattet, enthält jedoch auch leistungsstarke Funktionen für einen detaillierten Zugriff auf fast alle Arten von Meta-Daten.
Unterstützte Tag -Formate ( fett: neu in v3.0 ):
Einschränkungen:
Eigentum TTagItem.DataSize .
URL -Frames hinzugefügt und einen Kommentar zu TID3v2Tag.GetUnusedTextTags hinzugefügt.
Methode TOggContainer.ReadPackets(Target: TObjectList) , um alle Pakete aus dem Oggstream abzurufen.
Eigenschaft TOpusFile.VBR (was in fast jedem Fall True sein sollte) *
Methoden zum Lesen/Schreiben von Ganzzahlatomen in M4A -Dateien. HINWEIS: Verwendung mit Vorsicht. Ich brauche dies in meinem Hauptprojekt "NEMP" für das "TMPO" -atom (auch bekannt als BPM, schlägt pro Minute), aber dies ist nicht weit verbreitet auf andere Atome. Die Dokumentation dort ist nicht sehr hilfreich, und es gibt einige Inkonsistenzen in Bezug auf signierte/nicht signierte Ganzzahlen und die Größe der Werte (8, 16, 24, 32 Bit).
Tagtype in TApeTag.GetUnusedTextTags war ttVorbis , korrekt is ttApev2 .
Getter und Setter für TApeTag.EAN verwendeten verschiedene Schlüssel.
Die Unordnung wurde mit Kardinal/Ganzzahl -Typ für SerialNumber in Oggpages behoben.
FLAC -Dateien: gelöschte veraltete Funktion fisvalid gelöscht
Ein Parsenfehler in Bezug auf OGGPages und Oggpackets (die sich nicht auf OGG/OPUS -Dateien auswirkten, jedoch auf die neuen Methoden -ReadPackets).
Die Bibliothek AudiowerKiegebibliothek stammt aus mehreren formatspezifischen Bibliotheken für MP3, Flagge, OGG und andere. Aus diesem Grund gab es eine Menge Belastung der Vergangenheit im Code. Einige Duplikate, keine Konsistenz in Parameterreihenfolge, Typ oder Benennung und einige andere Unannehmlichkeiten.
Mit Version 3.0 versuche ich, die allgemeine Konsistenz und Verwendbarkeit der bereitgestellten Methoden zu verbessern. Es ist jedoch nicht möglich, dies nach unten kompatibel zu tun.
Es gibt viele, viele Änderungen, und Sie müssen entsprechende Änderungen in Ihrem Code vornehmen.
Weitere Informationen finden Sie unter ChangeLog.
Sie können diese Bibliothek auf verschiedenen "Ebenen" verwenden, aber es gibt keine wirkliche Unterscheidung zwischen diesen Ebenen. Sie können einfach mehr oder weniger aus den Funktionen dieser Bibliothek verwenden. Je nachdem, was Sie tun möchten, wird empfohlen, mehr oder weniger über die innere Struktur von "Audiodateien" zu wissen.
TTagItem -Klasse. Viele dieser Objekte enthalten Textinformationen, aber auch Bilder oder andere binäre Daten sind möglich.Beispiele finden Sie in den Demo -Projekten.
TBaseAudioFile (Einheit audioFiles.base.pas): Eine abstrakte Klasse, die einige grundlegende Eigenschaften wie Titel, Künstler, Album, Dauer und einige andere deklariert, die dann in den folgenden TxxxFile -Klassen implementiert werden.TMP3File , TOggVorbisFile , TFlacFile , ... (separate Einheiten): Klassen für die verschiedenen Filetypen, die die in TbaseAudiofile deklarierten abstrakten Methoden implementieren und einige weitere Methoden definieren können. Wenn Sie weitere Informationen zu einer Datei wünschen, müssen Sie möglicherweise explizit auf die Eigenschaften und Methoden dieser abgeleiteten Klassen zugreifen. Es gibt auch einige "Zwischenklassen" wie TBaseApeFile oder TBaseVorbisFile für mehrere Dateitypen, die ApeV2-Tags oder Vorbis-Kommentare enthalten.TAudioFileFactory (Einheit audioFiles.factory.pas): Die Werksklasse zum Erstellen der richtigen Audio -Dateiinstanzen basierend auf der Dateierweiterung.TTagItem (Einheit audiofiles.basetags.pas): Die abstrakte Basisklasse für alle einzelnen Elemente in einem Metadatenbehälter. Im Wesentlichen werden ein "Schlüssel" und ein "Wert" bereitgestellt, das durch einige andere Informationen über das Datenelement ergänzt wird. Daraus abgeleitet sind die Klassen TID3v2Frame , TApeTagItem , TCommentVector und einige andere.TID3v1Tag , TID3V2Tag , TApeTag , TVorbisComments ... (getrennte Einheiten, kein gemeinsamer Vorfahren): Umsetzung der einzelnen Metadatenbehälter. Extrem vereinfacht: Eine Liste von TTAGItEMs. Für Anfänger ist die Verwendung dieser Bibliothek super einfach. Verwenden Sie einfach das Werk, um ein Objekt vom Typ TBaseAudioFile zu erstellen, um einige der Eigenschaften anzuzeigen. Lassen Sie den Benutzer einige der Werte bearbeiten und die Datei aktualisieren. Das ist alles. Funktioniert an allen unterstützten Dateiformaten - MP3, OGG, FLAC, M4A, es spielt keine Rolle. Gleicher Code für alle.
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; Beachten Sie, dass Sie das AudioFileFactory-Object nicht erstellen (oder kostenlos) erstellen müssen. Dies wird von der Einheit AudioFiles.Factory.pas automatisch behandelt.
Einzelheiten siehe Demo "Demosimple".
Wichtiger Hinweis: Die Fabrik ist wahrscheinlich nicht mit Thread-Safe. Wenn Sie es in einem sekundären Thread verwenden möchten, sollten Sie eine andere Fabrik im Kontext des Threads erstellen.
Wenn die benannten Eigenschaften (wie Künstler, Titel und andere) nicht ausreichend sind, gibt es die Methode audioFile.GetTagList (neu in Version 3 dieser Bibliothek). Auf diese Weise können Sie alle Datenelemente in einer Datei auflisten und bearbeiten.
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 ;Um ein Element aus dieser Liste zu bearbeiten, können Sie den folgenden Code verwenden:
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 ; Während die meisten Metadaten in Audio -Dateien Text enthalten, gibt es einige Daten, die eine komplexere Struktur haben oder sogar reine Binärdaten enthalten. Wie die Art der Daten erkannt werden kann, unterscheidet sich von Format zu Format. Die möglichen Typen sind manchmal auch mehr und manchmal weniger differenziert. Es gibt auch einige Feinheiten, die mit den "Texten" berücksichtigt werden müssen, insbesondere mit dem ID3V2 -Tag. Dort enthalten "Texte" beispielsweise nicht nur den Text selbst, sondern auch einige zusätzliche Daten - z. B. die Sprache. Zu diesem Zweck liefert der Audio -Werktzeuge -Bibliothek die Aufzählungstypen teTagContentType und teTextMode . Der TagContentType enthält Informationen zum Inhaltstyp. Zusätzlich zu einigen allgemein gültigen Typen ( tctText, tctPicture, tctBinary ) gibt es verschiedene formatspezifische Typen wie tctLyrics oder tctUserText für ID3V2, tctExternal für APEV2 oder tctGenre für M4A-Dateien. Für einige dieser Typen ist es vernünftig, sie als Text zu betrachten, auch wenn sie eine andere interne Struktur haben und separat behandelt werden sollten. Der Parameter Textmode kann für diesen Zweck auf tmReasonable gesetzt werden. Beim Lesen der Daten ist auch tmForced verfügbar. Anschließend werden Binärdaten auch in Textform angezeigt (nicht druckbare Zeichen werden durch Punkte ersetzt ".").
Die Methode AudioFile.GetTagList(TagItems); hat einen optionalen Parameter, bei dem Sie definieren können, welche Art von Tags Sie in der Liste der TagItems enthalten sein möchten.
procedure GetTagList(Dest: TTagItemList; ContentTypes: TTagContentTypes = cDefaultTagContentTypes);
Der Standardwert gibt alle Arten von Tags zurück, die als Text interpretiert werden können, dh
cDefaultTagContentTypes = [tctText, tctComment, tctLyrics, tctURL, tctUserText, tctUserURL, tctExternal, tctTrackOrDiskNumber, tctGenre, tctSpecialText];
Die meisten Metadaten -Container ermöglichen mehr als ein Bild, auch bekannt als "Cover Art". Wenn Sie das Cover -Kunst anzeigen möchten, müssen Sie zuerst eine Liste aller Bild -Tag -Elemente erhalten.
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 ;Weitere Informationen finden Sie in der Demo "Demoextended".
Auf Expertenebene verwenden Sie das grundlegende Klassen TBaseAudioFile nicht mehr so oft. Stattdessen arbeiten Sie direkt mit den abgeleiteten Klassen und den spezifischen Metadatenbehältern zusammen.
Da dies Ihnen einen sehr grundlegenden Zugriff auf die Dateien und deren interne Struktur bietet, können Sie auch viel Unsinn mit ihnen machen, was zu Problemen mit anderen Programmen führen kann. Sei es, weil Sie sich nicht an den dokumentierten Standard halten oder weil Sie allgemein anerkannte inoffizielle Regeln brechen. Das Schreiben eines ID3V2 -Tags in eine OGG -Datei ist möglich, aber sicherlich keine gute Idee. Weder schreibt ein Vorbis -Kommentar in eine MP3 -Datei.
Verwenden Sie die Optionen mit Vorsicht - insbesondere mit Schreibzugriff.
Weitere Informationen zu den Möglichkeiten finden Sie in der Demo "Demomp3" (aber nicht immer empfohlen, einige Spieler können dann über diese Dateien stolpern).
In der Datei können mehrere Audioformate verschiedene Arten von Meta -Daten enthalten. Diese Bibliothek verwendet die folgenden Annahmen
MP3-Dateien enthalten normalerweise ID3V1 und ID3V2-Tags. Bei Verwendung der Klasse TMP3File wird normalerweise sichergestellt, dass beide Versionen in der Datei konsistent bleiben.
MP3-Dateien enthalten manchmal auch einen APEV2-Tag. Dieses Tag wird jetzt auch von der Klasse TMP3File vollständig verarbeitet. Durch das Festlegen grundlegender Eigenschaften wird sichergestellt, dass alle Meta -Tags konsistent bleiben. Stellen Sie sicher, dass die Eigenschaft TagsToBeWritten mt_Existing enthält (was der Standardwert ist).
Es gibt keinen Standardschlüssel für "Texte" in Vorbis -Kommentaren und APEV2 -Tags. Nach meinen Forschungen werden die folgenden Varianten verwendet: UNSYNCEDLYRICS , UNSYNCED LYRICS (mit einem Raum) und LYRICS . Diese drei Schlüssel werden beim Lesen von "Texten" berücksichtigt. Beim Schreiben wird der vorhandene Schlüssel verwendet. Wenn keiner der drei Varianten verfügbar ist, wird der Schlüssel in der globalen Variablen AWB_DefaultLyricsKey verwendet. Der Standardwert ist UNSYNCEDLYRICS .
Alle Audioformate, die standardmäßig APEV2-Tags verwenden (Monkey, Wavpack, Mussepack, Optimfrog, Truaudio) können auch ID3V1- und ID3V2-Tags enthalten. Die TxxxFile Klassen für diese Formate verarbeiten die ID3V1-Tag jetzt vollständig. Die Existenz eines ID3V2-Tags wird festgestellt (und die Größe wird bei Bedarf für die Berechnung der Dauer berücksichtigt), aber ansonsten ignoriert.
Für MP3-Dateien und APE-basierte Dateien können Sie Eigenschaften TagsToBeWritten , TagsToBeDeleted und DefaultTags verwenden, um zu entscheiden, welche Meta-Tags bei Verwendung der Methode UpdateFile oder RemoveFromFile in/aus der Datei geschrieben/entfernt werden. Die Standardeinstellungen sind
// 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 Wenn Sie mehrere Dateien nach Meta-Daten scannen (z. B. um die Daten in einer Medienbibliothek zu speichern), möchten Sie möglicherweise nur den "Titel", aber es ist Ihnen egal, ob sie aus dem ID3V2- oder dem ID3V1-Tag stammen. Um das Scannen zu beschleunigen (zumindest ist dies die Hoffnung), wird der Eigenschafts TagScanMode eingeführt. Mögliche Werte sind
TTagScanMode = (id3_read_complete, id3_read_smart, id3_read_v2_only ); Der Standardwert ist id3_read_complete , wobei alle enthaltenen Tags verarbeitet werden. Die Option id3_read_smart überprüft zuerst die ID3V2-Tag. Dieses Meta -Tag ist komplexer, muss aber trotzdem gelesen werden, um zu den Audio -Meta -Daten wie Bitrate, Dauer und anderen Dingen zu gelangen. Im Smart-Modus wird der ID3V1-Tag nur aus der Datei gelesen, wenn es keinen richtigen ID3V2-Tag gibt, der Künstler, Titel, Album, Track, Jahr und Genre enthält. Wenn Sie auch das Feld "Kommentar" enthalten möchten, setzen Sie fSmartRead_IgnoreComment auf False .
Wenn Sie eines dieser Eigenschaften durch die Setter der Klasse TMP3File ändern, wird die Eigenschaft fSmartRead_AvoidInconsistentData (Standard: True ) sicherstellen, dass auch der ID3V1-Tag ordnungsgemäß verarbeitet wird, sodass UpdateFile sowohl ID3V1- als auch ID3V2-Tag mit konsistenten Daten schreibt (gemäß der Einstellung von TagWriteMode ).
Hinweis: Für APE-basierte Dateien ist dies nicht erforderlich. Nach Erkennung von APE-Tags müssen auch ID3V1-Tags nach Überprüfung (und Lesen) geprüft werden, sodass keine signifikante Beschleunigung möglich ist.
Normalerweise enthalten MP3-Dateien, die mit variablen Bitrate codiert sind, einen sogenannten Xing-Header (oder ähnlichen), der zusätzliche Daten enthält, die für eine schnelle Berechnung der Dauer der Datei benötigt werden. Kürzlich habe ich einige Dateien ohne einen solchen Xing-Header gefunden, was zu viel länger berechneten Dauer und viel zu niedrigen Bitraten (dh 32 kbit/s) führte. Dies war nicht nur für diese Bibliothek ein Problem, sondern für viele andere Bibliotheken.
Für solche Dateien wird die neue Eigenschaft TMP3File.MpegScanMode eingeführt. Mögliche Werte sind
TMpegScanMode = (MPEG_SCAN_Fast, MPEG_SCAN_Smart, MPEG_SCAN_Complete);MPEG_SCAN_Fast scannt die Datei wie zuvor, in gutem Glauben enthält eine VBR-Datei einen Xing-Header (oder etwas Äquivalentes). Dies funktioniert in den meisten Fällen sehr gut.MPEG_SCAN_Smart prüft, ob das Ergebnis aus dem schnellen Scan sinnvoll ist. Wenn das berechnete Bitrate 32 kbit/s (oder sogar niedriger ist, was tatsächlich ungültig wäre), stimmt wahrscheinlich etwas nicht. Daher wird die Datei vollständig verarbeitet und scannt jeden einzelnen MPEG-Frame. Beachten Sie, dass die meisten MP3 -Dateien mit einem kleinen Moment der Stille beginnen. Ein auf "VBR" eingestellter Encoder verwendet wahrscheinlich die minimale Menge an Platz, um dies zu codieren - was 32 kbit/s ist.MPEG_SCAN_Complete immer die vollständige Datei. Dies führt zu den genauesten Dauern, erfordert aber auch viel mehr Zeit. Der Standardmodus ist MPEG_SCAN_Smart .
Diese Bibliothek sollte mit allen Delphi -Versionen von Delphi 7 bis Delphi 12 funktionieren. Es gibt jedoch einige Dinge, die Sie mit älteren Versionen ohne integrierte Unicode-Unterstützung berücksichtigen müssen (= vor Delphi 2009).
HINWEIS : Ich verwende "Unicode" hier in der Bedeutung von "mehr als Ansi". Das ist nicht 100% genau, aber ich hoffe, Sie wissen, was ich sage. ;-)
Vor Delphi 2009 war die VCL ansimy und unterstützte Unicode nicht. Dies umfasst die Anzeige von Strings mit Unicode -Zeichen und das Öffnen von Dateien mit Unicode -Zeichen in ihren Dateinamen. Dafür gab es eine Sammlung von Komponenten namens "Tntunicodecontrols". Ältere Versionen dieser Sammlung waren im Rahmen einer Creative Commons -Lizenz erhältlich und sollten noch irgendwo gefunden werden.
Diese Bibliothek kann diese Steuerelemente verwenden, indem ein Compiler -Switch in der config.inc aktiviert wird. Entfernen Sie einfach das "." In der Zeile {.$DEFINE USE_TNT_COMPOS} .
In der Bibliothek selbst werden die TNTs für die Klasse TNTFileStream verwendet. Natürlich können Sie auch andere Unicode -fähige FileStream -Klassen verwenden. Passen Sie einfach diese Codezeilen entsprechend Ihren Anforderungen an: (Datei: audioFiles.declarations.pas)
{ $IFDEF USE_TNT_COMPOS }
TAudioFileStream = TTNTFileStream;
{ $ELSE }
TAudioFileStream = TFileStream;
{ $ENDIF }Wenn Sie eine ältere Delphi -Version ohne tntunicodeControls verwenden, funktioniert diese Bibliothek weiterhin, aber Sie können Dateien nicht mit Dateinamen wie "จักรพรรณ์ อาบครบุรี - 10 เท่านี้ก็ตรม. MP3" öffnen. Wenn Sie versuchen, Informationen über Titel und Künstler aus einer solchen Datei anzuzeigen (nach dem Umbenennen nach dem Umbenennen), werden Sie nur einige "?????" sehen, "?????" anstelle des tatsächlichen Titels. Beachten Sie, dass das Umschreiben der Meta -Tags unter solchen Bedingungen zu einem Datenverlust führen kann.
Hinweis : Die Beispielprojekte verwenden die TNTControls (wie TtnTeTit anstelle von Tedit) nicht. Seien Sie vorsichtig mit älteren Delphis. ;-)
Neuere Delphi-Versionen (2009 und später) haben eine integrierte Unicode-Unterstützung, und daher ist die Verwendung dieser TntunicodeControls nicht erforderlich. Darüber hinaus wird die Definition des Typs UnicodeString dort nicht benötigt. Dies ist der Grund für diesen Compiler -Switch:
{$IFNDEF UNICODE}
UnicodeString = WideString;
{$ENDIF}
In Version 2.0 dieser Bibliothek verwende ich ein Werksmuster für die verschiedenen Arten von AudiOFiles. Eine Klasse für ein bestimmtes Audiodateiformat ist in der Fabrikklasse registriert. Für die Verwaltung aller registrierten Klassen verwendet die Fabrikklasse standardmäßig ein TDictionary. Wenn Ihre Delphi -Version nicht unterstützt wird, definieren Sie ihre Verwendung im confic.inc . In diesem Fall wird dafür eine reguläre Tobjektliste verwendet.
{$DEFINE USE_DICTIONARY}
Um die Zugriffsgeschwindigkeit in der Tobjectlist zu erhöhen, wird sie unter Verwendung der "Transponierungsmethode" als selbstorganisierende Liste implementiert. Wenn eine Audiodatei mit einer bestimmten Dateiname -Erweiterung über die Fabrik erstellt wird, wird diese Erweiterung/Klasse in der Liste nach oben verschoben, wodurch die Zeit verkürzt, um sie erneut zu finden.
Diese Bibliothek sollte in den meisten Fällen Informationen aus allen Arten von Audiodateien korrekt lesen. Es gibt jedoch einige merkwürdige Audio -Dateien "in der Wildnis", wobei Methoden oder Varianten, die von dieser Bibliothek nicht ordnungsgemäß behandelt wurden, verwendet. Ich denke, dass ich nach den Streckenjahre gerade mit fast allem umgehe, aber es könnte immer noch einige seltene Fälle geben, in denen ich fehlt.
Wenn Sie einen Fehler gefunden haben oder über einige Audiodateien (insbesondere MP3 -Dateien!) Verfügen, wobei die Methoden dieser Bibliothek falsche Daten liefern, kontaktieren Sie mich bitte und/oder senden Sie einige Beispieldateien an [email protected].
Aber ich kann nicht alles reparieren (und werde nicht). Das Verrückteste, was ich je gesehen habe, war ein ID3V2TAG mit der folgenden Codierung: UTF-16 (fein), null-terminiert (mehr oder weniger Standard), beginnend mit einer Bom (OK ...), Charakter-für-Charakter (WTF ...?)-Ja, kein Scherz. Insgesamt 6 Bytes pro Charakter ...