Question

I want to code a generic function to set a tag field of a music file, I'm using "TagLib Sharp" library, I'm trying to code something that can be tittled as "TagLib Sharp Helper Class"

To call the procedure I want to use some syntax like this to set the field "Album":

 TagLibSharp.Set_Tag_And_Save( _
             "C:\Test.mp3", _
             Function() TagLib.File.Create("").Tag.Album, _
             "Test album name" _
 )

The problem is I don't know what to do with the Lambda expression inside the procedure...

Here is all the code (notice the comment lines explainning where is the problem):

#Region " TagLib Sharp "

Public Class TagLibSharp

''' <summary>
''' Stores the Taglib object.
''' </summary>
Private Shared TagFile As TagLib.File = Nothing

''' <summary>
''' Sets a Tag field and saves the file changes.
''' </summary>
Public Shared Sub Set_Tag_And_Save(ByVal File As String, _
                                   ByVal Field As Linq.Expressions.Expression(Of Func(Of Object)), _
                                   ByVal Value As String)

    TagFile = TagLib.File.Create(File)

    Dim member As Linq.Expressions.MemberExpression = _
        If(TypeOf Field.Body Is Linq.Expressions.UnaryExpression, _
           DirectCast(DirectCast(Field.Body, Linq.Expressions.UnaryExpression).Operand, Linq.Expressions.MemberExpression), _
           DirectCast(Field.Body, Linq.Expressions.MemberExpression))

    MsgBox(member.Member.Name) ' Result: "Album"

    ' member.Member = Value ' Here is where I don't know what to do
    '
    ' This would be the ewuivalent:
    TagFile.Tag.Album = Value

    TagFile.Save()

End Sub

End Class

#End Region

UPDATE

Trying to solve the problem following the steps of Ben Allred solution I get an exception.

TagLibSharp.Set_Tag_And_Save("c:\1.mp3", Function() TagLib.File.Create("").Tag.Album = "Test album name")

The modified sub:

Public Shared Sub Set_Tag_And_Save(ByVal File As String, _
                                   ByVal FieldSetter As Action(Of TagLib.File))

    TagFile = TagLib.File.Create(File)
    FieldSetter(TagFile) ' Here throws an exception with this message: "taglib/"
    ' FieldSetter(TagLib.File.Create(File)) ' The same exception with this one.
    TagFile.Save()

End Sub

UPDATE 2:

Now I don't get any exception, but the tag field is not set.

TagLibSharp.Set_Tag_And_Save("c:\Test.mp3", Function(tagLibFile) tagLibFile.Tag.Title = "Test title name")

The modified sub:

Public Shared Sub Set_Tag_And_Save(ByVal File As String, _
                                   ByVal FieldSetter As Action(Of TagLib.File))

    TagFile = TagLib.File.Create(File)

    MsgBox(TagFile.Tag.Title) ' Result: Unbreakeable
    FieldSetter(TagFile)
    MsgBox(TagFile.Tag.Title) ' Result: Unbreakeable

    ' TagFile.Tag.Title = "Test title name"
    ' MsgBox(TagFile.Tag.Title) ' Result: "Test title name"

    TagFile.Save()

End Sub
Was it helpful?

Solution

