假想
我通常使用MP3Gain应用程序来设置mp3文件的重放增益。
应用程序可以在APEv2标记的mp3文件中创建以下字段:

(截图取自WinAmp播放器)
发问
使用TagLibSharp库,我编写了一个ID3v1和ID3v2解析器,现在,我想知道是否可以使用这个库读写所提到的APEv2字段?
研究
我认为MP3Gain应用程序为字段使用了唯一的名称,因此可能TagLibsharp不支持它们,但是TagLibsharp库有一个ReadBlock()、Removeblock()、Find()和RFind()方法,我认为这是我需要使用的方法,但我不知道如何结合使用它们.
这是我唯一拥有的:
Dim file As New TagLib.Mpeg.AudioFile("C:\input.mp3")
Dim data As Byte() = Encoding.ASCII.GetBytes("MP3GAIN_MINMAX")
Dim vector As New ByteVector(data)
Dim offset As Long = file.Find(vector)这是一个用Vb.Net编写的伪代码,只是为了演示预期的抽象或行为。
Imports TagLib
Public NotInheritable Class Mp3File
Private tagFile As Global.TagLib.Mpeg.AudioFile
Public ReadOnly Property APEv2 As APEv2Tag
Get
Return Me.apeTagB
End Get
End Property
Private ReadOnly apeTagB As APEv2Tag
Public Sub New(ByVal file As FileInfo)
Me.tagFile = New Global.TagLib.Mpeg.AudioFile(file.FullName)
Me.apeTagB = New APEv2Tag(Me.tagFile)
End Sub
End Class
''' <summary>
''' Represents the APEv2 tag for a MP3 file.
''' </summary>
Public Class APEv2Tag
Protected ReadOnly mp3File As Global.TagLib.Mpeg.AudioFile
Public Sub New(ByVal mp3File As Global.TagLib.Mpeg.AudioFile)
Me.mp3File = mp3File
End Sub
Public Overridable Property MP3GAIN_MINMAX As Double
Get
If field exists then...
Return TheValue...
End If
End Get
Set(ByVal value As Double)
...
End Set
End Property
' More properties here...
End Class更新:
我想我终于自己完成了“读”部分,但是我不知道如何写块,因为如果字段不存在,我可能会重写/损坏文件.
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Gets the <c>MP3GAIN_MINMAX</c> metatada field of the audio file.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' The <c>MP3GAIN_MINMAX</c> field value.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Private Function GetFieldMP3GainMinMax() As String
Dim data As Byte() = Encoding.UTF8.GetBytes("MP3GAIN_MINMAX")
Dim vector As New ByteVector(data)
Dim offset As Long = Me.mp3File.Find(vector)
Dim result As String
If (offset = -1) Then
Return String.Empty
Else
Try
offset += ("MP3GAIN_MINMAX".Length + 1)
Me.mp3File.Seek(offset, SeekOrigin.Begin)
result = Me.mp3File.ReadBlock(8).ToString.TrimEnd()
Return result
Catch ex As Exception
Throw
Finally
Me.mp3File.Seek(0, SeekOrigin.Begin)
End Try
End If
End Function
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Gets the <c>MP3GAIN_UNDO</c> metatada field of the audio file.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' The <c>MP3GAIN_UNDO</c> field value.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Private Function GetFieldMP3GainUndo() As String
Dim data As Byte() = Encoding.UTF8.GetBytes("MP3GAIN_UNDO")
Dim vector As New ByteVector(data)
Dim offset As Long = Me.mp3File.Find(vector)
Dim result As String
If (offset = -1) Then
Return String.Empty
Else
Try
offset += ("MP3GAIN_UNDO".Length + 1)
Me.mp3File.Seek(offset, SeekOrigin.Begin)
result = Me.mp3File.ReadBlock(12).ToString.TrimEnd()
Return result
Catch ex As Exception
Throw
Finally
Me.mp3File.Seek(0, SeekOrigin.Begin)
End Try
End If
End Function
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Gets the <c>REPLAYGAIN_TRACK_GAIN</c> metatada field of the audio file.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' The <c>REPLAYGAIN_TRACK_GAIN</c> field value.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Private Function GetFieldReplayGainTrackGain() As String
Dim data As Byte() = Encoding.UTF8.GetBytes("REPLAYGAIN_TRACK_GAIN")
Dim vector As New ByteVector(data)
Dim offset As Long = Me.mp3File.Find(vector)
Dim result As String
If (offset = -1) Then
Return String.Empty
Else
Try
offset += ("REPLAYGAIN_TRACK_GAIN".Length + 1)
Me.mp3File.Seek(offset, SeekOrigin.Begin)
result = Me.mp3File.ReadBlock(12).ToString.TrimEnd()
Return result
Catch ex As Exception
Throw
Finally
Me.mp3File.Seek(0, SeekOrigin.Begin)
End Try
End If
End Function
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Gets the <c>REPLAYGAIN_TRACK_PEAK</c> metatada field of the audio file.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' The <c>REPLAYGAIN_TRACK_PEAK</c> field value.
''' </returns>
''' ----------------------------------------------------------------------------------------------------
<DebuggerStepThrough>
Private Function GetFieldReplayGainTrackPeak() As String
Dim data As Byte() = Encoding.UTF8.GetBytes("REPLAYGAIN_TRACK_PEAK")
Dim vector As New ByteVector(data)
Dim offset As Long = Me.mp3File.Find(vector)
Dim result As String
If (offset = -1) Then
Return String.Empty
Else
Try
offset += ("REPLAYGAIN_TRACK_PEAK".Length + 1)
Me.mp3File.Seek(offset, SeekOrigin.Begin)
result = Me.mp3File.ReadBlock(8).ToString.TrimEnd()
Return result
Catch ex As Exception
Throw
Finally
Me.mp3File.Seek(0, SeekOrigin.Begin)
End Try
End If
End Function发布于 2016-03-31 21:56:08
从APEv2文件中获取TagLib#特定信息的过程类似于这个答案中描述的ID3v2标记的过程。
下面是如何读取值:
// Get the APEv2 tag if it exists.
TagLib.Ape.Tag ape_tag = (TagLib.Ape.Tag)file.GetTag(TagLib.TagTypes.Ape, false);
if(ape_tag != null) {
// Get the item.
TagLib.Ape.Item item = ape_tag.GetItem("MP3GAIN_MINMAX");
if (item != null) {
Console.Log(item.ToStringArray());
}
}我不能从屏幕截图中确定该字段是一个字符串还是两个字符串,由逗号连接。
储蓄将是相反的方向,但稍微简单一点:
// Get the APEv2 tag if it exists.
TagLib.Ape.Tag ape_tag = (TagLib.Ape.Tag)file.GetTag(TagLib.TagTypes.Ape, true);
if(ape_tag != null) {
ape_tag.SetValue("MP3GAIN_MINMAX", value);
}
file.Save();例如,对于Vb.Net:
字段:
ReadOnly mp3File As Global.TagLib.Mpeg.AudioFile = ...属性(MP3Gain相关):
Property MP3GainMinMax As String
Get
Return Me.GetField("MP3GAIN_MINMAX")
End Get
Set(ByVal value As String)
Me.SetField("MP3GAIN_MINMAX", value)
End Set
End Property
Property MP3GainUndo As String
Get
Return Me.GetField("MP3GAIN_UNDO")
End Get
Set(ByVal value As String)
Me.SetField("MP3GAIN_UNDO", value)
End Set
End Property
Property ReplayGainTrackGain As String
Get
Return Me.GetField("REPLAYGAIN_TRACK_GAIN")
End Get
Set(ByVal value As String)
Me.SetField("REPLAYGAIN_TRACK_GAIN", value)
End Set
End Property
Property ReplayGainTrackPeak As String
Get
Return Me.GetField("REPLAYGAIN_TRACK_PEAK")
End Get
Set(ByVal value As String)
Me.SetField("REPLAYGAIN_TRACK_PEAK", value)
End Set
End Property函数'Get':
Function GetField(ByVal fieldName As String) As String
Dim apeTag As TagLib.Ape.Tag =
DirectCast(Me.mp3File.GetTag(TagTypes.Ape, create:=False), TagLib.Ape.Tag)
If (apeTag IsNot Nothing) Then
Dim item As TagLib.Ape.Item = apeTag.GetItem(fieldName)
If (item IsNot Nothing) Then
Return item.ToString()
End If
End If
Return String.Empty
End Function方法“集合”:
Sub SetField(ByVal fieldName As String, ByVal value As String)
Dim apeTag As TagLib.Ape.Tag =
DirectCast(Me.mp3File.GetTag(TagTypes.Ape, create:=True), TagLib.Ape.Tag)
apeTag.SetValue(fieldName, value)
End Subhttps://stackoverflow.com/questions/36011496
复制相似问题