joeyb1275 Posted April 9, 2007 Posted April 9, 2007 (edited) ID3.au3 UDF Description: Reads ID3v1.0, ID3v1.1, ID3v1.1+, ID3v2.2, ID3v2.3, ID3v2.4, APEv2 and MPEG frame header Writes ID3v1.1, ID3v2.3, ID3v2.4 Latest Version v3.4 20120610 AutoIt Version Required: 23rd December, 2011 - v3.3.8.0 of AutoIt ID3 functions only works with .mp3 files Notes: More info on the ID3 format can be found at http://www.id3.org/Developer_Information and http://en.wikipedia.org/wiki/ID3 More info on the APE tag format can be found at http://wiki.hydrogenaudio.org/index.php?title=APEv2_specification If you only care about getting the basic info ie. Album, Artist, Track and Song Title then look into using Udf: Get Extended FIle Properties More ID3 implementations http://www.id3.org/Implementations Changes in latest version (see files for all changes):ID3_v3.4.au3 (06/10/2012) Added resetting of all global ID3 variables in _ID3ReadTag() to make sure they are set back to the default values changed _ID3WriteTag() to determine what tags have been read and to only write back those version if $iTagVersion=-1 edited _ID3WriteTag() comments added $iReturnTypeFlag to _ID3GetTagField() inputs for ID3v2 functions fixed _ID3GetTagField() so that @extended is set to the Number of frames that exist with same $sFrameIDRequest fixed _h_ID3v2_EncodeStringToBinary() variable typo ($FrameData should be $bFrameData), thanks BrewManNH! ID3_Example_GUI_v3.4.au3 (06/10/2012) changed all _ID3v1Field_GetString and _ID3v2Field_GetString to _ID3GetTagField ID3_SimpleExamples_v3.4.au3 (06/10/2012) I have realized that the GUI example has become overly complex, so I have added this file to help show how I intended ID3.au3 to be used. Simple Read Tag Example: $Filename = FileOpenDialog ( "Select Mp3 File", "", "Muisc (*.mp3)") $sTagInfo = _ID3ReadTag($Filename) MsgBox(0,"TagInfo",$sTagInfo) MsgBox(0,"ID3v1 Title",_ID3GetTagField("Title")) ;Title from ID3v1 MsgBox(0,"ID3v2 Title",_ID3GetTagField("TIT2")) ;Title from ID3v2Simple Write Tag Example: $Filename = FileOpenDialog( "Select Mp3 File", "", "Muisc (*.mp3)") $sTagInfo = _ID3ReadTag($Filename) _ID3SetTagField("COMM","TEST COMMENT - ID3v2 Comment Tag") _ID3WriteTag($Filename)Latest Version v3.4 20120610 ID3v2.3TagSpec.pdfID3v2.4TagSpec.pdfID3_Example_GUI_v3.4.au3ID3_SimpleExamples_v3.4.au3ID3_v3.4.au3 Edited October 11, 2013 by joeyb1275 argumentum and TheSaint 1 1
quaizywabbit Posted April 10, 2007 Posted April 10, 2007 nice job!! [u]Do more with pre-existing apps![/u]ANYGUIv2.8
CFire Posted April 10, 2007 Posted April 10, 2007 Very Nice! works great! [u]Scripts and UDF's[/u]WMMedia - UDF full of functions to Control Media Output.
joeyb1275 Posted April 12, 2007 Author Posted April 12, 2007 After searching differant ways to read the ID3 tags on an mp3 file I came across a few dlls that might help, cddbcontrol.dll id3com.dll UltraID3Lib.dll I was wondering if anybody had any luck using these to read/write the tag information. The most promising looked like the ID3Tag object in id3com.dll, but I couldn't get to far with it. Please let me know if there is anything better out there for reading and writing tags, for all the tag fields.
WeMartiansAreFriendly Posted April 12, 2007 Posted April 12, 2007 nice job.. i've beeing looking into id tags editing/reading for a while.. Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()
MrCreatoR Posted April 12, 2007 Posted April 12, 2007 joyeb1275After searching differant ways to read the ID3 tags on an mp3 file I came across a few dlls that might help,cddbcontrol.dllid3com.dllUltraID3Lib.dllWhere you find two last dll's? can you show the link please? i use the first one (cddbcontrol.dll), and it's help me to write/read id3 tags, but sometimes it's make my app to crash  Spoiler Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1  AutoIt Russian Community My Work... Spoiler Projects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize ProgramUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF Examples: ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating ) * === My topics === * ================================================== ==================================================    AutoIt is simple, subtle, elegant. © AutoIt Team
joeyb1275 Posted April 12, 2007 Author Posted April 12, 2007 (edited) joyeb1275Where you find two last dll's? can you show the link please? i use the first one (cddbcontrol.dll), and it's help me to write/read id3 tags, but sometimes it's make my app to crash I came across these dlls in the first post of a topic http://www.autoitscript.com/forum/index.ph...p;hl=id3com.dllI then googled the names of the dlls and found a bunch of sites where I could download them.I didn't have much luck with them. I really want the ability to extract the album art in the ID3V2 Tags and I could not see how that could be done with any one of those dlls.Good Luck! Edited April 12, 2007 by joeyb1275
Dave in PNG Posted April 18, 2007 Posted April 18, 2007 If I need all of the information, this code appears to open and close the MP3 file for every tag I want, which can be quite slow. Any chance on writing a function to return an array of all of the tags with just one open/close?
joeyb1275 Posted April 18, 2007 Author Posted April 18, 2007 If I need all of the information, this code appears to open and close the MP3 file for every tag I want, which can be quite slow. Any chance on writing a function to return an array of all of the tags with just one open/close? Yeah that would be no problem. Is it really that slow? I've actually read thousands of mp3s in a loop and it didn't seem to take that long. The reason it is built this way is so that if you only want one tag field, I didn't want to have to wait for all the fields to be read. When I first wrote this it did a single opening and closing of the file as you suggested but then when I started using it and adding more fields it would take a long time to get the album art if thats all I wanted. So in an attempt to optimize the speed for a sigle tag quary I made it open and close the file for each tag quary. I think I'll write a seperate function to retrieve all the tags and return them in an array. I'm also trying to write my own FileRead functions from ReadFile() in Kernel32.dll to optimize the way I have to offset and scan into a file. It might be a little while before I can write a function to read all the tags to an array so I welcome you to hack apart my code and see if you can create a ..... _ID3ReadToArray() perhaps? Maybe as an input there could be a $sfilter to get the tags that the user wants like if $sfilter = "Artist|Album|Title|Track" then the returned array will be have 5 elements [0] = 4 [1] = Artist [2] = Album [3] = Title [4] = Track or if $sfilter = -1 it would get all the tag fields. And maybe still have an input for what version id3tag to get with the ability to get both versions. So I'm thinking it would look like.. Func _ID3ReadToArray($Filename, $sfilter = -1, $Version = 2) ... EndFunc What do you think? Would a function like this be useful to you? Now that I've thought about it some more I might add it sooner then later
Dave in PNG Posted April 19, 2007 Posted April 19, 2007 Yes, it is slow when you are grabbing all of the tags. You suggested function would be a great addition as long as it minimized file IO. Do you think there might be able possibility of reading a few more of the tags like bitrate, channels, KPS, etc.? Thanks. Dave
joeyb1275 Posted April 21, 2007 Author Posted April 21, 2007 (edited) Yes, it is slow when you are grabbing all of the tags. You suggested function would be a great addition as long as it minimized file IO. Do you think there might be able possibility of reading a few more of the tags like bitrate, channels, KPS, etc.? Thanks. Dave bitrate, channels, KPS... that information is in the MPEG Header, I'm still working on a reader for that. I changed my entire code for ID3.au3 it should be better only one fileopen and more frame ids are included you only need to use _ID3TagToArray() and if you don't want all the frames just set the $sFilter to the FrameIds of the ones you want. I included a function to delete any files created by ID3.au3 like the album art and now the lyrics are saved to a text file. I minimized the file includes and i think the code a bit more readable. When I first started this project I was still a new user of AutoIt, so my code was not the greatest but it worked. Here is an example script #include-once #include <ID3.au3> #include <Array.au3> $Filename = FileOpenDialog ( "Select Mp3 File", "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", "Music (*.mp3)") $sFilter = "TIT2|TALB|TPE1|TYER|APIC" $ID3v2Tag = _ID3TagToArray($Filename,2,$sFilter) ;~ $ID3v2Tag = _ID3TagToArray($Filename,2) _ArrayDisplay($ID3v2Tag,"$ID3v2Tag") $ID3v1Tag = _ID3TagToArray($Filename,1) _ArrayDisplay($ID3v1Tag,"$ID3v1Tag") _ID3DeleteFiles() See first post for latest version . The other files that were originally posted are not needed! Let me know if you have problems with it. Edited April 21, 2007 by joeyb1275
joeyb1275 Posted April 22, 2007 Author Posted April 22, 2007 (edited) Posted latest version... Added support for ID3v2.2 and fix a bug for ID3v2 tag reading. Edited April 22, 2007 by joeyb1275
Dave in PNG Posted April 22, 2007 Posted April 22, 2007 Thanks for working on this. I'll do some benchmarking, change the code to use the new code and repeat my tests. I'll report when I'm done. Looking forward to the new tags. In looking at the spec for ID3, I am amazed at the flexability but at the cost of complexity. You are doing good work. Dave
Dave in PNG Posted April 23, 2007 Posted April 23, 2007 I created a fileset of 129 MP3 files (4.7 GB) and ran the older code and the newer code. I also ran it against the same files on a hard drive and on a DVD. The new code was 7.8% faster from the DVD and 16% faster from a hard drive. Well worth the effort I think In search of more speed( ) I looked at your code. I started with the V1 code as it's the simplest. You are doing one FileOpen(), several FileRead() calls, then a FileClose. I wondered whether one FileOpen, one FileRead() for the entire 128 bytes of the tag, then a series of in-memory BinaryMid() calls (beta only) then a FileClose() would be faster. I rewrote the _ReadID3V1() function like this and guess what? It's about the same speed. Oh well. Thanks again. Dave
joeyb1275 Posted April 23, 2007 Author Posted April 23, 2007 (edited) I created a fileset of 129 MP3 files (4.7 GB) and ran the older code and the newer code. I also ran it against the same files on a hard drive and on a DVD.The new code was 7.8% faster from the DVD and 16% faster from a hard drive. Well worth the effort I thinkIn search of more speed( ) I looked at your code. I started with the V1 code as it's the simplest. You are doing one FileOpen(), several FileRead() calls, then a FileClose. I wondered whether one FileOpen, one FileRead() for the entire 128 bytes of the tag, then a series of in-memory BinaryMid() calls (beta only) then a FileClose() would be faster. I rewrote the _ReadID3V1() function like this and guess what? It's about the same speed. Oh well. Thanks again.DaveThat was a good idea but its too bad it was still the same speed. I have another idea, I found a UDF for the kernel32.dll file reading functions and there is a function called _APIFileSetPos( ByRef $hFile, ByRef $nPos ) this sets the position of the file pointer. So what I'm thinking is for _ReadID3V1() instead of FileRead($hfile,FileGetSize($Filename)-128) to get to the right position in the file maybe trying _APIFileSetPos( ByRef $hFile, ByRef $nPos ) . I'm not sure there will be a big differance, but if you really want speed, I think its worth it. Nice job with the speed testing! I will try the same.I don't think I want to include APIFileReadWrite.au3. I'd like to keep it simple. I updated ID3.au3 again...added a minor bug fixalso when $sFilter is not -1 the returned array will only be the items that are in $sFilter. Edited April 23, 2007 by joeyb1275
Dave in PNG Posted April 23, 2007 Posted April 23, 2007 I agree with you about including other code, especially when it may or may not make a difference. Your new filter code addition is very timely for me. I will use it tomorrow. Does it return the tags in the order it was specified in the filter? Dave
joeyb1275 Posted April 24, 2007 Author Posted April 24, 2007 I agree with you about including other code, especially when it may or may not make a difference.Your new filter code addition is very timely for me. I will use it tomorrow. Does it return the tags in the order it was specified in the filter?DaveIt returns the tags in the order they are found in the file. I think doing some kind of array sorting might slow things down. I would like to return the tags in the order that the user requests them, so I'll give it some more thought.
Dave in PNG Posted April 24, 2007 Posted April 24, 2007 Array sorting (as implemented in AutoIt) is rather slow. If your code would return the tags in the order they were specified, it would make for a predictable result.Dave
sonicxtacy02 Posted April 26, 2007 Posted April 26, 2007 forgive me for bein stupid here but how do i use this UDF. i used include on id3.au3 and placed the .au3 in my include folder but the only thing i get back when i define $filename is the $frame msgbox. Nowhere do i see the array and no files are saved anywhere.
joeyb1275 Posted April 26, 2007 Author Posted April 26, 2007 forgive me for bein stupid here but how do i use this UDF. i used include on id3.au3 and placed the .au3 in my include folder but the only thing i get back when i define $filename is the $frame msgbox. Nowhere do i see the array and no files are saved anywhere.What is the string that defines $filename? It should have the fullpath to the .mp3. What is the line of code where you call $ID3v2Tag = _ID3TagToArray()? Are you using the latest id3.au3(see first post)? I did a search for Msgbox(0,"$frame" in my code and it did not find that string so I'm not sure where that msgbox came from.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now