Im trying to change the title of a mp3 file
but it doesnt work ans also error An attempt was made to move the file pointer before the beginning of the file pops up at file seek ive comented it out (ie. '///###@@) in the WriteID3v11() sub

heres my code

code from codeproject by Angren Aldaron (http://www.codeproject.com/KB/audio-video/id3v1editor.aspx

'
' * Created by SharpDevelop.
' * User: Merlin Hunter
' * Date: 31.05.2005
' * Time: 19:33
' * 
' * You may use this code for all purposes,
' * but you use this code at your own risk.
' 


Imports System
Imports System.IO
Imports System.Text

Namespace id3v1Tagger
    ''' <summary>
    ''' Description of LTTagger.
    ''' </summary>
    Public Class Tagger
        Private filePath As String

        ' Used Standard: ID3v1.1
        '		 * This standard uses one byte of the comment field to insert a title number
        '		 

        Private buffer As Byte() = New Byte(127) {}
        'buffer for read an write actions
        Private m_title As String = ""
        'Byte 4-33
        Private m_artist As String = ""
        'Byte 34-63
        Private m_album As String = ""
        'Byte 64-93
        Private m_year As String = ""
        'Byte 94-97
        Private m_comment As String = ""
        'Byte 98-125
        'Byte 126 is a Zero Byte Seperator
        Private m_titleNumber As String = ""
        'Byte 127
        Private genre As String = "255"
        'Byte 128
        Private m_hasTag As Boolean = False
        Private hadTag As Boolean = False
        Private m_fullFilePath As String = ""

        Public Sub New(ByVal filePath As String)
            Me.filePath = filePath

            'if the file doesn't exist, we needn't to work further
            If Not File.Exists(filePath) Then
                Throw New FileNotFoundException("Datei nicht gefunden", filePath)
            End If
            IntializeID3v1Variables(Me.filePath)
        End Sub

        Private Sub IntializeID3v1Variables(ByVal filePath As String)
            Dim myFile As New FileInfo(filePath)
            m_fullFilePath = myFile.FullName
            '
            '			 * if the file ist smaller than 128 byte, there can't be a ID3v1 tag.
            '			 * Even a MP3 file with such size isn't possible, but the user should decide
            '			 * if he want add a ID3v1
            '			 

            If myFile.Length <= 128 Then
            Else

                Dim fileStream As Stream = myFile.OpenRead()
                fileStream.Seek(-128, SeekOrigin.[End])
                'speed up to needed position
                For i As Integer = 0 To 127
                    buffer(i) = CByte(fileStream.ReadByte())
                Next
                fileStream.Close()
                'close fileStream
                If Encoding.[Default].GetString(buffer, 0, 3).Equals("TAG") Then
                    Me.m_hasTag = True
                    Me.hadTag = True
                    Me.m_title = Encoding.[Default].GetString(buffer, 3, 30)
                    Me.m_artist = Encoding.[Default].GetString(buffer, 33, 30)
                    Me.m_album = Encoding.[Default].GetString(buffer, 63, 30)
                    Me.m_year = Encoding.[Default].GetString(buffer, 93, 4)
                    Me.m_comment = Encoding.[Default].GetString(buffer, 97, 28)
                    If Convert.ToInt32(buffer(126)) <= 147 Then
                        Me.m_titleNumber = (Convert.ToInt32(buffer(126))).ToString()
                    End If
                    If Convert.ToInt32(buffer(127)) > 0 Then
                        Me.genre = (Convert.ToInt32(buffer(127))).ToString()
                    End If
                End If
            End If
        End Sub

#Region "properties for setting and getting the fields"
        Public Property HasTag() As Boolean
            Get
                Return Me.m_hasTag
            End Get
            Set(ByVal value As Boolean)
                Me.m_hasTag = value
            End Set
        End Property

        ''' <summary>
        ''' sets or reads the title. If there's a size over 30 characters, it throws a FormatException
        ''' </summary>
        Public Property Title() As String
            Get
                Return Me.m_title
            End Get
            Set(ByVal value As String)
                If value.Length > 30 Then
                    Throw New FormatException("Der Text ist länger als 30 Zeichen, und könnte deswegen nicht gespeichert werden.")
                End If
                Me.m_title = value

                'change the data first to a byte-array, and copy that array in the buffer
                Dim temp As Byte() = New Byte(29) {}
                StringToByte(value).CopyTo(temp, 0)
                temp.CopyTo(buffer, 3)
            End Set
        End Property

        ''' <summary>
        ''' sets or reads the artist. If there's a size over 30 characters, it throws a FormatException
        ''' </summary>
        Public Property Artist() As String
            Get
                Return Me.m_artist
            End Get
            Set(ByVal value As String)
                If value.Length > 30 Then
                    Throw New FormatException("Der Text ist länger als 30 Zeichen, und könnte deswegen nicht gespeichert werden.")
                End If
                Me.m_artist = value

                'change the data first to a byte-array, and copy that array in the buffer
                Dim temp As Byte() = New Byte(29) {}
                StringToByte(value).CopyTo(temp, 0)
                temp.CopyTo(buffer, 33)
            End Set
        End Property

        ''' <summary>
        ''' sets or reads the album. If there's a size over 30 characters, it throws a FormatException
        ''' </summary>
        Public Property Album() As String
            Get
                Return Me.m_album
            End Get
            Set(ByVal value As String)
                If value.Length > 30 Then
                    Throw New FormatException("Der Text ist länger als 30 Zeichen, und könnte deswegen nicht gespeichert werden.")
                End If
                Me.m_album = value

                'first change the data to a byte-array, and copy that array in the buffer
                Dim temp As Byte() = New Byte(29) {}
                StringToByte(value).CopyTo(temp, 0)
                temp.CopyTo(buffer, 63)
            End Set
        End Property

        ''' <summary>
        ''' sets or reads the year. If there's a size over 4 characters, it throws a FormatException
        ''' </summary>
        Public Property Year() As String
            Get
                Return Me.m_year
            End Get
            Set(ByVal value As String)
                If value.Length > 4 Then
                    Throw New FormatException("Der Text ist länger als 4 Zeichen, und könnte deswegen nicht gespeichert werden.")
                End If
                Me.m_year = value

                'change the data first to a byte-array, and copy that array in the buffer
                Dim temp As Byte() = New Byte(3) {}
                StringToByte(value).CopyTo(temp, 0)
                temp.CopyTo(buffer, 93)
            End Set
        End Property

        ''' <summary>
        ''' sets or reads the comment. If there's a size over 28 characters, it throws a FormatException
        ''' </summary>
        Public Property Comment() As String
            Get
                Return Me.m_comment
            End Get
            Set(ByVal value As String)
                If value.Length > 28 Then
                    Throw New FormatException("Der Text ist länger als 28 Zeichen, und könnte deswegen nicht gespeichert werden.")
                End If
                Me.m_comment = value

                'change the data first to a byte-array, and copy that array in the buffer
                'Note: normally the comment field has 29 bytes, but the last byte is a
                'zero byte seperator
                Dim temp As Byte() = New Byte(28) {}
                StringToByte(value).CopyTo(temp, 0)
                temp.CopyTo(buffer, 97)
            End Set
        End Property

        ''' <summary>
        ''' sets or reads the title number. If the value is greater than 255
        ''' or smaller than 0 or the value is not a number, it throws a FormatException
        ''' </summary>
        Public Property TitleNumber() As String
            Get
                Return Me.m_titleNumber
            End Get
            Set(ByVal value As String)
                If value.Equals("") Then
                    value = "0"
                End If
                If Int32.Parse(value) > 255 Then
                    Throw New FormatException("Die eingegebene Zahl ist größer als 255, und könnte deswegen nicht korrekt gespeichert werden.")
                End If
                If Int32.Parse(value) < 0 Then
                    Throw New FormatException("Die eingegebene Zahl ist kleiner als 0, und könnte deswegen nicht korrekt gespeichert werden")
                End If
                Me.m_titleNumber = value
                'format the data and write it to the buffer
                buffer(126) = Convert.ToByte(value)
            End Set
        End Property

        ''' <summary>
        ''' sets or reads the GenreID. If the value is greater than 255
        ''' or smaller than 0 or the value is not a number, it throws a FormatException
        ''' </summary>
        Public Property GenreID() As String
            Get
                If m_hasTag Then
                    Return Me.genre
                Else
                    Return ""
                End If
            End Get
            Set(ByVal value As String)
                If value.Equals("") Then
                    value = "255"
                End If
                If Int32.Parse(value) > 255 Then
                    Throw New FormatException("Die eingegebene Zahl ist größer als 255, und könnte deswegen nicht korrekt gespeichert werden.")
                End If
                Me.genre = value
                'format the data and writh it to the buffer
                buffer(127) = Convert.ToByte(value)
            End Set
        End Property

        ''' <summary>
        ''' reads the genreID and returns the genre name as string. If theres a ID over 147
        ''' it return an empty string
        ''' </summary>
        Public ReadOnly Property GenreName() As String
            Get
                If Int32.Parse(Me.genre) < 147 Then
                    Return ""
                Else
                    Return GenreDB.GenreList(Int32.Parse(Me.genre))
                End If
            End Get
        End Property
#End Region
        Public ReadOnly Property FullFilePath() As String
            Get
                Return m_fullFilePath
            End Get
        End Property

        Public ReadOnly Property FileSize() As Long
            Get
                Return (New FileInfo(m_fullFilePath)).Length
            End Get
        End Property

        Private Function StringToByte(ByVal stringToConvert As String) As [Byte]()
            Dim message As [Byte]() = Encoding.[Default].GetBytes(stringToConvert.ToCharArray())
            Return message
        End Function


        ''' <summary>
        ''' This method writes the data. If the file is in use it will throw
        ''' an IOException
        ''' </summary>
        Public Sub WriteID3v11()
            'first change the data to a byte-array, and copy that array in the buffer
            Dim bHandled As Boolean = False
            Dim temp As Byte() = New Byte(2) {}
            StringToByte("TAG").CopyTo(temp, 0)
            temp.CopyTo(buffer, 0)

            Dim myFile As New FileInfo(filePath)
            Dim myStream As FileStream = myFile.OpenWrite()

            'there was a tag, which now will be updated
            If hadTag And m_hasTag And Not bHandled Then
                bHandled = True
                myStream.Seek(0, SeekOrigin.Begin)
                '///###@@  OVER HERE!! -->  myStream.Seek(-128, SeekOrigin.[End])
                myStream.Write(buffer, 0, 128)
            End If

            'It didn't exist a tag, now one will be inserted
            If Not hadTag And m_hasTag And Not bHandled Then
                bHandled = True
                hadTag = True
                myStream.Seek(0, SeekOrigin.[End])
                myStream.Write(buffer, 0, 128)
            End If

            'Nothing will change. No tag existed, no tag will be inserted
            If Not hadTag And Not m_hasTag And Not bHandled Then
                bHandled = True
            End If

            'It existed a tag, which will be deleted
            If hadTag And Not m_hasTag And Not bHandled Then
                bHandled = True
                hadTag = False
                myStream.SetLength(myStream.Length - 128)
            End If

            myStream.Close()
        End Sub
    End Class

    ''' <summary>
    ''' Central genre enumeration. It raises clarity and reduces ram usage
    ''' </summary>
    Public Class GenreDB
        'Winamp Extensions

        Private Shared m_genreList As String() = New String() {"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", _
         "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", _
         "Other Genre", "Pop", "R&B", "Rap", "Reggae", "Rock", _
         "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", _
         "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz&Funk", _
         "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", _
         "Game", "Sound Clip", "Gospel", "Noise", "Alternativ Rock", "Bass", _
         "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", _
         "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", _
         "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", _
         "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native US", "Carbaret", _
         "New Wave", "Psychedelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", _
         "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", _
         "Rock & Roll", "Hard Rock", "Folk", "Folk-Rock", "National Folk", "Swing", _
         "Fast Fusion", "Bebop", "Latin", "Revival", "Celtic", "Bluegrass", _
         "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychadelic Rock", "Symphonic Rock", "Slow Rock", _
         "Big Band", "Chorus", "Easy Listening", "Acoustic", "Homour", "Speech", _
         "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", _
         "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", _
         "Samba", "Folklore", "Ballad", "Power Ballad", "Rythmic Soul", "Freestyle", _
         "Duet", "Punk Rock", "Drum Solo", "Acapella", "Euor-House", "Dance Hall", _
         "Goa", "Drum & Bass", "Club-House", "Hardcore", "Terror", "Indie", _
         "BritPop", "Negerpunk", "Polsk Punk", "Beat", "Christian Gangsta", "Heavy Metal", _
         "Black Metal", "Crossover", "Contemporary", "Christian Rock", "Merengue", "Salsa", _
         "Trash Metal", "Anime", "JPop", "SynthPop"}

        'Property to get the whole list
        Public Shared ReadOnly Property GenreList() As String()
            Get
                Return m_genreList
            End Get
        End Property

        Public Shared Function GetGenreID(ByVal genre As String) As String
            Dim genreID As Integer = 255
            For i As Integer = 0 To m_genreList.Length - 1
                If genre.ToLower().Equals(m_genreList(i).ToLower()) Then
                    genreID = i
                    Exit For
                End If
            Next

            Return genreID.ToString()
        End Function
    End Class
End Namespace

n how i call it

Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
        Dim fname As String = ""
        Dim temp As String = ""
        Dim OldName As String = ""

        Dim ii As Integer = ListBox2.TopIndex
        Dim files As String()
        files = IO.Directory.GetFiles(loc_path, "*.mp3")

        For Each filepath As String In files
            Dim idtag As New id3v1Tagger.Tagger(filepath)
            Dim dirName As String = IO.Path.GetFileName(filepath)
            OldName = dirName
            temp = dirName
            fname = ListBox1.Items(ii)

            My.Computer.FileSystem.RenameFile(filepath, fname)

            idtag.Title = temp
            idtag.WriteID3v11()
            ii += 1
            pgr.Value += 1
            System.Threading.Thread.Sleep(3000)
            If ii = ListBox2.Items.Count Then
                Exit For
            End If
        Next
        MsgBox("Done!", MsgBoxStyle.Information)

    End Sub

Theres no other error but it doesnt wrk pl helppp \

thnx

Recommended Answers

All 2 Replies

You are trying to get a position 128 bytes before the end of file.
As you just created it, the file is empty and the seek position results to be before the BOF.

Hope this helps

so umm what do I have to do? I am not exactly familiar with this kinda problems hehe :D

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.