Jump to content

ID3 UDF ID3v1 & ID3v2 MP3 Tags


joeyb1275
 Share

Recommended Posts

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

ID3v2.3TagSpec.pdf

ID3v2.4TagSpec.pdf

post-21864-0-66446400-1339116656_thumb.p

post-21864-0-87423500-1339176159_thumb.p

ID3_Example_GUI_v3.4.au3

ID3_SimpleExamples_v3.4.au3

ID3_v3.4.au3

Edited by joeyb1275
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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:

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: 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 Program

AutoIt_Icon_small.pngUDFs: 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
 
AutoIt_Icon_small.pngExamples: 
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 AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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:

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

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