(My syntax is C#. I don't know the exact syntax in VB.)

The easiest way to do what you want with what you have is to make the following changes:

1 - Change the lambda expression to take one parameter of type TagLib.File.

public void Set_Tag_And_Save(..., Action<TagLib.File> FieldSetter, ...)

2 - Pass the action to the call to Set_Tag_And_Save and set the value in the action.

Set_Tag_And_Save("C:\Test.mp3", tagLibFile => tagLibFile.Tag.Album = "Test album name");

3 - Call the action inside Set_Tag_And_Save.

FieldSetter(TagFile);
TagFile.Save();

OTHER TIPS

I did some modifications to call it as this:

TagLibSharp.Set_Tag_Fields("C:\Test.mp3", _
                           {Sub(x) x.Tag.Title = "Title Test", _
                            Sub(x) x.Tag.Performers = {"Artist Test"}, _
                            Sub(x) x.Tag.Album = "Album Test", _
                            Sub(x) x.Tag.Year = "2000"})

Here is the full Helper Class:

#Region " TagLib Sharp Helper "


' [ TagLib Sharp Helper ]
'
' // By Elektro H@cker
'
'
' Instructions:
' 1. Add a reference to "taglib-sharp.dll" into the project.
'
'
' Examples:
'
' MsgBox(TagLibSharp.FileIsCorrupt("C:\File.mp3")) ' Result: True or False
' MsgBox(TagLibSharp.FileIsWriteable("C:\File.mp3")) ' Result: True or False
' MsgBox(TagLibSharp.Get_Title("C:\File.mp3"))
' MsgBox(TagLibSharp.Get_Artist("C:\File.mp3"))
' MsgBox(TagLibSharp.Get_Album("C:\File.mp3"))
' MsgBox(TagLibSharp.Get_Genre("C:\File.mp3"))
' MsgBox(TagLibSharp.Get_Year("C:\File.mp3"))
' MsgBox(TagLibSharp.Get_Basic_TagInfo("C:\File.mp3"))
' TagLibSharp.RemoveTag("C:\File.mp3", TagLib.TagTypes.Id3v1 Or TagLib.TagTypes.Id3v2) ' Removes ID3v1 + ID3v2 Tags
' TagLibSharp.Set_Tag_Fields("C:\Test.mp3", Sub(x) x.Tag.Title = "Title Test"})
' TagLibSharp.Set_Tag_Fields("C:\Test.mp3", {Sub(x) x.Tag.Title = "Title Test", Sub(x) x.Tag.Performers = {"Artist Test"}})


Public Class TagLibSharp

''' <summary>
''' Stores the Taglib object.
''' </summary>
Private Shared TagFile As TagLib.File = Nothing

''' <summary>
''' Checks if file is possibly corrupted.
''' </summary>
Public Shared Function FileIsCorrupt(ByVal File As String) As Boolean

    Try
        Return TagLib.File.Create(File).PossiblyCorrupt

    Catch ex As Exception
        Throw New Exception(ex.Message)
        Return True

    Finally
        If TagFile IsNot Nothing Then TagFile.Dispose()

    End Try

End Function

''' <summary>
''' Checks if file can be written.
''' </summary>
Public Shared Function FileIsWriteable(ByVal File As String) As Boolean

Try
    Return TagLib.File.Create(File).Writeable

Catch ex As Exception
    Throw New Exception(ex.Message)
    Return True

Finally
    If TagFile IsNot Nothing Then TagFile.Dispose()

End Try

End Function

''' <summary>
''' Get TagTypes of file.
''' </summary>
Public Shared Function Get_Tags(ByVal File As String) As String

Try
    Return TagLib.File.Create(File).TagTypes.ToString

Catch ex As Exception
    Throw New Exception(ex.Message)
    Return String.Empty

Finally
    If TagFile IsNot Nothing Then TagFile.Dispose()

End Try

End Function

''' <summary>
''' Remove a entire Tag from file.
''' </summary>
Public Shared Sub RemoveTag(ByVal File As String, ByVal TagTypes As TagLib.TagTypes)

Try
    TagFile = TagLib.File.Create(File)
Catch ex As Exception
    Throw New Exception(ex.Message)
    Exit Sub
End Try

Try

    If Not TagFile.PossiblyCorrupt _
    AndAlso TagFile.Writeable Then

        TagFile.RemoveTags(TagTypes)
        TagFile.Save()

    End If

Catch ex As Exception
    Throw New Exception(ex.Message)

Finally
    If TagFile IsNot Nothing Then TagFile.Dispose()

End Try

End Sub

''' <summary>
''' Gets the Title tag field of file.
''' </summary>
Public Shared Function Get_Title(ByVal File As String) As String

Try
    Return TagLib.File.Create(File).Tag.Title

Catch ex As Exception
    Throw New Exception(ex.Message)
    Return String.Empty

Finally
    If TagFile IsNot Nothing Then TagFile.Dispose()

End Try

End Function

''' <summary>
''' Gets the Artist tag field of file.
''' </summary>
Public Shared Function Get_Artist(ByVal File As String) As String

Try
    Return TagLib.File.Create(File).Tag.Performers(0)

Catch ex As Exception
    Throw New Exception(ex.Message)
    Return String.Empty

Finally
    If TagFile IsNot Nothing Then TagFile.Dispose()

End Try

End Function

''' <summary>
''' Gets the Album tag field of file.
''' </summary>
Public Shared Function Get_Album(ByVal File As String) As String

Try
    Return TagLib.File.Create(File).Tag.Album

Catch ex As Exception
    Throw New Exception(ex.Message)
    Return String.Empty

Finally
    If TagFile IsNot Nothing Then TagFile.Dispose()

End Try

End Function

''' <summary>
''' Gets the Genre tag field of file.
''' </summary>
Public Shared Function Get_Genre(ByVal File As String) As String

Try
    Return TagLib.File.Create(File).Tag.Genres(0)

Catch ex As Exception
    Throw New Exception(ex.Message)
    Return String.Empty

Finally
    If TagFile IsNot Nothing Then TagFile.Dispose()

End Try

End Function

''' <summary>
''' Gets the Year tag field of file.
''' </summary>
Public Shared Function Get_Year(ByVal File As String) As String

Try
    Return TagLib.File.Create(File).Tag.Year

Catch ex As Exception
    Throw New Exception(ex.Message)
    Return String.Empty

Finally
    If TagFile IsNot Nothing Then TagFile.Dispose()

End Try

End Function

''' <summary>
''' Gets the basic tag fields of file.
''' </summary>
Public Shared Function Get_Basic_TagInfo(ByVal File As String) As String

Try
    TagFile = TagLib.File.Create(File)

    Return String.Format("Title: {1}{0}Artist: {2}{0}Album: {3}{0}Genre: {4}{0}Year: {5}", Environment.NewLine, _
                         TagFile.Tag.Title, _
                         TagFile.Tag.Performers(0), _
                         TagFile.Tag.Album, _
                         TagFile.Tag.Genres(0), _
                         TagFile.Tag.Year)

Catch ex As Exception
    Throw New Exception(ex.Message)
    Return String.Empty

Finally
    If TagFile IsNot Nothing Then TagFile.Dispose()

End Try

End Function

''' <summary>
''' Sets a Tag field.
''' </summary>
Public Shared Sub Set_Tag_Fields(ByVal File As String, _
                                   ByVal FieldSetter As Action(Of TagLib.File))

Try
    TagFile = TagLib.File.Create(File)
Catch ex As Exception
    Throw New Exception(ex.Message)
    Exit Sub
End Try

Try

    If Not TagFile.PossiblyCorrupt _
    AndAlso TagFile.Writeable Then

        FieldSetter(TagFile)
        TagFile.Save()

    End If

Catch ex As Exception
    Throw New Exception(ex.Message)

Finally
    If TagFile IsNot Nothing Then TagFile.Dispose()

End Try

End Sub

''' <summary>
''' Sets multiple Tag fields.
''' </summary>
Public Shared Sub Set_Tag_Fields(ByVal File As String, _
                                   ByVal FieldSetter() As Action(Of TagLib.File))

Try
    TagFile = TagLib.File.Create(File)
Catch ex As Exception
    Throw New Exception(ex.Message)
    Exit Sub
End Try

Try

    If Not TagFile.PossiblyCorrupt _
    AndAlso TagFile.Writeable Then

        For Each Field In FieldSetter
            Field(TagFile)
        Next

        TagFile.Save()

    End If

Catch ex As Exception
    Throw New Exception(ex.Message)

Finally
    If TagFile IsNot Nothing Then TagFile.Dispose()

End Try

End Sub

End Class

#End Region
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top