Библиотека Delphi для аудиофайлов.
Читайте и напишите метатеги (например, артист, название, альбом, жанр, ...) из разных аудиоформатов, и собирайте информацию о аудиофайле (например, продолжительность, битрейт, Spemplere). Audiowerkzeugebibliothek поставляется с очень простым использованием для базовой информации, но также содержит мощные функции для углубленного доступа почти ко всем видам метаданных.
Поддерживаемые форматы тегов ( жирное жирный: новое в v3.0 ):
Ограничения:
Собственность TTagItem.DataSize .
Добавлены рамки URL и комментарий к TID3v2Tag.GetUnusedTextTags .
Метод TOggContainer.ReadPackets(Target: TObjectList) , чтобы получить все пакеты из OGGStream.
Свойство TOpusFile.VBR (что должно быть True почти во всех случаях) *
Методы для чтения/записи целочисленных атомов в файлах M4A. Примечание: используйте с осторожностью. Мне нужно это в моем основном проекте «NEMP» для атома «TMPO» (он же BPM, удары в минуту), но это не широко проверено для других атомов. Документация там не очень полезна, и существуют некоторые несоответствия в отношении целых чисел подписанного/не знаменитого и размера значений (8, 16, 24, 32 бит).
Tagtype в TApeTag.GetUnusedTextTags был ttVorbis , правильно - это ttApev2 .
Getter и Setter для TApeTag.EAN использовал разные клавиши.
Исправлена беспорядок с помощью кардинального/целочисленного типа для последовательного воздуха в oggpages.
Файлы FLAC: удаленная устаревшая функция Fisvalid
Исправлена ошибка анализа в отношении OGGPAGES и OGGPACKET (которые на самом деле не влияли на файлы OGG/OPUS, но на новый метод ReadPackets).
Библиотека Audiowerkzeugebibliothek возникла из нескольких специфичных для формата библиотек для MP3, флага, OGG и других. Из -за этого было много бремени прошлого, содержащегося в коде. Некоторые дубликаты, нет согласованности в порядке параметров, типа или именования, а также некоторые другие неудобства.
С версией 3.0 я стараюсь улучшить общую последовательность и удобство использования предоставленных методов. Однако невозможно сделать это вниз по совместимости.
Есть много, много изменений, и вам нужно будет внести соответствующие изменения в вашем коде.
См. Чанглог для некоторых деталей.
Вы можете использовать эту библиотеку на разных «уровнях», но между этими уровнями нет реальной дифференциации. Вы можете просто использовать более или менее из функций этой библиотеки. В зависимости от того, что вы хотите сделать, рекомендуется узнать больше о внутренней структуре «аудиофайлов».
TTagItem . Многие из этих объектов содержат текстовую информацию, но изображения или другие двоичные данные также возможны.Смотрите демонстрационные проекты для примеров.
TBaseAudioFile (Unit audiofiles.base.pas): абстрактный класс, который объявляет некоторые основные свойства, такие как название, артист, альбом, продолжительность и некоторые другие, которые затем реализованы в следующих классах TxxxFile .TMP3File , TOggVorbisFile , TFlacFile , ... (отдельные единицы): классы для нескольких филетипов, которые реализуют абстрактные методы, объявленные в Tbaseaudiofile, и могут определить некоторые другие методы. Если вам нужна дополнительная информация о файле, вам может потребоваться явно получить доступ к свойствам и методам этих полученных классов. Существуют также некоторые «промежуточные классы», такие как TBaseApeFile или TBaseVorbisFile для нескольких типов файлов, которые содержат комментарии APEV2-Tags или Vorbis.TAudioFileFactory (Unit audiofiles.factory.pas): класс завода для создания правильных экземпляров аудиофайл на основе расширения файла.TTagItem (Unit audiofiles.basetags.pas): абстрактный базовый класс для всех отдельных элементов в контейнере метаданных. По сути, предоставляются «ключ» и «значение», дополненные несколькими другими частями информации о элементе данных. Из этого получены классы TID3v2Frame , TApeTagItem , TCommentVector и некоторые другие.TID3v1Tag , TID3V2Tag , TApeTag , TVorbisComments ... (отдельные единицы, без общего предка): реализация отдельных контейнеров метаданных. Чрезвычайно упрощенный: список Ttagitems. Для начинающих использование этой библиотеки очень легко. Просто используйте завод, чтобы создать объект типа TBaseAudioFile , чтобы отобразить некоторые свойства, пусть пользователь редактирует некоторые значения и обновите файл. Вот и все. Работает во всех поддерживаемых форматах файлов - MP3, OGG, FLAC, M4A, это не имеет значения. Тот же код для всех.
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; Обратите внимание, что вам не нужно создавать (или бесплатно) AudioFileFactory-Object. Это обрабатывается устройством AudioFiles.Factory.pas автоматически.
Смотрите демонстрацию «Демосимпл» для деталей.
Важное примечание: завод, вероятно, не безопасен. Если вы хотите использовать его в вторичном потоке, вы должны создать другую фабрику в контексте потока.
Если указанные свойства (такие как артист, название и другие) недостаточно, существует метод audiofile.gettaglist (новая в версии 3 этой библиотеки). Это позволяет вам перечислять и редактировать все элементы данных в файле.
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 ;Чтобы отредактировать элемент из этого списка, вы можете использовать следующий код:
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 ; В то время как большинство метаданных в аудиофайлах содержит текст, есть некоторые данные, которые имеют более сложную структуру или даже содержат чистые двоичные данные. Как тип данных может быть распознан, отличается от формата к формату. Возможные типы также иногда более и иногда менее дифференцированы. И есть также некоторые тонкости, которые следует учитывать с «текстами», особенно с тегом ID3V2. Там, например, «тексты» содержат не только сам текст, но и некоторые дополнительные данные - например, язык. Для этой цели Audio Werkzeuge Bibliothek предоставляет типы перечисления teTagContentType и teTextMode . TagContentType предоставляет информацию о типе контента. В дополнение к нескольким обычно допустимым типам ( tctText, tctPicture, tctBinary ), существуют различные специфичные для формата типы, такие как tctLyrics или tctUserText для ID3V2, tctExternal для APEV2 или tctGenre для файлов M4A. Для некоторых из этих типов разумно рассматривать их как текст, даже если они имеют другую внутреннюю структуру и должны рассматриваться отдельно. Параметр TextMode может быть установлен в tmReasonable для этой цели. При чтении данных также доступен tmForced . Двоичные данные затем также отображаются в текстовой форме (не печатные символы заменяются точками ».).
Метод AudioFile.GetTagList(TagItems); Имеет дополнительный параметр, где вы можете определить, какие теги вы хотите включить в список Tagitems.
procedure GetTagList(Dest: TTagItemList; ContentTypes: TTagContentTypes = cDefaultTagContentTypes);
Значение по умолчанию возвращает все виды тегов, которые можно интерпретировать как текст, т.е.
cDefaultTagContentTypes = [tctText, tctComment, tctLyrics, tctURL, tctUserText, tctUserURL, tctExternal, tctTrackOrDiskNumber, tctGenre, tctSpecialText];
Большинство контейнеров метаданных позволяют более одной картины, также известной как «обложка». Если вы хотите отобразить обложку, вам нужно сначала получить список всех элементов тега изображения.
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 ;Смотрите демонстрацию «демоэкгалд» для деталей.
На экспертном уровне вы больше не используете базовый класс TBaseAudioFile , который часто. Вместо этого вы работаете напрямую с производными классами и конкретными контейнерами метаданных.
Поскольку это дает вам очень базовый доступ к файлам и их внутренней структуре, вы также можете сделать с ними много чепухи, что может привести к проблемам с другими программами. Будь то, потому что вы не придерживаетесь документированного стандарта или потому, что вы ломаете общепринятые неофициальные правила. Написание тега ID3V2 в файле OGG возможно, но, конечно, не очень хорошая идея. Ни один из них не пишет комментарий Vorbis в Mp3 -файл.
Используйте варианты, предоставляемые с осторожностью - особенно с доступом к записи.
См. Демо «Demomp3» для получения более подробной информации о том, что возможно (но не всегда рекомендуется, некоторые игроки могут наткнуться на эти файлы).
Несколько аудио форматов могут содержать различные виды метаданных в файле. Эта библиотека использует следующие предположения
MP3-файлы обычно содержат ID3V1 и ID3V2-Tags. При использовании класса TMP3File , обычно гарантируется, что обе версии остаются последовательными в файле.
Файлы MP3 иногда также содержат APEV2-Tag. Этот тег теперь также полностью обрабатывается классом TMP3File . Установка основных свойств гарантирует, что все метатеги остаются последовательными. Убедитесь, что свойство TagsToBeWritten содержит mt_Existing (что является значением по умолчанию).
В комментариях Vorbis нет стандартного ключа, определенного для «текстов» и тегов APEV2. Согласно моим исследованиям, используются следующие варианты: UNSYNCEDLYRICS , UNSYNCED LYRICS (с пространством) и LYRICS . Эти три ключа принимаются во внимание при чтении «текст». При написании используется существующий ключ. Если ни один из трех вариантов не доступен, используется ключ в глобальной переменной AWB_DefaultLyricsKey . Значение по умолчанию - UNSYNCEDLYRICS .
Все аудиоформаты, использующие APEV2-tags по умолчанию (Monkey, Wavpack, Musepack, Optimfrog, Trueaudio) также могут содержать ID3V1- и ID3V2-Tags. Классы TxxxFile для этих форматов теперь полностью обрабатывают ID3V1-TAG. Существование ID3V2-TAG обнаруживается (и его размер рассматривается для расчета продолжительности, если это необходимо), но в противном случае игнорируется.
Для MP3-файлов и файлов на основе APE вы можете использовать свойства TagsToBeWritten , TagsToBeDeleted и DefaultTags чтобы решить, какие метатеги записываются/удалены в/из файла при использовании файла Method UpdateFile или RemoveFromFile . Настройки по умолчанию
// 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 Если вы сканируете несколько файлов для метаданных (например, для хранения данных в медиа-библиотеке), вам может потребоваться только «заголовок», но вам все равно, происходит ли это от ID3V2- или ID3V1-Tag. Чтобы ускорить сканирование (по крайней мере, это надежда), вводится свойство TagScanMode . Возможные значения
TTagScanMode = (id3_read_complete, id3_read_smart, id3_read_v2_only ); Значение по умолчанию - id3_read_complete , где обрабатываются все содержащие теги. Опция id3_read_smart сначала проверит ID3V2-Tag. Этот метатец более сложный, но его нужно прочитать в любом случае, чтобы добраться до звуковых метадан, таких как битрейт, продолжительность и другие вещи. В Smart Mode ID3V1-Tag читается только из файла, если нет правильного ID3V2-TAG, содержащего артист, название, альбом, трек, год и жанр. Если вы также хотите включить поле «Комментарий», установите fSmartRead_IgnoreComment на False .
Если вы измените одно из этих свойств через сеттеры класса TMP3File , свойство fSmartRead_AvoidInconsistentData (по умолчанию: True ) гарантирует, что также обрабатывается ID3V1-tag, так что UpdateFile будет писать как iD3v1-, так и id3v2-tag с последовательными данными (в соответствии с настройкой TagWriteMode ).
Примечание. Для файлов на основе APE это не нужно. Обнаружение обезьяны всегда требует проверки (и чтения) ID3v1-tags, поэтому существенного ускорения не возможно.
Обычно mp3-файлы, кодируемые с переменной битрейтом, содержат так называемый заголовок XING (или что-то подобное), содержащее дополнительные данные, необходимые для быстрого расчета продолжительности файла. Недавно я нашел несколько файлов без такой заголовка XING, что привело к гораздо более длинным рассчитанным продолжительности и слишком низким битрейтом (т. Е. 32 кбит/с). Это не было проблемой только для этой библиотеки, но все еще для многих других библиотек.
Для таких файлов введено новое свойство TMP3File.MpegScanMode . Возможные значения
TMpegScanMode = (MPEG_SCAN_Fast, MPEG_SCAN_Smart, MPEG_SCAN_Complete);MPEG_SCAN_Fast сканирует файл так же, как и прежде, добросовестно, что файл VBR содержит заголовок XING (или что-то эквивалентное). В большинстве случаев это работает очень хорошо.MPEG_SCAN_Smart проверяет, имеет ли смысл результат быстрого сканирования. Если рассчитываемый битрейт составляет 32 кбит/с (или даже ниже, что на самом деле было бы недействительным), то, вероятно, что -то не так. Следовательно, файл полностью обрабатывается, сканируя каждый мапед-карт. Обратите внимание, что большинство файлов MP3 начинаются с небольшого момента молчания. Энкодер, установленный в «VBR», скорее всего, будет использовать минимально возможное количество пространства для кодирования этого, которое составляет 32 кбит/с.MPEG_SCAN_Complete всегда без полного файла. Это приводит к наиболее точной продолжительности, но также требует гораздо больше времени. Режим по умолчанию - MPEG_SCAN_Smart .
Эта библиотека должна работать со всеми версиями Delphi от Delphi 7 до Delphi 12 . Тем не менее, есть некоторые вещи, которые следует иметь в виду со старыми версиями без встроенной поддержки Unicode (= до Delphi 2009).
Примечание : я использую «Unicode» здесь в значении «больше, чем ANSI». Это не на 100% точно, но я надеюсь, что вы знаете, что я говорю. ;-)
До Delphi 2009 VCL был только ANSI и не поддерживал Unicode. Это включает в себя отображение строк с символами Unicode и открывающими файлами с символами Unicode в их именах файлов. Для этого была собрана коллекция компонентов, называемых «tntunicodecontrols». Старые версии этой коллекции были доступны по лицензии Creative Commons, и их все еще их можно найти.
Эта библиотека может использовать эти элементы управления, активируя компилятор в файле config.inc . Просто удалите "." В строке {.$DEFINE USE_TNT_COMPOS} .
В самой библиотеке TNT используются для класса TNTFileStream . Конечно, вы также можете использовать другие классы FileStream Unicode. Просто настройте эти строки кода в соответствии с вашими потребностями: (файл: audiofiles.declarations.pas)
{ $IFDEF USE_TNT_COMPOS }
TAudioFileStream = TTNTFileStream;
{ $ELSE }
TAudioFileStream = TFileStream;
{ $ENDIF }Если вы используете более старую версию Delphi без tntunicodecontrols, эта библиотека по -прежнему будет работать, но вы не можете открывать файлы с такими именами файлов, как «จักรพรรณ์ อาบครบุรี - 10 เท่านี้ก็ตรม. Mp3». Когда вы пытаетесь отобразить информацию о заголовке и артистах из такого файла (после его переименования), вы увидите только некоторые "????? вместо фактического названия. Обратите внимание, что переписывание метагов в таких условиях может привести к потере данных.
ПРИМЕЧАНИЕ . Образец проектов не использует TNTControls (например, ttntedit вместо TEDIT). Будьте осторожны со старым Delphis. ;-)
Новые версии Delphi (2009 и позже) имеют встроенную поддержку Unicode, и, следовательно, использование этих tntunicodecontrols не требуется. Кроме того, определение типа UnicodeString там не требуется. Это причина этого компилятора:
{$IFNDEF UNICODE}
UnicodeString = WideString;
{$ENDIF}
В версии 2.0 этой библиотеки я использую заводской шаблон для различных типов аудиофилей. Класс для конкретного формата аудиофайла зарегистрирован в классе завода. Для управления всеми зарегистрированными классами в классе Factory по умолчанию использует Tdictionary. Если ваша версия Delphi не поддерживает Tdictionary, упустите его использование в confic.inc . В этом случае для этого будет использоваться обычный Tobjectist.
{$DEFINE USE_DICTIONARY}
Чтобы увеличить скорость доступа в TobjectList, он реализован в качестве списка самоорганизации, используя «метод транспонирования». Если аудиофайл с определенным расширением файла создается через завод, это расширение/класс будет перемещен вверх в списке, сократив время, чтобы найти его снова.
Эта библиотека должна правильно прочитать информацию из всех видов аудиофайлов в большинстве случаев. Тем не менее, есть некоторые нечетные аудиофайлы «в дикой природе», использующие методы или варианты, не обработанные должным образом этой библиотекой. Я думаю, что после севераллов я сейчас справляюсь почти со всем, но я все еще не могу быть в некоторых редких случаях, которые мне не хватает.
Если вы нашли ошибку, или если у вас есть некоторые аудиофайлы (особенно файлы MP3!), Где методы этой библиотеки предоставляют неверные данные, пожалуйста, свяжитесь со мной и/или отправьте несколько образцов файлов по адресу [email protected].
Но я не могу (и не буду) все исправить. Самая сумасшедшая вещь, которую я когда-либо видел,-это ID3V2TAG со следующим кодированием: UTF-16 (нормально), нулевой (более или менее стандартный), начиная с рода (ОК ...), характер за характером (wtf ...?)-Да, без шутов. В общей сложности 6 байтов на персонажа ...