Read MP3 ID3 Tag Script for PHP

Created: December 12, 2014
Last Modified: July 15, 2019
((( spellific )))
Practice spelling while playing a fun word game!
Click here to play
Speech Recognition Anywhere
  • Type emails with your voice
  • Write documents with your voice
  • Control the Internet with your voice
  • Chrome Extension
Reconocimiento de voz en cualquier lugar
  • Escribe correos electrónicos con tu voz
  • Escribe documentos con tu voz
  • Controla la Internet con tu voz
  • Extensión de Chrome
Spracherkennung Allerorts
  • Geben Sie E-Mails mit Ihrer Stimme ein
  • Schreiben Sie Dokumente mit Ihrer Stimme
  • Steuern Sie das Internet mit Ihrer Stimme
  • Chrome-Erweiterung
Reconnaissance de la parole
  • Tapez des e-mails avec votre voix
  • Écrivez des documents avec votre voix
  • Contrôlez l'Inernet avec votre voix
  • Extension Chrome
Riconoscimento vocale ovunque
  • Digita e-mail con la tua voce
  • Scrivi documenti con la tua voce
  • Controlla Internet con la tua voce
  • Estensione Chrome
どこでも
音声認識
  • あなたの声で文書を書く
  • あなたの声でメールを入力してください
  • 音声でインターネットをコントロール
  • Chrome拡張機能
语音识别
无处不在
  • 用你的声音写文件
  • 用您的声音输入电子邮件
  • 用你的声音控制互联网
  • Chrome 扩展程序
語音識別
無處不在
  • 用你的聲音寫文件
  • 用您的聲音輸入電子郵件
  • 用你的聲音控制互聯網
  • Chrome 擴展程序
Subscribe to Internet Tips and Tools Feed

I created this PHP script to read the ID3 tag from MP3 files because I did not like having to install the PECL id3 library to use the id3_get_tag() function in PHP. Also many programmers have found it confusing to install the PECL id3 library. There are many forums with Fatal error: Call to undefined function: id3_get_tag() with no one giving complete instructions on how to fix the error. Also many other PHP libraries or functions on the Internet for getting mp3 id3 tags were either too big and messy, undocumented or uncommented, or incomplete (not able to read ID3v1 and ID3v2 tags) or incorrect.

Features of this PHP script:

  • Small script with comments
  • Read ID3v1, ID3v2.2, ID3v2.3 and ID3v2.4 MP3 tags
  • Creates extra custom tags with bitrate, duration etc...
  • New!! Reads tags from mp3s on local or remote servers.
With this script you can use the mp3_get_tags() function as follows:
$id3_tags = mp3_get_tags($file);
$id3_tags["title"]; // Title of mp3 file
$id3_tags["album"]; // Album Title of mp3 file
$id3_tags["artist"]; // Artist Tag
$id3_tags["year"]; // Year
$id3_tags["comment"]; // Title of mp3 file
$id3_tags["genre"]; // Genre can be text or numeric value representing genre

$id3_tags["genre_name"] = mp3_get_genre_name($id3_tags["genre"]); // Get genre name from number value

Also the following custom tags are created for convenience:

$id3_tags["id3_tag_version"]; // ID3 Tag Version; 1, 2.2, 2.3 or 2.4
$id3_tags["version"]; // MPEG Audio version ID
$id3_tags["layer"]; // MPEG Audio layer description
$id3_tags["crc"]; // 0 = Yes using CRC. 1 = No CRC
$id3_tags["bitrate"]; // Ex: 64, 128, 160, 320. CBR (Constant Bit Rate)
$id3_tags["frequency"]; // Sampling Rate Frequency
$id3_tags["filesize"]; // Size of mp3 file
$id3_tags["duration"]; // Duration of mp3 in seconds. Probably only correct for CBR not VBR
$id3_tags["formatted_time"]; // Duration of mp3 in i:s. Probably only correct for CBR not VBR

You can add more ID3 tags to the $tags_array() if you know the tag abbreviation and tag name which you can find at the following reference sites:

id3v2 tagshttp://id3.org/id3v2-00
id3v2.3 tagshttp://id3.org/id3v2.3.0#Declared_ID3v2_frames
id3v2.4 tagshttp://id3.org/id3v2.4.0-frames
id3v2.4 Structurehttp://id3.org/id3v2.4.0-structure

Click here for a list of all id3 tags and genres dlc_b

Download

Downloaded 0 times.
Please make a donation to reveal the download link.

HISTORY

3/26/2019 - Version 2.0d - Fixed "warning: undefined variable" if PHP is set to display warnings.

