使用 Taglib-Sharp 操作 UserDefined 标签(TXXX 帧)
Manipulate UserDefined tag (TXXX frame) with Taglib-Sharp
形势任务
我有一个大音乐collection,我想清理他们ID3V2 tags with PowerShell and taglip-sharp。 comment
或 encoding
等标签应删除,而 artist
或 title
等其他标签则不应删除。
Usually you manipulate ID3 tags this way (Simplified version)
# 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()
问题
许多音乐文件在帧 called TXXX
中存储自定义信息,如 URL
或 Shop Name
。不幸的是,无法使用上面显示的方法访问此框架。或者我还没有找到办法
相反,您使用
# Read UserTextInformationFrame
$media.GetTag([TagLib.TagTypes]::Id3v2).GetFrames("TXXX")
这个User defined text information frame可以保存多个值。有些很有用,因为像 Foobar 这样的音乐播放器会在 TXXX
中存储 PERFORMER
、DATE
或 replay_track_gain
标签。
上面一行的示例输出可以是:
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 documentation for SetTextFrame
奖励问题: taglib-sharp 是否能够在将新标签保存为 ID3v2.3 标签的同时去除 Id3v1 和 ID3v2.4 标签? (Related SO answer, but doesn't distinguish between v2.3 and v2.4)
我找到了尝试错误的方法。这并不优雅,因为如果您只想更改一个值,则必须删除所有 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()
形势任务
我有一个大音乐collection,我想清理他们ID3V2 tags with PowerShell and taglip-sharp。 comment
或 encoding
等标签应删除,而 artist
或 title
等其他标签则不应删除。
Usually you manipulate ID3 tags this way (Simplified version)
# 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()
问题
许多音乐文件在帧 called TXXX
中存储自定义信息,如 URL
或 Shop Name
。不幸的是,无法使用上面显示的方法访问此框架。或者我还没有找到办法
相反,您使用
# Read UserTextInformationFrame
$media.GetTag([TagLib.TagTypes]::Id3v2).GetFrames("TXXX")
这个User defined text information frame可以保存多个值。有些很有用,因为像 Foobar 这样的音乐播放器会在 TXXX
中存储 PERFORMER
、DATE
或 replay_track_gain
标签。
上面一行的示例输出可以是:
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 documentation for SetTextFrame
奖励问题: taglib-sharp 是否能够在将新标签保存为 ID3v2.3 标签的同时去除 Id3v1 和 ID3v2.4 标签? (Related SO answer, but doesn't distinguish between v2.3 and v2.4)
我找到了尝试错误的方法。这并不优雅,因为如果您只想更改一个值,则必须删除所有 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()