Jump to content

ID3 UDF ID3v1 & ID3v2 MP3 Tags


joeyb1275
 Share

Recommended Posts

  • 2 months later...

Thank you for the excellent UDF!
It needs help. Already tried all sorts of variants. After a record or just read the tags file, it can not be removed. But disappears from the disc only after the closure of the program. How can I fix it?

Thanks!

Edited by AndreyS
Link to comment
Share on other sites

After a record or just read the tags file, it can not be removed. But disappears from the disc only after the closure of the program. How can I fix it?

Hi Andrey S.

I haven't looked at this in a while, and are still not using the latest version available here, that was created by the OP.

That said, I really don't understand your issue. You need to give a step by step description, and provide the code for those steps, so that we can both see any mistakes you may have made, plus gain understanding of your problem.

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
Share on other sites

Why are you opening the file to read the tag information of the file if you're deleting it right afterwards? What purpose are you doing this for?

Edited by BrewManNH

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Can you show an actual script that demonstrates the problem? That script you posted worked fine for me, it got deleted without any issues using the version 3.4 UDF.

There are plenty of checks in the UDF where the file handle gets closed prior to returning from the function, so I can't see anything in it that would cause the issue you're describing.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

I need to delete happened immediately after using FileDelete. Not after the completing the program!

Please tell me how to do it?

Functions FileClose(), FileFlush(), _ID3DeleteFiles() not help. What are the other variants?

Edited by AndreyS
Link to comment
Share on other sites

As I said, the problem isn't happening for me with the snippet you posted. It gets deleted as soon as the first MsgBox shows up. There's no file locking on my computers that I tested it on.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Are you wanting to delete the file or delete the TAG?

I ask that, because I am a little confused at this point.

Sometimes, if a file is in use by another program, it cannot be deleted.

If I remember rightly, when you read the tags with _ID3ReadTag($File), a temporary file is created, that is cleaned up by using _ID3DeleteFiles(). I'm not sure if that is only when artwork is present, and thus the temp file is a JPG file.

Not having seen your full code, I can only speculate, that another section of your code might be (still) accessing your MP3 file, thus preventing it from being deleted.

Or it may be a permissions issue?

Or perhaps the file is read only?

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
Share on other sites

It gets deleted as soon as the first MsgBox shows up. There's no file locking on my computers that I tested it on.

It's incredible! How did you do it? I tested it on three computers and I have all three file is not removed after performing FileDelete(). Second MsgBox always returns 1.
Yes, the code in my program more complicated. But the problem is not exactly in it. I specifically wrote this test code to clearly see that the file can not be deleted if the function is activated _ID3DeleteFiles()

Are you wanting to delete the file or delete the TAG?

In my program, I only read tags. But the problem is not in my program, and that even this simple test code does not delete the file immediately.

Sometimes, if a file is in use by another program, it cannot be deleted.

The file is not used precisely no other program. I simply copied to the desktop and immediately launch the program.

that is cleaned up by using _ID3DeleteFiles()

As I wrote a function _ID3DeleteFiles () does not help.

Not having seen your full code, 

It does not matter what code I have in the program. I have this example does not even work.

Or it may be a permissions issue?

Or perhaps the file is read only?

 
With the permissions too, no problems.
File exactly conventional and correct attributes. It is no problem and immediately deleted as soon as I remove the function _ID3ReadTag ()
 
Thank you for your attention!
I really hope for your help!
Link to comment
Share on other sites

Well, I don't know that we can help any further, going by the simplicity of the code you posted.

It is possible perhaps, that something hasn't returned correctly for you when reading the ID3 tags, and thus the MP3 file is locked. How many MP3 files from different sources have you tried? It could be, that something in the tags is causing the issue, as we have not had this reported before .... APE tags perhaps or a really long entry, etc?

Have you tried to manually delete before closing the program?
If the file is locked, Windows should tell you.

Knowing what versions of Windows and AutoIt, might help too.

As for another program locking the file, it could be as simple as Anti-Virus, and so not obvious.

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
Share on other sites

I changed a little example to make it clearer.

#include <ID3_v3.4.au3>

