Управлять тегом 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()
Другие вопросы по тегам