Управлять тегом UserDefined (кадр TXXX) с помощью Taglib-Sharp
Ситуация и задача
У меня есть большая музыкальная коллекция, и я хочу очистить их ID3V2-теги с помощью PowerShell и taglip-sharp. Некоторые теги, такие как comment
или же encoding
должны быть удалены в то время как другие, как artist
или же title
не следует.
Обычно вы управляете тегами ID3 таким образом (упрощенная версия)
# Add taglib dll
[Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\taglib-sharp.dll")
# Load example mp3 into memory as [taglib.file]
$media = [TagLib.File]::Create("C:\path\to\musicFile.mp3")
# Change comment tag
$media.tag.tags[0].Comment = "Hello World"
# Save tags back to mp3 file
$Media.Save()
проблема
Многие музыкальные файлы хранят пользовательскую информацию, такую как URL
или же Shop Name
в рамке под названиемTXXX
, К сожалению, этот кадр не доступен с помощью метода, показанного выше. Или я еще не нашел способ.
Вместо этого вы используете
# Read UserTextInformationFrame
$media.GetTag([TagLib.TagTypes]::Id3v2).GetFrames("TXXX")
Этот пользовательский текстовый информационный фрейм может содержать несколько значений. А некоторые полезны, так как музыкальные плееры, такие как магазин Foobar PERFORMER
, DATE
или же replay_track_gain
теги в TXXX
,
Пример вывода для строки выше может быть:
Description : replaygain_track_gain
Text : {-5.00 dB}
FieldList : {-5.00 dB}
TextEncoding : Latin1
FrameId : {84, 88, 88, 88}
Size : 32
Flags : None
GroupId : -1
EncryptionId : -1
Description : URL
Text : {www.amazon.com}
FieldList : {www.amazon.com}
TextEncoding : UTF16
FrameId : {84, 88, 88, 88}
Size : 43
Flags : None
GroupId : -1
EncryptionId : -1
После этого я смог отфильтровать все ненужные значения TXXX
# Create a whitelist of TXXX frames
$goodTXXX = 'performer','replaygain_track_gain','date'
# Read UserTextInformationFrame AND filter it
$newTXXX = $Media.GetTag([TagLib.TagTypes]::Id3v2).GetFrames("TXXX") |
where { $goodTXXX -contains $_.Description }
Вопрос: Как записать несколько значений в TXXX
Рамка
Итак, мой вопрос, как мне сохранить мои отфильтрованные результаты обратно в mp3 файл?
Мои неудачные попытки были:
$media.GetTag([TagLib.TagTypes]::Id3v2).RemoveFrames("TXXX")
$media.GetTag([TagLib.TagTypes]::Id3v2).SetTextFrame("TXXX",$newTXXX)
# Removes old values, but does not show anything in Foobar
#$media.GetTag([TagLib.TagTypes]::Id3v2).GetFrames("TXXX").SetText("Hello World")
# Shows garbage in Foobar. And it's not usable for multiple values
Документация Taglib-Sharp для SetTextFrame
Дополнительный вопрос: способен ли taglib-sharp выделять теги Id3v1 и ID3v2.4 при сохранении новых тегов как тегов ID3v2.3? ( Связанный ответ SO, но не различает v2.3 и v2.4)
1 ответ
Я нашел способ с Try & Error. Это не элегантно, так как вы должны удалить все значения TXXX и добавить их обратно, если вы просто хотите изменить одно
# Add taglib dll
[Void][System.Reflection.Assembly]::LoadFrom("$PSScriptRoot\taglib-sharp.dll")
# Load example mp3 into memory as [taglib.file]
$media = [TagLib.File]::Create("C:\path\to\musicFile.mp3")
# Get or create the ID3v2 tag.
[TagLib.Id3v2.Tag]$id3v2tag = $media.GetTag([TagLib.TagTypes]::Id3v2, 1)
# Create new 'TXXX frame' object
$TXXXFrame = [TagLib.Id3v2.UserTextInformationFrame]("WWW")
# Delete complete TXXX frame first, or else all values are just appended
$id3v2tag.RemoveFrames("TXXX")
# Set the value/text in the newly created TXXX frame, default Text encoding is UTF8
# Use curly brackets instead of single quotation marks
$TXXXFrame.Text = {www.myurl.com}
# Add TXXX frame to tag
$id3v2tag.AddFrame($TXXXFrame)
# Write all changed tags back to file
$media.Save()