$File=@DesktopDir&"\1.mp3"
_ID3ReadTag($File) ; If you remove this line the file is immediately deleted. And it is necessary to remove and use this function.
_ID3DeleteFiles()
MsgBox(0,0,FileDelete($File))
MsgBox(0,0,FileExists($File))

HotKeySet("{ESC}", "Quit")

While 1
    Sleep(100)
WEnd

Func Quit()
    Exit
EndFunc


And the attached file which is removed. Try yourself off if you have it from the disk.

1.mp3

Link to comment
Share on other sites

I found the problem in the UDF. The function _APEv2Tag_ReadFromFile is missing a FileClose before it returns at the end. So if there's no APE tags found in the file, the handle doesn't get closed.

Add this line just before the return statement.

FileClose($hfile) ; <<<<<<<<<<<<<<<<<<<<<<<< Add this line
    Return $APEv2_TAGINFO

 

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Lots of jumping around in there. It's set up as functional programming rather than trying to stuff everything into one huge function. A bit harder to follow, but allows for modular updating.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

I found the problem in the UDF.

Well discovered bug. :thumbsup:

Obviously only introduced in the later version(s), when APE Tags were supported for removal etc.

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Link to comment
Share on other sites

  • 1 month later...

There is a bug that may lead to a crash, because in some rare cases a not existing index for an array is used.

I think the two lines i added will fix this:

Func _h_ID3v2Tag_RemoveUnsynchronisation()
    ;The only purpose of the 'unsynchronisation scheme' is to make the ID3v2 tag as compatible
    ;as possible with existing software. There is no use in 'unsynchronising' tags if the file
    ;is only to be processed by new software. Unsynchronisation may only be made with MPEG 2
    ;layer I, II and III and MPEG 2.5 files. Whenever a false synchronisation is found within
    ;the tag, one zeroed byte is inserted after the first false synchronisation byte. The format
    ;of a correct sync that should be altered by ID3 encoders is as follows:
    ;       %11111111 111xxxxx
    ;And should be replaced with:
    ;       %11111111 00000000 111xxxxx
    ;This has the side effect that all $FF 00 combinations have to be altered, so they won't be
    ;affected by the decoding process. Therefore all the $FF 00 combinations have to be replaced
    ;with the $FF 00 00 combination during the unsynchronisation.  To indicate usage of the
    ;unsynchronisation, the first bit in 'ID3 flags' should be set. This bit should only be set if
    ;the tag contains a, now corrected, false synchronisation. The bit should only be clear if the
    ;tag does not contain any false synchronisations.


    ;Find all %11111111 00000000 111xxxxx = 0xFF 0x00 0xE0 and 0xFF 0x00 0x00
    Local $aIndex[1]
    $aIndex[0] = 0
    For $ibyte = 1 To BinaryLen($ID3v2_RawDataBinary) - 1
        If BinaryMid($ID3v2_RawDataBinary, $ibyte, 1) == Binary("0xFF") Then
            If BinaryMid($ID3v2_RawDataBinary, $ibyte + 1, 1) == Binary("0x00") Then
                _ArrayAdd($aIndex, $ibyte)
                $aIndex[0] += 1
            EndIf
        EndIf
    Next
;~  _ArrayDisplay($aIndex)
    If $aIndex[0] > 0 Then
        Local $ID3v2_RawDataBinary_Temp = BinaryMid($ID3v2_RawDataBinary, 1, 5)
        Local $bCurrentTagFlags = BinaryMid($ID3v2_RawDataBinary, 6, 1)
        $ID3v2_RawDataBinary_Temp &= Binary("0x" & Hex(BitAND(127, Dec(Hex($bCurrentTagFlags, 2))), 2)) ;Clear unsynchronisation flag in Tag header
        $ID3v2_RawDataBinary_Temp &= BinaryMid($ID3v2_RawDataBinary, 7, $aIndex[1])
        Local $Start, $Length = $aIndex[1]
        For $ibyte = 1 To $aIndex[0] - 1
            $ID3v2_RawDataBinary_Temp &= BinaryMid($ID3v2_RawDataBinary, $aIndex[$ibyte] + 2, $aIndex[$ibyte + 1] - $aIndex[$ibyte] - 1)
        Next
        $ID3v2_RawDataBinary_Temp &= BinaryMid($ID3v2_RawDataBinary, $aIndex[$aIndex[0]] + 2)

        $ID3v2_RawDataBinary = $ID3v2_RawDataBinary_Temp
    EndIf