7/6/2017 - Version 2.0c - Bug Fix: Comments were possibly not displaying correctly for some MP3 files because ID3v2.3 tags and ID3v2.4 tags use four letter abbreviations and ID3v2.2 tags use three letter abbreviations. Instead of putting them in the same array on line 35, the array has been split in to two on line 48 depending on the ID3 tag version.

4/18/2016 - Version 2.0b - Bug Fix: If PHP is set to display warnings then get "Variable $bits undefined on line 91" warning. Fixed by declaring variable $bits on line 84. Also undefined constant warning on line 113. Fixed by commenting line 112 and 113 because they were no longer being used. It was an old way to get formatted_time.

11/30/2015 - Version 2.0a - Bug Fix: Minor bug with getting correct bitrate and duration with some MP3 files and causing a Division by zero error in PHP. Fixed with line 61 by removing 10 + before total_size in the stream_get_contents statement.

10/19/2015 - Version 2.0 - Major Changes: Now the script can read mp3s on remote servers and not just the same server the script is on. Major bug fixes: There were many bugs with getting the bitrate, duration, etc. from some versions of mp3 files. Those bugs seem to have been fixed.

12/17/2014 - Version 1.0b - Bug Fix: Forgot to remove an echo for testing on line 102

12/12/2014 - Version 1.0 - Created function mp3_get_tags()

((( spellific )))
Practice spelling while playing a fun word game!
Click here to play
Speech Recognition Anywhere
  • Type emails with your voice
  • Write documents with your voice
  • Control the Internet with your voice
  • Chrome Extension
Reconocimiento de voz en cualquier lugar
  • Escribe correos electrónicos con tu voz
  • Escribe documentos con tu voz
  • Controla la Internet con tu voz
  • Extensión de Chrome
Spracherkennung Allerorts
  • Geben Sie E-Mails mit Ihrer Stimme ein
  • Schreiben Sie Dokumente mit Ihrer Stimme
  • Steuern Sie das Internet mit Ihrer Stimme
  • Chrome-Erweiterung
Reconnaissance de la parole
  • Tapez des e-mails avec votre voix
  • Écrivez des documents avec votre voix
  • Contrôlez l'Inernet avec votre voix
  • Extension Chrome
Riconoscimento vocale ovunque
  • Digita e-mail con la tua voce
  • Scrivi documenti con la tua voce
  • Controlla Internet con la tua voce
  • Estensione Chrome
どこでも
音声認識
  • あなたの声で文書を書く
  • あなたの声でメールを入力してください
  • 音声でインターネットをコントロール
  • Chrome拡張機能
语音识别
无处不在
  • 用你的声音写文件
  • 用您的声音输入电子邮件
  • 用你的声音控制互联网
  • Chrome 扩展程序
語音識別
無處不在
  • 用你的聲音寫文件
  • 用您的聲音輸入電子郵件
  • 用你的聲音控制互聯網
  • Chrome 擴展程序
Back to www.seabreezecomputers.com
Subscribe to Internet Tips and Tools Feed        

User Comments

There are 45 comments.

Displaying first 50 comments.

1. Posted By: junior programmer - - August 28, 2015, 12:32 am
Sir, This script is working for local mp3 file, But how to get tags of remote file like "http://domain/folder/name.mp3"

Thank you.

2. Posted By: Jeff - - September 30, 2015, 1:09 pm
Hi Junior Programmer,

Sorry for the late response. I thought I had replied to you a month ago but I can't find my reply. I'm not sure what the problem could be without some kind of error. Do you get an error?

Jeff
www.seabreezecomputers.com/

3. Posted By: Jeff - - October 19, 2015, 2:11 pm
Hello junior programmer,

I have updated the script mp3_get_tags.php. It can now read mp3 tags of local and remote mp3 files.

Jeff
www.seabreezecomputers.com/tips/mp3_id3_tag.htm

4. Posted By: Mgeezy - - February 26, 2016, 1:18 am
Hello, can this work with ID3 of wav files and/or can it be easily converted?

5. Posted By: n0n0 - - April 18, 2016, 2:54 am
Hi, thanks for the script, it's really helpful, but i have a couple of problems when trying to use it :
I have two warnings telling me the variable "bits" is undefined (line 91) and same thing for the constant "time" (line 113).
Ultimately, it does not show any information on the tags of the file I'm trying to get.
Could you please help me ?=)

6. Posted By: Jeff - - April 18, 2016, 11:31 am
Hi n0n0,

