【问题标题】:Read APEv2 mp3 tag with TagLibSharp?使用 TagLibSharp 读取 APEv2 mp3 标签?
【发布时间】:2016-03-15 12:33:30
【问题描述】:

场景


我一般使用MP3Gain应用来设置mp3文件的回放增益。

应用程序可以在 mp3 文件的 APEv2 标签中创建这些字段:

(截图来自WinAmp播放器)

问题


使用 TagLibSharp 库我写了一个 ID3v1ID3v2 解析器,现在,我想知道我是否可以读写上面提到的 APEv2 字段使用这个库?

研究


我认为 MP3Gain 应用程序使用唯一的字段名称,所以可能 TagLibsharp 不支持它们,但是,TagLibsharp 库有一个 @ 987654326@、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

【问题讨论】:

    标签: c# .net vb.net mp3 taglib-sharp


    【解决方案1】:

    从 TagLib# 文件中获取 APEv2 特定信息的过程类似于this answer 中描述的 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
    

    函数“获取”:

    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 Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-26
      • 2011-09-14
      • 1970-01-01
      • 1970-01-01
      • 2011-09-12
      • 2010-12-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多