EndFunc   ;==>_h_ID3v2Tag_RemoveUnsynchronisation

If $aIndex[0] > 0 Then

...

EndIf

prevents the execution of the code if the array is not filled with data.

Edited by Allow2010
Link to comment
Share on other sites

OK, i found another Problem: Some the udf semms to have troubles reading the TagSize correctly.

This lines give a bad result

Local $iTagSize = _ID3v2Tag_GetTagSize()

and this resulats in the while loop to take almost forever.

I added

While $iBytesRead < $iTagSize and $iTagSize<5000

to prevent such situations, but i am not deep enough in this code to really understand how i can fix this in a better way.

Func _h_ID3v2Tag_EnumerateFrameIDs()
    Local $bFrameHeader, $iTagVersion = 3, $iFrameSize, $sFrameID = "", $iZPAD = 0, $sID3v2_TAGINFO = ""
    Local $iReadBytesOffset = 10, $iFrameHeaderLen
    Local $iTagSize = _ID3v2Tag_GetTagSize()
    $ID3v2_TagFrameString = ""
    If _ID3v2Tag_GetHeaderFlags("ExtendedHeader") <> 0 Then
        ;ID3v2_TagSize include this ExtendedHeader
        ;MsgBox(0,"_GetID3v2_TagFlags",_ID3v2Tag_GetHeaderFlags("ExtendedHeader"))
        $iReadBytesOffset += 10
    EndIf

    Local $iBytesRead = $iReadBytesOffset

;   MsgBox(0,"Version",_ID3v2Tag_GetVersion())

    Local $iTagVersion = Number(StringLeft(_ID3v2Tag_GetVersion(), 1))
    If $iTagVersion == 2 Then
        $iFrameHeaderLen = 6
    Else
        $iFrameHeaderLen = 10
    EndIf

    ConsoleWrite("$iTagSize " & $iTagSize & @CRLF)

    ;Scan Tag for all Fields
    While $iBytesRead < $iTagSize and $iTagSize<5000
;       ConsoleWrite("$iBytesRead " & $iBytesRead & @CRLF)

        $bFrameHeader = BinaryMid($ID3v2_RawDataBinary, $iBytesRead + 1, $iFrameHeaderLen)
        $iBytesRead += $iFrameHeaderLen
        $sFrameID = _h_ID3v2FrameHeader_GetFrameID($bFrameHeader)

;~      MsgBox(0,$sFrameID,$bFrameHeader)

        ;Check for a valid frameID string
        ;****************************************************************************************
        If $sFrameID <> -1 Then
            ;check flags

            $iFrameSize = _h_ID3v2FrameHeader_GetFrameSize($bFrameHeader)

            ;Test Code for Foobar2000 ID3v2.4 COMM tag is not conforming to Spec
;~          If _h_ID3v2FrameHeader_GetFlags($bFrameHeader, "Unsynchronisation") == 1 Then
;~              If _h_ID3v2FrameHeader_GetFlags($bFrameHeader, "DataLengthIndicator") == 1 Then
;~                  MsgBox(0,"$iFrameSize",$iFrameSize)
;~                  ;FrameSize is the number of bytes NOT including Unsynchronisation
;~                  Local $iOriginalFrameSize = $iFrameSize
;~                  For $ibytestep=0 To $iFrameSize
;~                      MsgBox(0,"Binary",BinaryMid($ID3v2_RawDataBinary,$iBytesRead + 1 + $ibytestep,3))
;~                      If BinaryMid($ID3v2_RawDataBinary,$iBytesRead + 1 + $ibytestep,1) == Binary("0xFF") Then
;~                          If BinaryMid($ID3v2_RawDataBinary,$iBytesRead + 1 + $ibytestep + 1,1) == Binary("0x00") Then
;~                              $iFrameSize += 1
;~                              $iBytesRead += 1
;~                              MsgBox(0,"$iFrameSize",$iFrameSize)
;~                          EndIf
;~                      EndIf
;~                  Next
;~              Else
;~                  ;FrameSize is the number of bytes including Unsynchronisation
;~              EndIf
;~          EndIf


        Else
            If Dec(Hex(BinaryMid($bFrameHeader, 1, 2), 4)) == 0 Then