Your PHP server is set to display warnings. I think I fixed the script so that it will not display those warnings. Go ahead and download it again at the website. But for the future you may want to set your PHP to not display warnings, but only errors.

One way to do this: On your server there should be a php.ini file. Edit the file and look for a line that starts with error_reporting and change it to:

error_reporting=E_ALL & ~E_NOTICE


Jeff
www.seabreezecomputers.com/tips/mp3_id3_tag.htm

7. Posted By: n0n0 - - April 18, 2016, 11:59 pm
Thanks a lot ! It works perfectly ! :D

8. Posted By: Stephan - - June 15, 2016, 8:48 am
Nice tool!
how do I call the file and parse the tags in my php-script?
I am trying it like this:

require_once('mp3_get_tags.php'); // call the script
$file="http://url.com/to/the/audio.mp3"; // get the mp3
$id3_tags1=mp3_get_tags($file); // get the tags of the file
echo $id3_tags1["title"]; // parse the title

this doesnt work. I am sure I am doing something completely wrong..=(
(i am new to php)

Thanks for any suggestions!

Cheers.


9. Posted By: Stephan - - June 15, 2016, 9:19 am
Sorry about my previous comment. It works!!!!!
I just hat to adjust my php-server settings to allow content from external urls.
This is an amazing script!

Many many thanks!!!!!!

10. Posted By: John Kiernan - - April 7, 2017, 9:05 am
This script is great, except for two things:
My MP3 file is over 1 hour (1:17:58), but the array shows it only as 17:58. Is there any tweaking I can do to get it all?

Secondly, for some reason, when I add tags on my original files, the comment field looks like this:
'comment'=> string 'composer fieldTPOSdiscnumber fieldTCONspeechTIT2title fieldTRCK01TYER2001' (length=73)
However, when I open it in audacity and then save it, it looks like this:
'comment'=> string 'this is the comment field.' (length=26)

Any thoughts on how I could tweak this as well?

Thanks in advance for the reply and especially thanks for the script itself.
-- John Kiernan

11. Posted By: Jeff - - April 10, 2017, 1:38 pm
Hi John Kiernan,

For the formatted_time to display hours try changing line 115 of the script to:

$id3_tags["formatted_time"]=gmdate("H:i:s", $id3_tags["duration"]);

I'm not sure about the comment field problem. How are you adding the comments to the mp3 file?

Jeff
www.seabreezecomputers.com/

12. Posted By: Michael - - May 11, 2017, 6:57 am
Hi John Kiernan and Jeff,

the Reason for the Comment-Problem is maybe the v2.2-Tag 'COM' for comments and the v2.3-Tag 'TCOM' for Composer. Looking for the 'COM'-Tag the script finds the '(T)COM'-Data.
Maybe the $tags_array has to be divided in a v2.2- and a v2.3-Version and these parts have to be used depending on the $id3_major_version.

Greetings from Cologne
Michael

13. Posted By: John Kiernan - - May 18, 2017, 11:45 am
Dear Jeff -
Thanks so much for the tip on the time thing, that took care of it!

On the comment glitch, I personally use either Audacity or MP3Tag (both freeware) for stamped the metadata onto the MP3 file, but I'm not 100% sure what software was/is being used by the people uploading the files.

I did some more investigating and made a discovery. Using MP3Tag, if I modified the text fields (added a few letters here and there), it didn't affect the comments. However, if I changed the "Genre" with the "Genre" dropdown, then the comments field got corrupted.

14. Posted By: Jeff - - May 18, 2017, 11:56 am
Hi Michael,

Thanks for the comment. I have made a version of the script that separates the $tags_array by version like you stated. But I have not put it up on the website yet because there has not been enough testing. If you would like to test it you can add the following lines right at line 48 of the script:


if ($id3_major_version >=3) // Version 2.0c
$tags_array=array( // first ID3v2.3 and ID3v2.4 tags
'TIT2'=> 'title', 'TALB'=> 'album', 'TPE1'=> 'artist',
'TYER'=> 'year', 'COMM'=> 'comment', 'TCON'=> 'genre', 'TLEN'=> 'length');
else
$tags_array=array( // second ID3v2.2 tags - id3.org/id3v2-00
'TT2'=> 'title', 'TAL'=> 'album', 'TP1'=> 'artist',
'TYE'=> 'year', 'COM'=> 'comment', 'TCO'=> 'genre', 'TLE'=> 'length'
);


Thanks,

Jeff
www.seabreezecomputers.com/

15. Posted By: Boris - - July 6, 2017, 4:01 am
Hi Jeff,

I really appreciate your effort, and the function works very good. But I have a problem with some characters when echoing them on my website. Characters are from latin-ext charset, ČčĆćĐđ. I have spent a few days now trying to get them to work. I tried as many encodings ID3 tags support (UTF-8, UTF-16, ISO-8859-1), versions 2.4, 2.3, 1.1, but I just can't get it to work. Sometimes I get some '~' or '?' characters, sometimes a blank space. My page is set to charset=utf-8. Can you please help me?

16. Posted By: Jeff - - July 6, 2017, 9:41 am
Hi Boris,

Sorry, I'm not sure what can be done. But you can try testing the following PHP command. Put it at the top of your PHP file:

ini_set(default_charset, "ISO-8859-1");

Jeff
www.seabreezecomputers.com/

17. Posted By: Clain Dsilva - - August 31, 2017, 9:41 am
Great Script, Is it possible to write / update Id3 tags with this script as well? if so what will be the approach?

18. Posted By: Jeff - - August 31, 2017, 6:45 pm
Hi Clain Dsliva,

Unfortunately the script is not capable of updating ID3 tags. I have not looked into doing that. It is probably possible, but I'm not sure how.

Jeff
www.seabreezecomputers.com/

19. Posted By: ciprian - - October 13, 2017, 11:16 am
Hello!
Thank you very much for this piece of artwork!
However, I have a problem. The script doesn't work with files that have spaces in the filename. Do you know if there is any solution for this? (apart from renaming the file).

Thank you very much!

20. Posted By: Jeff - - October 13, 2017, 6:57 pm
Hello ciprian,

The script works with mp3s with spaces in the filename for me just fine. Can you show an example of how you are using mp3_get_tags() with a filename with spaces? Are you getting an error? If so, what is the error?

Jeff
www.seabreezecomputers.com/

21. Posted By: Ciprian - - October 14, 2017, 4:31 am
Soory! It was my error.
Apologies, the script works perfect!

22. Posted By: Jeff - - October 14, 2017, 3:07 pm
Hi Ciprian,

Thanks for the update! I'm glad it is working!

Jeff
www.seabreezecomputers.com/

23. Posted By: Dave Menconi - - February 10, 2018, 4:47 pm
Great piece of code! Thank you very much!

How is this licensed? That is, can I use it for my personal code? For open source code I release? For commercial code?

Respectfully, I recommend that you include one of the existing licensing regimens (gnu or apache or whatever) depending on what you want so as to protect your rights and make it clear to people using it exactly what they are allowed to do. I personally like apache because it prevents other people from claiming it's not mine but allows them to use it for whatever they want. The gnu "copyleft" is more restrictive and may prevent people from using it in open source situations, depending on which one you use.

(As I understand it "copyright" by itself leaves me open to be sued by you for ANY use I might put it to. So I'm completely exposed if I use it and therefore I shouldn't use it.)

Thanks

Dave


24. Posted By: Jeff - - February 12, 2018, 12:53 am
Hi Dave,

Thank you for asking. You are right, I should put a licensing statement in the code but I don't like how big each of the statements are. I know they are relatively small, but I like to keep my source code really small.

You may freely use the code in personal or commercial projects, just please leave the attribution copyright notice and website link because I worked really hard on the code. Kind of like an Apache 2.0 License.

Jeff
www.seabreezecomputers.com/

25. Posted By: PetitsPas - - February 18, 2018, 4:12 pm
Great thanks for these functions. It was just I needed and it works fine!

26. Posted By: jedrek - - April 11, 2018, 11:17 am
Hi

with $id3_tags["artist"]=trim(substr($data, 33, 30)); i can extract artist.
How do I extract "initialKey" from the tag?

Kind Regards

27. Posted By: Jeff - - April 11, 2018, 9:18 pm
"initialKey" is not a standard id3 tag so I don't know where it would be. You could try echoing the last 128 bytes of an ID3 version 1 with
echo substr($data, -128);
And then see at what character number the initialKey starts. That's if the mp3 is using ID3v1. But that is a pretty old standard.

Most tags are written in ID3v2.3 or ID3v2.4 and support a tag called TKEY which is the initialKey. You can extract it by adding this to the $tags_array on line 50:
'TKEY'=> 'initialKey'

Jeff
www.seabreezecomputers.com/

28. Posted By: jedrek - - April 16, 2018, 6:35 pm
Thanks for reply Jeff!
Done it! Added the 'TKEY'=> 'initialKey' line..
But how do i call it to output later then?

29. Posted By: jedrek - - April 16, 2018, 6:49 pm
Never mind! Got It :)

