Jump to content

This site uses cookies. By continuing to browse the site you are agreeing to our use of cookies. Find out more here. X
X


Photo

ID3 UDF ID3v1 & ID3v2 MP3 Tags


  • Please log in to reply
169 replies to this topic

#1 joeyb1275

joeyb1275

    Wayfarer

  • Active Members
  • Pip
  • 61 posts

Posted 09 April 2007 - 11:53 PM

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:

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 ID3v2

Simple 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

Attached Thumbnails

  • Screenshot_v3.2.png
  • Screenshot_v3.3.png

Attached Files


Edited by joeyb1275, 11 October 2013 - 01:45 PM.








#2 quaizywabbit

quaizywabbit

    picked the wrong day to quit sniffin' glue

  • Active Members
  • PipPipPipPipPipPip
  • 494 posts

Posted 10 April 2007 - 12:39 AM

nice job!!
Do more with pre-existing apps!ANYGUIv2.8

#3 CFire

CFire

    Seeker

  • Active Members
  • 20 posts

Posted 10 April 2007 - 04:40 AM

Very Nice! works great!
Scripts and UDF'sWMMedia - UDF full of functions to Control Media Output.

#4 joeyb1275

joeyb1275

    Wayfarer

  • Active Members
  • Pip
  • 61 posts

Posted 12 April 2007 - 03:07 AM

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.

#5 WeMartiansAreFriendly

WeMartiansAreFriendly

    Where's the kaboom?

  • Active Members
  • PipPipPipPipPipPip
  • 1,245 posts

Posted 12 April 2007 - 03:58 AM

nice job.. i've beeing looking into id tags editing/reading for a while..
Posted ImageDon't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()

#6 MrCreatoR

MrCreatoR

    Must AutoIt!

  • MVPs
  • 3,251 posts

Posted 12 April 2007 - 01:04 PM

joyeb1275

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

Where 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 :shocked:
Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

Posted Image AutoIt Russian CommunityPosted Image 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 ProgramPosted Image UDFs: 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 UDFPosted Image 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 DemoLike the examples/UDFs? Please rate the topic (up-right corner of the post header: Rating Posted Image)* === My topics === *

==========================================================Posted Image==========================================================

AutoIt is simple, subtle, elegant. © AutoIt Team


#7 joeyb1275

joeyb1275

    Wayfarer

  • Active Members
  • Pip
  • 61 posts

Posted 12 April 2007 - 04:11 PM

joyeb1275

Where 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 :shocked:



I came across these dlls in the first post of a topic
http://www.autoitscript.com/forum/index.ph...p;hl=id3com.dll
I 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 by joeyb1275, 12 April 2007 - 04:12 PM.


#8 Dave in PNG

Dave in PNG

    Wayfarer

  • Active Members
  • Pip
  • 50 posts

Posted 18 April 2007 - 05:07 AM

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?

#9 joeyb1275

joeyb1275

    Wayfarer

  • Active Members
  • Pip
  • 61 posts

Posted 18 April 2007 - 10:44 AM

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 :shocked:

#10 Dave in PNG

Dave in PNG

    Wayfarer

  • Active Members
  • Pip
  • 50 posts

Posted 19 April 2007 - 07:37 PM

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

#11 joeyb1275

joeyb1275

    Wayfarer

  • Active Members
  • Pip
  • 61 posts

Posted 21 April 2007 - 03:57 PM

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 by joeyb1275, 21 April 2007 - 07:34 PM.


#12 joeyb1275

joeyb1275

    Wayfarer

  • Active Members
  • Pip
  • 61 posts

Posted 22 April 2007 - 03:04 PM

Posted latest version...

Added support for ID3v2.2 and fix a bug for ID3v2 tag reading.

Edited by joeyb1275, 22 April 2007 - 03:12 PM.


#13 Dave in PNG

Dave in PNG

    Wayfarer

  • Active Members
  • Pip
  • 50 posts

Posted 22 April 2007 - 10:09 PM

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

#14 Dave in PNG

Dave in PNG

    Wayfarer

  • Active Members
  • Pip
  • 50 posts

Posted 23 April 2007 - 04:03 AM

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. :shocked:

Oh well. Thanks again.

Dave

#15 joeyb1275

joeyb1275

    Wayfarer

  • Active Members
  • Pip
  • 61 posts

Posted 23 April 2007 - 10:08 AM

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. :shocked:

Oh well. Thanks again.

Dave



That 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 fix
also when $sFilter is not -1 the returned array will only be the items that are in $sFilter.

Edited by joeyb1275, 23 April 2007 - 11:41 AM.


#16 Dave in PNG

Dave in PNG

    Wayfarer

  • Active Members
  • Pip
  • 50 posts

Posted 23 April 2007 - 07:10 PM

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

#17 joeyb1275

joeyb1275

    Wayfarer

  • Active Members
  • Pip
  • 61 posts

Posted 24 April 2007 - 12:42 AM

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


It 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.

#18 Dave in PNG

Dave in PNG

    Wayfarer

  • Active Members
  • Pip
  • 50 posts

Posted 24 April 2007 - 01:09 AM

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

#19 sonicxtacy02

sonicxtacy02

    Wayfarer

  • Active Members
  • Pip
  • 65 posts

Posted 26 April 2007 - 02:17 PM

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.

#20 joeyb1275

joeyb1275

    Wayfarer

  • Active Members
  • Pip
  • 61 posts

Posted 26 April 2007 - 05:34 PM

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.




5 user(s) are reading this topic

0 members, 5 guests, 0 anonymous users