;~              MsgBox(0,"$bFrameHeader",$bFrameHeader)
                $iZPAD = ($iTagSize + 10) - ($iBytesRead - $iFrameHeaderLen)
;~              MsgBox(0,"ZPAD Start",BinaryToString(BinaryMid($ID3v2_RawDataBinary,$iBytesRead - $iFrameHeaderLen)))
                $ID3v2_TagFrameString &= "ZPAD" & "|" & String($iBytesRead - $iFrameHeaderLen + 1) & "|" & $iZPAD & @CRLF
                ExitLoop
            Else
;~              MsgBox(0,"Error Check Scan Frame 1",$sFrameID) ;Need to error check scan
;~              MsgBox(0,"$bFrameHeader",$bFrameHeader)
                ;This could be ZPAD with first byte wrong
;~              MsgBox(0,"$iBytesRead",$iBytesRead & " of " & $iTagSize)
;~              MsgBox(0,"20 bytes",BinaryMid($ID3v2_RawDataBinary,$iBytesRead - 6,20))
                $iBytesRead -= Round(($iFrameSize / 8 + 2))
;~              MsgBox(0,"$iBytesRead",$iBytesRead)
                For $itest = 1 To ($iBytesRead + $iFrameSize + 20)
                    $bFrameHeader = BinaryMid($ID3v2_RawDataBinary, $iBytesRead + 1 + $itest, $iFrameHeaderLen)
                    $sFrameID = _h_ID3v2FrameHeader_GetFrameID($bFrameHeader)
                    If $sFrameID <> -1 Then
                        $iBytesRead += $itest
;~                      MsgBox(0,"$iBytesRead Really in Frame",$itest)
                        $iFrameSize = _h_ID3v2FrameHeader_GetFrameSize($bFrameHeader)
;~                      MsgBox(0,"$FrameSize",$iFrameSize)
                        ExitLoop 1
                    Else
;~                      MsgBox(0,"Error Check Scan Frame",String($iBytesRead + 1 + $itest) & " => " & $FrameID)
                    EndIf
                Next
            EndIf
        EndIf
        ;****************************************************************************************


        $ID3v2_TagFrameString &= $sFrameID & "|" & String($iBytesRead + 1) & "|" & String($iFrameSize) & @CRLF
;~      MsgBox(0,"$ID3v2_TagFrameString",$ID3v2_TagFrameString)
        $iBytesRead += $iFrameSize
;~      MsgBox(0,"$iBytesRead",$iBytesRead & " of " & $iTagSize)
        $sFrameIndex = StringInStr($sID3v2_TAGINFO, $sFrameID)
        If $sFrameIndex == 0 Then
            $sID3v2_TAGINFO &= "|" & $sFrameID & ":" & "1"
        Else

            $sFrameIndexEnd = StringInStr(StringMid($sID3v2_TAGINFO, $sFrameIndex), ":")
            $iNumFrameID = 1 + Number(StringMid($sID3v2_TAGINFO, $sFrameIndex + $sFrameIndexEnd, 1))
            $sNewFrameIDString = $sFrameID & ":" & $iNumFrameID
            $sID3v2_TAGINFO = StringReplace($sID3v2_TAGINFO, $sFrameID & ":" & $iNumFrameID - 1, $sNewFrameIDString)
        EndIf

    WEnd


    ;TODO Check MPEG Header
;~  Local $sMPEG_TagHeader = _MPEG_GetTagHeader()
;~  If $sMPEG_TagHeader <> -1 Then
;~      $ID3v2_TagFrameString &= "MPEG" & "|" & $sMPEG_TagHeader & @CRLF
;~  EndIf

    Return $sID3v2_TAGINFO & @CRLF

EndFunc   ;==>_h_ID3v2Tag_EnumerateFrameIDs

 

Edited by Allow2010
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...