30. Posted By: Jeff - - April 16, 2018, 11:48 pm
Hi jedrek,

You're welcome. I'm glad it is working for you.

Jeff
www.seabreezecomputers.com/

31. Posted By: jedrek - - April 18, 2018, 7:53 pm
Hi again Jeff
Getting this error. Im using the script in a loop a copule of hundreds of times. Dont really know where this is comming from..
Could it be that the script encounters a file that is too big or the amount of times its run that crashes it? any idea?

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 131071953 bytes) in mp3_get_tags.php on line 99

32. Posted By: jedrek - - April 18, 2018, 7:55 pm
line 99...
$bits .=str_pad(decbin(ord($data[$i])), 8, 0, STR_PAD_LEFT);

33. Posted By: Jeff - - April 19, 2018, 11:32 pm
Hi jedrek,

It sounds like your server is running out of memory. Or at least it has reached the limit that php is set to. A couple hundred times is a lot. You may want to setup some pagination where it only does 100 and then you change the page and it does 100 more.

Or you can try to raise the memory limit in php. In php.ini look for memory_limit and then you can raise it to something like:
memory_limit=512M

Or in your php file you can try this command:
ini_set('memory_limit', '512M');


Jeff
www.seabreezecomputers.com/

34. Posted By: Ifor - - September 26, 2018, 2:04 am
Hi, great script!

