Una biblioteca de Delphi para archivos de audio.
Lea y escriba metaetiquetas (como artista, título, álbum, género, ...) de muchos formatos de audio diferentes, y recopile información sobre el archivo de audio (como la duración, la tasa de bits, la muestra). Audiowerkzeugibibliothek viene con un uso muy simple para la información básica, pero también contiene características potentes para un acceso profundo a casi todo tipo de meta datos.
Formatos de etiqueta compatibles ( en negrita: Nuevo en v3.0 ):
Limitaciones:
Propiedad TTagItem.DataSize .
Se agregó marcos de URL y comente a TID3v2Tag.GetUnusedTextTags .
Método TOggContainer.ReadPackets(Target: TObjectList) para obtener todos los paquetes del OGGStream.
Propiedad TOpusFile.VBR (que debería ser True en casi todos los casos) *
Métodos para leer/escribir átomos enteros en archivos M4A. Nota: Use con precaución. Necesito esto en mi proyecto principal "Nemp" para el átomo "TMPO" (también conocido como BPM, ritmos por minuto), pero esto no se prueba ampliamente para otros átomos. La documentación no es muy útil, y hay algunas inconsistencias con respecto a los enteros firmados/sin firmar y el tamaño de los valores (8, 16, 24, 32 bits).
TagType en TApeTag.GetUnusedTextTags fue ttVorbis , correcto es ttApev2 .
Getter y Setter para TApeTag.EAN usó diferentes teclas.
Se corrigió el desorden con tipo cardinal/entero para Number Serial en OGGPages.
Archivos FLAC: Función desordenada FISVALID
Se corrigió un error de análisis con respecto a OGGPages y OGGpackets (que en realidad no tuvieron ningún efecto en los archivos OGG/OPUS, sino en el nuevo método ReadPackets).
La biblioteca Audiowerkzeugibibliothek se originó en varias bibliotecas específicas de formato para MP3, Flag, OGG y otros. Debido a eso, había mucha carga del pasado contenida en el código. Algunos duplicados, no hay consistencia en el orden de los parámetros, el tipo o los nombres, y algunos otros inconvenientes.
Con la versión 3.0, trato de mejorar la consistencia general y la usabilidad de los métodos proporcionados. Sin embargo, no es posible hacer esto compatible hacia abajo.
Hay muchos, muchos cambios, y deberá hacer los cambios correspondientes en su código.
Consulte ChangeLog para algunos detalles.
Puede usar esta biblioteca en diferentes "niveles", pero no existe una diferenciación real entre estos niveles. Puede usar más o menos de las características de esta biblioteca. Dependiendo de lo que desee hacer, se recomienda saber más o menos sobre la estructura interna de los "archivos de audio".
TTagItem . Muchos de estos objetos contienen información de texto, pero las imágenes u otros datos binarios también son posibles.Vea los proyectos de demostración para ver ejemplos.
TBaseAudioFile (Unit Audiofiles.base.pas): una clase abstracta que declara algunas propiedades básicas como el título, el artista, el álbum, la duración y otros, que luego se implementan en las siguientes clases TxxxFile .TMP3File , TOggVorbisFile , TFlacFile , ... (unidades separadas): clases para varios filetipos, que implementan los métodos abstractos declarados en tbaseaudiofile, y pueden definir algunos métodos más. Si desea más información sobre un archivo, es posible que deba acceder explícitamente a las propiedades y métodos de estas clases derivadas. También hay algunas "clases intermedias" como TBaseApeFile o TBaseVorbisFile para varios tipos de archivos que contienen Tags APEV2 o comentarios de Vorbis.TAudioFileFactory (Unidad Audiofiles.Factory.pas): la clase de fábrica para crear las instancias de archivo de audio correctas basadas en la extensión del archivo.TTagItem (Unidad Audiofiles.Basetags.pas): La clase base abstracta para todos los elementos individuales en un contenedor de metadatos. Esencialmente, se proporcionan una "clave" y un "valor", complementado con algunos otros datos sobre el elemento de datos. Se derivan de esto las clases TID3v2Frame , TApeTagItem , TCommentVector y algunos otros.TID3v1Tag , TID3V2Tag , TApeTag , TVorbisComments ... (Unidades separadas, sin antepasado común): Implementación de los contenedores de metadatos individuales. Extremadamente simplificado: una lista de ttagitems. Para los principiantes, el uso de esta biblioteca es súper fácil. Simplemente use la fábrica para crear un objeto de tipo TBaseAudioFile para mostrar algunas de las propiedades, permita que el usuario edite algunos de los valores y actualice el archivo. Eso es todo. Funciona en todos los formatos de archivo compatibles: MP3, OGG, FLAC, M4A, no importa. Mismo código para todos.
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; Tenga en cuenta que no necesita crear (o liberarse) el AudioFileFactory-Object. Esto es manejado por la unidad AudioFiles.Factory.pas automáticamente.
Vea la demostración "Demosimple" para más detalles.
Nota importante: la fábrica probablemente no sea segura de hilo. Si desea usarlo en un hilo secundario, debe crear otra fábrica dentro del contexto del hilo.
Si las propiedades nombradas proporcionadas (como el artista, el título y otros) no son suficientes, existe el método Audiofile.getTaglist (nuevo en la versión 3 de esta biblioteca). Esto le permite enumerar y editar todos los elementos de datos en un archivo.
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 ;Para editar un elemento en esta lista, puede usar el siguiente código:
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 ; Si bien la mayoría de los metadatos en los archivos de audio contienen texto, hay algunos datos que tienen una estructura más compleja o incluso contienen datos binarios puros. Cómo se puede reconocer el tipo de datos difiere del formato al formato. Los tipos posibles también son a veces cada vez más diferenciados. Y también hay algunas sutilezas a considerar con los "textos", especialmente con la etiqueta ID3V2. Allí, por ejemplo, "letras" contienen no solo el texto en sí, sino también algunos datos adicionales, por ejemplo, el idioma. Para este propósito, el Audio Werkzeuge Bibliothek proporciona los tipos de enumeración teTagContentType y teTextMode . TagContentType proporciona información sobre el tipo de contenido. Además de algunos tipos generalmente válidos ( tctText, tctPicture, tctBinary ), existen varios tipos específicos de formato, como tctLyrics o tctUserText para ID3V2, tctExternal para APEV2 o tctGenre para archivos M4A. Para algunos de estos tipos, es razonable considerarlos como texto, incluso si tienen una estructura interna diferente y deben tratarse por separado. El parámetro TextMode se puede establecer en tmReasonable para este propósito. Al leer los datos, tmForced también está disponible. Los datos binarios también se muestran en forma de texto (los caracteres no imprimibles se reemplazan con puntos ".").
El método AudioFile.GetTagList(TagItems); Tiene un parámetro opcional, donde puede definir qué tipo de etiquetas desea ser incluidas en la lista Tagitems.
procedure GetTagList(Dest: TTagItemList; ContentTypes: TTagContentTypes = cDefaultTagContentTypes);
El valor predeterminado devolverá todo tipo de etiquetas que se pueden interpretar como texto, es decir
cDefaultTagContentTypes = [tctText, tctComment, tctLyrics, tctURL, tctUserText, tctUserURL, tctExternal, tctTrackOrDiskNumber, tctGenre, tctSpecialText];
La mayoría del contenedor de metadatos permite más de una imagen, también conocido como "Arte de portada". Si desea mostrar la portada, primero debe obtener una lista de todos los elementos de etiqueta de imágenes.
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 ;Consulte la demostración "DemoExtended" para más detalles.
A nivel experto, ya no usa la clase básica TBaseAudioFile con tanta frecuencia. En cambio, trabaja directamente con las clases derivadas y los contenedores de metadatos específicos.
Como esto le brinda acceso muy básico a los archivos y su estructura interna, también puede hacer muchas tonterías con ellos, lo que puede generar problemas con otros programas. Ya sea porque no se adhiere al estándar documentado o porque rompa reglas no oficiales generalmente reconocidas. Es posible escribir una etiqueta ID3V2 en un archivo OGG, pero ciertamente no es una buena idea. Tampoco está escribiendo un comentario de Vorbis en un archivo MP3.
Use las opciones proporcionadas con precaución, especialmente con el acceso a la escritura.
Consulte la demostración "Demomp3" para obtener más detalles de lo que es posible (pero no siempre recomendado, algunos jugadores pueden tropezar con estos archivos en ese momento).
Varios formatos de audio pueden contener diferentes tipos de meta datos dentro del archivo. Esta biblioteca usa los siguientes supuestos
Los archivos MP3 generalmente contienen etiquetas ID3V1 e ID3V2. Al usar la clase TMP3File , generalmente se asegura que ambas versiones se mantengan consistentes en el archivo.
Los archivos MP3 a veces también contienen una etiqueta APEV2. Esta etiqueta ahora también está completamente procesada por la clase TMP3File . Configuración de propiedades básicas asegurará que todas las metaetiquetas permanezcan consistentes. Asegúrese de que la propiedad TagsToBeWritten contenga mt_Existing (que es el valor predeterminado).
No hay una clave estándar definida para "letras" en comentarios de Vorbis y etiquetas APEV2. Según mi investigación, las siguientes variantes están en uso: UNSYNCEDLYRICS , UNSYNCED LYRICS (con espacio) y LYRICS . Estas tres claves se tienen en cuenta al leer 'letras'. Al escribir, se usa la clave existente. Si ninguna de las tres variantes está disponible, se utiliza la clave establecida en la variable global AWB_DefaultLyricsKey . El valor predeterminado es UNSYNCEDLYRICS .
Todos los formatos de audio utilizando Tags APEV2 por defecto (Monkey, Wavpack, MusePack, Optimfrog, Trueudio) también pueden contener etiquetas ID3V1 e ID3V2. Las clases TxxxFile para esos formatos ahora procesan completamente el ID3V1-TAG. Se detecta la existencia de una etiqueta ID3V2 (y su tamaño se considera para el cálculo de la duración, si es necesario), pero de lo contrario se ignora.
Para archivos MP3 y archivos basados en APE, puede usar Propiedades TagsToBeWritten , TagsToBeDeleted y DefaultTags para decidir qué metaets se escriben/eliminan en/desde el archivo cuando se usa el método UpdateFile o RemoveFromFile . La configuración predeterminada es
// 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 está escaneando múltiples archivos para meta datos (por ejemplo, para almacenar los datos en una biblioteca de medios), es posible que desee solo el "título", pero no le importa si proviene de ID3V2 o ID3V1-TAG. Para acelerar el escaneo (al menos esta es la esperanza), se introduce la propiedad TagScanMode . Los valores posibles son
TTagScanMode = (id3_read_complete, id3_read_smart, id3_read_v2_only ); El valor predeterminado es id3_read_complete , donde se procesan todas las etiquetas contenidas. La opción id3_read_smart verificará la etiqueta ID3V2 primero. Esta metaetiqueta es más compleja, pero debe leerse de todos modos para llegar a los meta datos de audio como tasa de bits, duración y otras cosas. En el modo inteligente, la etiqueta ID3V1 solo se lee del archivo, si no hay una etiqueta ID3V2 adecuada que contenga artista, título, álbum, pista, año y género. Si también desea que se incluya el campo "Comentario", establezca fSmartRead_IgnoreComment en False .
Si cambia una de estas propiedades a través de los establecedores de la clase TMP3File , la propiedad fSmartRead_AvoidInconsistentData (predeterminada: True ) asegurará que también se procese correctamente el ID3V1-TAG, para que UpdateFile escriba tanto ID3V1- e ID3V2-TAG con datos consistentes (según la configuración de TagWriteMode ).
Nota: Para archivos basados en APE esto no es necesario. La detección de Tags APE siempre requiere verificación (y lectura) Tags ID3V1 también, por lo que no hay una aceleración significativa posible.
Por lo general, los archivos MP3 codificados con tasa de bits variable contienen un llamado encabezado XING (o algo similar) que contiene datos adicionales necesarios para un cálculo rápido de la duración del archivo. Recientemente encontré algunos archivos sin un encabezado de XING, lo que resultó en duraciones calculadas mucho más largas y tasas de bits demasiado bajas (es decir, 32 kbit/s). Este no fue un problema solo para esta biblioteca, pero aún así es para muchas otras bibliotecas.
Para tales archivos, se introduce la nueva propiedad TMP3File.MpegScanMode . Los valores posibles son
TMpegScanMode = (MPEG_SCAN_Fast, MPEG_SCAN_Smart, MPEG_SCAN_Complete);MPEG_SCAN_Fast escanea el archivo al igual que antes, de buena fe, que un archivo VBR contiene un encabezado XING (o algo equivalente). Esto funciona muy bien en la mayoría de los casos.MPEG_SCAN_Smart verifica si el resultado del escaneo rápido tiene sentido. Si la tasa de bits calculada es de 32 kbit/s (o incluso más baja, lo que en realidad sería inválido), entonces probablemente haya algo mal. Por lo tanto, el archivo se procesa por completo, escaneando todos y cada uno de los framos de MPEG. Tenga en cuenta que la mayoría de los archivos MP3 comienzan con un pequeño momento de silencio. Un codificador establecido en "VBR" probablemente usará la cantidad mínima posible de espacio para codificar esto, que es de 32 kbit/s.MPEG_SCAN_Complete siempre sin el archivo completo. Esto lleva a las duraciones más precisas, pero también requiere mucho más tiempo. El modo predeterminado es MPEG_SCAN_Smart .
Esta biblioteca debería funcionar con todas las versiones de Delphi de Delphi 7 a Delphi 12 . Sin embargo, hay algunas cosas a tener en cuenta con versiones más antiguas sin soporte de Unicode incorporado (= antes de Delphi 2009).
Nota : Uso "Unicode" aquí en el sentido de "más que ANSI". Eso no es 100% preciso, pero espero que sepas lo que estoy diciendo. ;-)
Antes de Delphi 2009, el VCL era solo ANSI y no admitía Unicode. Esto incluye la visualización de cadenas con caracteres Unicode y de apertura de archivos con caracteres Unicode en sus nombres de archivo. Para eso, ha habido una colección de componentes llamados "tntunicodecontrols". Las versiones más antiguas de esta colección estaban disponibles bajo una licencia Creative Commons, y aún deben encontrarse en algún lugar.
Esta biblioteca puede utilizar estos controles activando un conmutador de compilador en el archivo config.inc . Simplemente elimine el "." En la línea {.$DEFINE USE_TNT_COMPOS} .
Dentro de la biblioteca en sí, los TNT se usan para la clase TNTFileStream . Por supuesto, también puede usar otras clases de FileStream capaces de Unicode. Simplemente ajuste estas líneas de código de acuerdo con sus necesidades: (Archivo: Audiofiles.Declarations.pas)
{ $IFDEF USE_TNT_COMPOS }
TAudioFileStream = TTNTFileStream;
{ $ELSE }
TAudioFileStream = TFileStream;
{ $ENDIF }Si está utilizando una versión de Delphi más antigua sin tntunicodeControls, esta biblioteca seguirá funcionando, pero no puede abrir archivos con nombres de archivo como "จักรพรรณ์ อาบครบุรี - 10 เท่านี้ก็ตรม. Mp3". Cuando intenta mostrar información sobre el título y el artista de dicho archivo (después de cambiar el nombre), verá solo algunos "????" en lugar del título real. Tenga en cuenta que reescribir las metaetiquetas en tales condiciones podría conducir a la pérdida de datos.
NOTA : Los proyectos de muestra no usan los tntcontrols (como ttntedit en lugar de tedit). Tenga cuidado allí con Delphis mayor. ;-)
Las versiones más nuevas de Delphi (2009 y posterior) tienen soporte de unicode incorporado y, por lo tanto, no se necesita el uso de estos tntunicodecontrols. Además, no se necesita la definición del tipo UnicodeString . Esta es la razón de este interruptor del compilador:
{$IFNDEF UNICODE}
UnicodeString = WideString;
{$ENDIF}
En la versión 2.0 de esta biblioteca, uso un patrón de fábrica para los diferentes tipos de audiofiles. Una clase para un formato de archivo de audio específico se registra en la clase de fábrica. Para administrar todas las clases registradas, la clase de fábrica utiliza un TDICCIONARIO por defecto. Si su versión de Delphi no es compatible con TDictionary, invade su uso en confic.inc . En ese caso, se utilizará una tobjectList regular para eso.
{$DEFINE USE_DICTIONARY}
Para aumentar la velocidad de acceso en TobjectList, se implementa como una lista de autoorganización, utilizando el "método de transposición". Si se crea un archivo de audio con una extensión de nombre de archivo específica a través de la fábrica, esta extensión/clase se moverá hacia arriba en la lista, reduciendo el tiempo para encontrarla nuevamente.
Esta biblioteca debe leer correctamente la información de todo tipo de archivos de audio en la mayoría de los casos. Sin embargo, hay algunos archivos de audio impares "en la naturaleza", utilizando métodos o variantes que no manejan correctamente esta biblioteca. Creo que después de los años de Severals, estoy lidiando casi todo en este momento, pero todavía podría haber algunos casos raros que me falta.
Si encontró un error, o si tiene algunos archivos de audio (¡especialmente los archivos MP3!), Cuando los métodos de esta biblioteca proporcionan datos incorrectos, comuníquese conmigo y/o envíe algunos archivos de muestra a [email protected].
Pero no puedo (y no) arreglar todo. Lo más loco que he visto fue un ID3V2TAG con la siguiente codificación: UTF-16 (bien), terminado nulo (más o menos estándar), comenzando con un BOM (OK ...), Carácter por Caracter (WTF ...?)-Sí, no es broma. Un total de 6 bytes por personaje ...