Perpustakaan Delphi untuk file audio.
Baca dan tulis tag meta (seperti artis, judul, album, genre, ...) dari berbagai format audio, dan kumpulkan informasi tentang file audio (seperti durasi, bitrate, samplerate). AudiowerKzeugebibliothek hadir dengan penggunaan yang sangat sederhana untuk informasi dasar, tetapi juga berisi fitur-fitur kuat untuk akses mendalam ke hampir semua jenis data meta.
Format tag yang didukung ( BOLD: baru di v3.0 ):
Keterbatasan:
Properti TTagItem.DataSize .
Menambahkan frame url dan komentar ke TID3v2Tag.GetUnusedTextTags .
Metode TOggContainer.ReadPackets(Target: TObjectList) untuk mendapatkan semua paket dari oggstream.
Properti TOpusFile.VBR (yang seharusnya True di hampir setiap kasus) *
Metode untuk membaca/menulis atom integer dalam file M4A. Catatan: Gunakan dengan hati -hati. Saya membutuhkan ini di proyek utama saya "NEMP" untuk atom "TMPO" (alias BPM, ketukan per menit), tetapi ini tidak diuji secara luas untuk atom lainnya. Dokumentasi di sana tidak terlalu membantu, dan ada beberapa ketidakkonsistenan mengenai bilangan bulat yang ditandatangani/tidak ditandatangani dan ukuran nilai (8, 16, 24, 32 bit).
TagType di TApeTag.GetUnusedTextTags adalah ttVorbis , benar adalah ttApev2 .
Getter and Setter untuk TApeTag.EAN menggunakan kunci yang berbeda.
Memperbaiki kekacauan dengan jenis kardinal/integer untuk serialNumber di oggpages.
File FLAC: Fungsi yang sudah dihapus fisvalid
Memperbaiki kesalahan parsing tentang oggpages dan oggpackets (yang sebenarnya tidak berpengaruh pada file ogg/opus, tetapi pada metode baru readpackets).
Perpustakaan AudiowerKzeugebibibliothek berasal dari beberapa pustaka khusus format untuk MP3, Flag, Ogg dan lainnya. Karena itu, ada banyak beban masa lalu yang terkandung dalam Kode. Beberapa duplikat, tidak ada konsistensi dalam urutan parameter, jenis atau penamaan, dan beberapa ketidaknyamanan lainnya.
Dengan versi 3.0, saya mencoba meningkatkan konsistensi dan kegunaan keseluruhan metode yang disediakan. Namun, tidak mungkin untuk melakukan ini kompatibel ke bawah.
Ada banyak, banyak perubahan, dan Anda harus membuat perubahan yang sesuai dalam kode Anda.
Lihat Changelog untuk beberapa detail.
Anda dapat menggunakan pustaka ini pada "level" yang berbeda, tetapi tidak ada diferensiasi nyata antara level ini. Anda bisa menggunakan lebih atau kurang dari fitur perpustakaan ini. Bergantung pada apa yang ingin Anda lakukan, disarankan untuk mengetahui lebih atau kurang tentang struktur bagian dalam "file audio".
TTagItem . Banyak dari objek ini berisi informasi teks, tetapi gambar atau data biner lainnya juga dimungkinkan.Lihat proyek demo untuk contoh.
TBaseAudioFile (unit audiofiles.base.pas): Kelas abstrak yang menyatakan beberapa properti dasar seperti judul, artis, album, durasi dan beberapa lainnya, yang kemudian diimplementasikan di kelas TxxxFile berikut.TMP3File , TOggVorbisFile , TFlacFile , ... (unit terpisah): Kelas untuk beberapa tipe filet, yang mengimplementasikan metode abstrak yang dinyatakan dalam tbaseaudiofile, dan dapat mendefinisikan beberapa metode lagi. Jika Anda ingin informasi lebih lanjut tentang file, Anda mungkin perlu mengakses properti dan metode kelas yang diturunkan secara eksplisit. Ada juga beberapa "kelas menengah" seperti TBaseApeFile atau TBaseVorbisFile untuk beberapa jenis file yang berisi tag apev2 atau komentar vorbis.TAudioFileFactory (unit audiofiles.factory.pas): kelas pabrik untuk membuat instance file audio yang benar berdasarkan ekstensi file.TTagItem (unit audiofiles.basetags.pas): Kelas dasar abstrak untuk semua elemen individu dalam wadah metadata. Pada dasarnya, "kunci" dan "nilai" disediakan, ditambah dengan beberapa informasi lain tentang elemen data. Berasal dari ini adalah kelas TID3v2Frame , TApeTagItem , TCommentVector dan beberapa lainnya.TID3v1Tag , TID3V2Tag , TApeTag , TVorbisComments ... (unit terpisah, tidak ada leluhur yang sama): Implementasi dari masing -masing wadah metadata. Sangat disederhanakan: daftar ttagitems. Untuk pemula, penggunaan perpustakaan ini sangat mudah. Cukup gunakan pabrik untuk membuat objek tipe TBaseAudioFile untuk menampilkan beberapa properti, biarkan pengguna mengedit beberapa nilai dan memperbarui file. Itu saja. Bekerja pada semua format file yang didukung - mp3, ogg, flac, m4a, tidak masalah. Kode yang sama untuk semua.
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; Perhatikan bahwa Anda tidak perlu membuat (atau membebaskan) objek audiofilefactory-objek. Ini ditangani oleh unit AudioFiles.Factory.pas secara otomatis.
Lihat demo "demosimple" untuk detailnya.
Catatan penting: Pabrik mungkin tidak aman. Jika Anda ingin menggunakannya di utas sekunder, Anda harus membuat pabrik lain dalam konteks utas.
Jika properti yang disebutkan yang disediakan (seperti artis, judul, dan lainnya) tidak cukup, ada metode audiofile.gettaglist (baru dalam versi 3 perpustakaan ini). Ini memungkinkan Anda untuk mendaftar dan mengedit semua elemen data dalam file.
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 ;Untuk mengedit elemen dari daftar ini, Anda dapat menggunakan kode berikut:
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 ; Sementara sebagian besar metadata dalam file audio berisi teks, ada beberapa data yang memiliki struktur yang lebih kompleks atau bahkan berisi data biner murni. Bagaimana jenis data dapat dikenali berbeda dari format ke format. Jenis yang mungkin juga terkadang lebih dan terkadang kurang berbeda. Dan ada juga beberapa seluk -beluk yang perlu dipertimbangkan dengan "teks", terutama dengan tag ID3V2. Di sana, misalnya, "lirik" tidak hanya mengandung teks itu sendiri, tetapi juga beberapa data tambahan - misalnya bahasa. Untuk tujuan ini, Audio Werkzeuge Bibliothek memberikan tipe enumerasi teTagContentType dan teTextMode . TagContentType memberikan informasi tentang jenis konten. Selain beberapa tipe yang umumnya valid ( tctText, tctPicture, tctBinary ), ada berbagai jenis format-spesifik seperti tctLyrics atau tctUserText untuk ID3V2, tctExternal untuk APEV2 atau tctGenre untuk file M4A. Untuk beberapa jenis ini, masuk akal untuk menganggapnya sebagai teks, bahkan jika mereka memiliki struktur internal yang berbeda dan harus diperlakukan secara terpisah. Parameter TextMode dapat diatur ke tmReasonable untuk tujuan ini. Saat membaca data, tmForced juga tersedia. Data biner kemudian juga ditampilkan dalam bentuk teks (karakter yang tidak dapat dicetak diganti dengan titik-titik ".").
Metode AudioFile.GetTagList(TagItems); Memiliki parameter opsional, di mana Anda dapat menentukan jenis tag apa yang ingin Anda sertakan dalam daftar TagItems.
procedure GetTagList(Dest: TTagItemList; ContentTypes: TTagContentTypes = cDefaultTagContentTypes);
Nilai default akan mengembalikan semua jenis tag yang dapat diartikan sebagai teks, yaitu
cDefaultTagContentTypes = [tctText, tctComment, tctLyrics, tctURL, tctUserText, tctUserURL, tctExternal, tctTrackOrDiskNumber, tctGenre, tctSpecialText];
Sebagian besar wadah metadata memungkinkan lebih dari satu gambar, alias "sampul seni". Jika Anda ingin menampilkan sampul seni, Anda harus mendapatkan daftar semua item tag gambar terlebih dahulu.
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 ;Lihat Demo "Demoextended" untuk detailnya.
Di tingkat ahli, Anda tidak lagi menggunakan kelas dasar TBaseAudioFile itu sering. Sebaliknya, Anda bekerja secara langsung dengan kelas yang diturunkan dan wadah metadata spesifik.
Karena ini memberi Anda akses yang sangat mendasar ke file dan struktur internal mereka, Anda juga dapat melakukan banyak omong kosong dengan mereka, yang dapat menyebabkan masalah dengan program lain. Baik itu karena Anda tidak mematuhi standar yang terdokumentasi atau karena Anda melanggar aturan tidak resmi yang diakui secara umum. Menulis tag ID3V2 dalam file OGG adalah mungkin, tetapi tentu saja bukan ide yang bagus. Tidak ada yang menulis komentar Vorbis ke file MP3.
Gunakan opsi yang diberikan dengan hati -hati - terutama dengan akses tulis.
Lihat demo "demomp3" untuk detail lebih lanjut tentang apa yang mungkin (tetapi tidak selalu direkomendasikan, beberapa pemain mungkin tersandung tentang file -file ini).
Beberapa format audio dapat berisi berbagai jenis data meta dalam file. Perpustakaan ini menggunakan asumsi berikut
File MP3 biasanya berisi tag ID3V1 dan ID3V2. Saat menggunakan kelas TMP3File , biasanya dipastikan bahwa kedua versi tetap konsisten dalam file.
File MP3 terkadang juga berisi APEV2-tag. Tag ini sekarang juga sepenuhnya diproses oleh kelas TMP3File . Mengatur Properti Dasar akan memastikan bahwa semua tag meta tetap konsisten. Pastikan bahwa TagsToBeWritten properti berisi mt_Existing (yang merupakan nilai default).
Tidak ada kunci standar yang ditentukan untuk "lirik" dalam komentar Vorbis dan tag APEV2. Menurut penelitian saya, varian berikut sedang digunakan: UNSYNCEDLYRICS , UNSYNCED LYRICS (dengan ruang) dan LYRICS . Tiga kunci ini diperhitungkan saat membaca 'lirik'. Saat menulis, kunci yang ada digunakan. Jika tidak satu pun dari tiga varian yang tersedia, set kunci dalam variabel global AWB_DefaultLyricsKey digunakan. Nilai defaultnya UNSYNCEDLYRICS .
Semua format audio menggunakan APEV2-tag secara default (monyet, wavpack, musePack, optimfrog, trueAudio) juga dapat mengandung tag ID3V1- dan id3v2. Kelas TxxxFile untuk format tersebut sekarang sepenuhnya memproses ID3V1-TAG. Keberadaan tag ID3V2 terdeteksi (dan ukurannya dipertimbangkan untuk perhitungan durasi, jika diperlukan), tetapi diabaikan.
Untuk file MP3 dan file berbasis APE, Anda dapat menggunakan Properties TagsToBeWritten , TagsToBeDeleted dan DefaultTags untuk memutuskan tag meta mana yang ditulis/dihapus ke/dari file saat menggunakan Metode UpdateFile atau RemoveFromFile . Pengaturan default adalah
// 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 Jika Anda memindai beberapa file untuk data meta (misalnya untuk menyimpan data ke perpustakaan media), Anda mungkin hanya ingin "judul", tetapi Anda tidak peduli apakah itu berasal dari ID3V2- atau ID3V1-TAG. Untuk mempercepat pemindaian (setidaknya ini adalah harapan), TagScanMode properti diperkenalkan. Nilai yang mungkin adalah
TTagScanMode = (id3_read_complete, id3_read_smart, id3_read_v2_only ); Nilai default adalah id3_read_complete , di mana semua tag yang terkandung diproses. Opsi id3_read_smart akan memeriksa ID3V2-TAG terlebih dahulu. Tag meta ini lebih kompleks, tetapi tetap perlu dibaca untuk sampai ke data meta audio seperti bitrate, durasi, dan hal -hal lainnya. Dalam Mode Cerdas, ID3V1-TAG hanya dibaca dari file, jika tidak ada ID3V2-tag yang berisi artis, judul, album, Track, Year and Genre. Jika Anda juga ingin bidang "komentar" disertakan, atur fSmartRead_IgnoreComment ke False .
Jika Anda mengubah salah satu properti ini melalui setters dari kelas TMP3File , properti fSmartRead_AvoidInconsistentData (default: True ) akan memastikan bahwa juga ID3V1-TAG diproses dengan benar, sehingga UpdateFile akan menulis kedua ID3V1- dan ID3V2-TAG dengan data yang konsisten (menurut pengaturan TagWriteMode ).
Catatan: Untuk file berbasis APE ini tidak diperlukan. Mendeteksi tag kera selalu memerlukan pemeriksaan (dan membaca) tag ID3V1 juga, jadi tidak ada percepatan yang signifikan.
Biasanya, file MP3 yang dikodekan dengan bitrate variabel berisi apa yang disebut xing-header (atau sesuatu yang serupa) yang berisi data tambahan yang diperlukan untuk perhitungan cepat durasi file. Baru-baru ini saya menemukan beberapa file tanpa header xing seperti itu, menghasilkan durasi yang lebih lama dihitung, dan bitrate terlalu rendah (yaitu 32 kbit/s). Ini bukan masalah hanya untuk perpustakaan ini, tetapi masih untuk banyak perpustakaan lainnya.
Untuk file tersebut, properti baru TMP3File.MpegScanMode diperkenalkan. Nilai yang mungkin adalah
TMpegScanMode = (MPEG_SCAN_Fast, MPEG_SCAN_Smart, MPEG_SCAN_Complete);MPEG_SCAN_Fast memindai file seperti sebelumnya, dengan itikad baik bahwa file VBR berisi xing-header (atau sesuatu yang setara). Ini bekerja dengan sangat baik dalam banyak kasus.MPEG_SCAN_Smart memeriksa, apakah hasil dari pemindaian cepat masuk akal. Jika bitrat yang dihitung adalah 32 kbit/s (atau bahkan lebih rendah, yang sebenarnya tidak valid), maka mungkin ada sesuatu yang salah. Oleh karena itu, file sepenuhnya diproses, memindai masing-masing dan setiap mpeg-frame. Perhatikan bahwa sebagian besar file MP3 dimulai dengan sedikit keheningan. Set encoder ke "VBR" kemungkinan akan menggunakan jumlah ruang minimum yang mungkin untuk menyandikan ini - yaitu 32kbit/s.MPEG_SCAN_Complete selalu tanpa file lengkap. Ini mengarah pada durasi yang paling akurat, tetapi juga membutuhkan lebih banyak waktu. Mode default adalah MPEG_SCAN_Smart .
Perpustakaan ini harus bekerja dengan semua versi Delphi dari Delphi 7 ke Delphi 12 . Namun, ada beberapa hal yang perlu diingat dengan versi yang lebih lama tanpa dukungan unicode bawaan (= sebelum Delphi 2009).
Catatan : Saya menggunakan "unicode" di sini dalam arti "lebih dari ANSI". Itu tidak 100% akurat, tapi saya harap Anda tahu apa yang saya katakan. ;-)
Sebelum Delphi 2009, VCL itu hanya dan tidak mendukung Unicode. Ini termasuk tampilan string dengan karakter unicode dan membuka file dengan karakter unicode dalam nama file mereka. Untuk itu, telah ada kumpulan komponen yang disebut "tntunicodecontrols". Versi yang lebih lama dari koleksi ini tersedia di bawah lisensi Creative Commons, dan masih harus ditemukan di suatu tempat.
Perpustakaan ini dapat menggunakan kontrol ini dengan mengaktifkan sakelar kompiler di file config.inc . Lepaskan saja "." Di baris {.$DEFINE USE_TNT_COMPOS} .
Di dalam perpustakaan itu sendiri, TNT digunakan untuk kelas TNTFileStream . Tentu saja Anda dapat menggunakan kelas filestream unicode yang berkemampuan lain juga. Cukup sesuaikan baris kode ini sesuai dengan kebutuhan Anda: (file: audiofiles.declarations.pas)
{ $IFDEF USE_TNT_COMPOS }
TAudioFileStream = TTNTFileStream;
{ $ELSE }
TAudioFileStream = TFileStream;
{ $ENDIF }Jika Anda menggunakan versi Delphi yang lebih lama tanpa Tntunicodecontrols, perpustakaan ini masih akan berfungsi, tetapi Anda tidak dapat membuka file dengan nama file seperti "จักรพรรณ์ อาบครบุรี - 10 เท่านี้ก็ตรม. MP3". Ketika Anda mencoba menampilkan informasi tentang judul dan artis dari file seperti itu (setelah mengganti nama), Anda hanya akan melihat beberapa "?????" bukannya judul yang sebenarnya. Perhatikan bahwa menulis ulang tag meta dalam kondisi seperti itu dapat menyebabkan kehilangan data.
Catatan : Proyek sampel tidak menggunakan TNTControls (seperti TTNTEDIT, bukan tedit). Hati -hati di sana dengan Delphis yang lebih tua. ;-)
Versi Delphi yang lebih baru (2009 dan kemudian) memiliki dukungan unicode bawaan, dan oleh karena itu penggunaan tntunicodecontrol ini tidak diperlukan. Selain itu, definisi jenis UnicodeString tidak diperlukan di sana. Inilah alasan sakelar kompiler ini:
{$IFNDEF UNICODE}
UnicodeString = WideString;
{$ENDIF}
Dalam versi 2.0 dari perpustakaan ini, saya menggunakan pola pabrik untuk berbagai jenis audiofil. Kelas untuk format file audio tertentu terdaftar di kelas pabrik. Untuk mengelola semua kelas yang terdaftar, kelas pabrik menggunakan tdiksi secara default. Jika versi Delphi Anda tidak mendukung tDictionary, lepaskan penggunaannya di confic.inc . Dalam hal ini, Daftar Tobjects biasa akan digunakan untuk itu.
{$DEFINE USE_DICTIONARY}
Untuk meningkatkan kecepatan akses di Daftar TobjectList, itu diimplementasikan sebagai daftar pengorganisasian sendiri, menggunakan "Metode Transpose". Jika file audio dengan ekstensi nama file tertentu dibuat melalui pabrik, ekstensi/kelas ini akan dipindahkan ke atas dalam daftar, mengurangi waktu untuk menemukannya lagi.
Perpustakaan ini harus membaca informasi dengan benar dari semua jenis file audio dalam banyak kasus. Namun, ada beberapa file audio aneh "di alam liar", menggunakan metode atau varian yang tidak ditangani dengan benar oleh perpustakaan ini. Saya pikir setelah bertahun -tahun saya mengatasi hampir semuanya sekarang, tetapi masih ada beberapa kasus langka yang saya lewatkan.
Jika Anda menemukan bug, atau jika Anda memiliki beberapa file audio (terutama file MP3!), Di mana metode perpustakaan ini memberikan data yang salah, silakan hubungi saya dan/atau kirim beberapa file sampel ke [email protected].
Tapi saya tidak bisa (dan tidak mau) memperbaiki semuanya. Hal paling gila yang pernah saya lihat adalah ID3V2Tag dengan pengkodean berikut: UTF-16 (baik), yang diakhiri nol (lebih atau kurang standar), dimulai dengan BOM (OK ...), karakter demi karakter (WTF ...?)-Ya, tidak ada bercanda. Total 6 byte per karakter ...