Have you looked into supporting other character encodings at all?

I noticed someone else was asking about this last year and I am in the same situation. The tags themselves are encoded properly, but the output from the script is garbled. Any ideas?

35. Posted By: Jeff - - September 26, 2018, 9:53 am
Hi Ifor,

I tried to look into other character encodings. But for some reason everything I tried did not work. If you can figure out how to make it work then please let me know.

Jeff
www.seabreezecomputers.com/

36. Posted By: Alexandra - - October 26, 2018, 3:25 am
Hi! Thanks for you module, he's awesome. But please, add support utf-8.

37. Posted By: Jeff - - October 26, 2018, 9:52 am
Hi Alexandra,

Thank you for the feedback. A few of us have been trying to get it to display extended characters correctly, but we have not been able to figure it out. It seems to have to do with lines 83 and 84:

for ($i=0; $i < strlen($content); $i++)
if($content[$i] >=" " && $content[$i] <="~") $tag_content .=$content[$i];


Jeff
www.seabreezecomputers.com/

38. Posted By: Chris - - March 15, 2019, 3:55 am
How to edit the source of mp3? I dont find the code in the PHP Sourcecode.

BR, Chris

39. Posted By: Jeff - - March 15, 2019, 10:23 am
Hi Chris,

I don't know. This script is not for editing mp3s but for reading id3 tags on mp3s.

Jeff
www.seabreezecomputers.com/

40. Posted By: Dinesh Kuniyal - - March 13, 2022, 9:13 am
how to read the album art or album image of the mp3 file??

41. Posted By: eleuname - - May 12, 2022, 5:59 am
for the cover image i've added 'APIC'=> 'cover' on line 38 (after 'TLEN'=> 'length',) and 'PIC'=> 'cover' on line 41 (after 'TLE'=> 'length',). now if i echo the output it shows a long string of characters (it's not base64 i think). how can i generate a jpeg from that? sorry i'm new to php

42. Posted By: Jeff - - May 16, 2022, 5:21 pm
Hi eleuname,

I'm not sure because I have never extracted the image from the mp3 file. Maybe it will work if you base64_encode() the string of characters. This answer from Stack Overflow may help:
https://stackoverflow.com/a/16746750

Jeff
http://www.seabreezecomputers.com/

43. Posted By: Sean - - August 31, 2022, 3:36 am
Hi,

I've added support for a couple of additional tags:


// Custom Tags
'TRCK'=> 'track',
'POPM'=> 'rating',

// Custom Tags
//'PIC'=> 'cover',
'TRK'=> 'track',
'POP'=> 'rating'


These both work, however, only the first digit of the track is returned.. ie. instead of 11 it returns 1.

The rating (Popularimeter) tag also works, but returns the first field of the frame, ie the email field, rather than the required 2nd field, containing the actual Rating data.

Any advice on how to correct for these issues ?

Thanks

44. Posted By: Jeff - - August 31, 2022, 1:28 pm
Hi Sean,

Unfortunately, I don't know the answer. I'll let you know if I find anything. Let me know if you figure it out.

Jeff
http://www.seabreezecomputers.com/

45. Posted By: kodersha - - April 18, 2023, 7:52 am
Hello! Please, add suppot utf-8.