How can I extract metadata from MP3 using PHP?

1k views Asked by At

I have got a PHP script that searches the current directory for MP3 files. I want to be able to get the metadata on the file and assign that to variables.

I am currently trying to use the Mp3Info library but it's complaining when I create an instance of it with a line that says

Undefined type 'wapmorgan\Mp3Info\Mp3Info'

How can I get this working?

<?php
use wapmorgan\Mp3Info\Mp3Info;

/* Scan dir for files */
$files = glob("*.mp3"); // all files ending with mp3.

/* sort files according to their upload time. */
usort($files, 
  function ($a, $b) {
    return filemtime($a) < filemtime($b);
  }
);

for ($i = 0; $i < sizeof($files); $i++) {
  $trackName = basename($files[$i]);
  // echo $trackName . "** **";

  // create path string for the current file
  $songPath = './';
  $songPath .= $trackName;
  // echo $songPath;

  $track = new Mp3Info($songPath, true); // MY PROBLEM SEEMS TO BE APPEARING HERE

  echo $track;

  /* Insert data into db after creating variables here */
}
1

There are 1 answers

3
AmigoJack On

Welcome to PHP.

Error/warning/info messages

Just like other scripting/programming languages in PHP you almost always also get a line number to seek to instead of a textual message only, so you don't have to guess where the issue occured. In the case of

<?php

use wapmorgan\Mp3Info\Mp3Info;
new Mp3Info( 'music.mp3' );

...you get a very distinctive message:

Fatal error: Uncaught Error: Class 'wapmorgan\Mp3Info\Mp3Info' not found in example.php:4
Stack trace:
#0 {main}
  thrown in example.php on line 4

Do you spot your script filename, followed by a colon and the number 4? Both times? It's the line number. The message even says so in the stack trace. Of course: read error/warning/info messages in its original and not interpreted by your web browser as HTML. In other words: press Ctrl+U to see more linebreaks.

See more at PHP Manual > Language Reference > Errors: Basics.

(Source) File inclusion

Just like other scripting/programming languages external declarations aren't magically included into your code - you have to tell so by via include or require. You haven't done so, which is why Mp3Info cannot be resolved by PHP. The correct code would be:

<?php

require( './Mp3Info.php' );  // Include _Mp3Info_'s source file with its declarations
use wapmorgan\Mp3Info\Mp3Info;
new Mp3Info( './music.mp3' );

Now there's no error anymore in your code. Of course: Mp3Info can still cause/throw errors, f.e. when the given file doesn't exist.

Data types

Just like other scripting/programming languages PHP knows different data types, f.e. string, array and object. Likewise you cannot use every possible combination of data type and function. Mp3Info's constructor will not return a string - it will return an object. Creating an instance of a class will always result in an object.

echo is meant for data types that can be converted into string (such as int and float and boolean). But an object cannot be converted into string, so using echo $object will yield an error. You need to look for something else:

  • use print_r() to print all properties of the object at once, or
  • use one of the object's property, because that can be converted to string and then used in echo (or print).

Complete working example

<?php

require( './Mp3Info.php' );  // Wherever that source file resides
use wapmorgan\Mp3Info\Mp3Info;

$obj= new Mp3Info( './music.mp3', TRUE );  // Also parse tag frames

// Print all object properties at once. Don't interpret as HTML.
header( 'Content-Type: text/plain' );
print_r( $obj );

// Print one chosen property's value only.
print( $obj-> tags['song'] );

Mp3Info

That's a questionable class/library - just search for need to to see what it misses. It will also only expect ID3v1 and ID3v2 tags in an MP3 files - not in other files and no other metadata as well. Which is by far not complete: see ID3 Parser and Editor and Where is the ID3v2 documentation?. Although not being perfect either, I recommend trying getID3, which supports much more in any way.