Closed GoogleCodeExporter closed 8 years ago
The error message you received comes from this block of code:
{{{
if (!file_exists($filename) || !is_readable($filename) ||
($fd = fopen($filename, $mode)) === false) {
require_once('Zend/Io/Exception.php');
throw new Zend_Io_Exception
('Unable to open file for reading: ' . $filename);
}
}}}
Which means that a) file_exists returns false, or b) is_readable returns false,
or c)
fopen with $mode (which by default is 'rb') returns false. Could you make a
sample
script that executes each one of those functions for your file that throws the
exception with Id3v2 class and let me know what they return for you.
Can you reproduce the error and is it always the same file that is causing you
the
trouble?
Can you also elaborate the second problem about the class not recognizing
'_data'
field. What field? Which class? How does the class crash? Can you post an
extract of
the trace.
Original comment by svollbehr
on 7 Apr 2010 at 8:16
[deleted comment]
[deleted comment]
The script is attached. Ideally I want to loop through entire directories
(which is
how my script is currently setup with the getId3 class), but I've just uploaded
the
bare-minimum to reproduce the issues mentioned above. The error is in the
constructor anyway, so anything after that doesn't really make any difference.
The files referred to in the script are available for download on my site at:
http://datacodesolutions.com/download.php
At one point, in trying to troubleshoot the "unknown _data" error, I actually
opened
up the .mp3 file in notepad++ and deleted one of the fields(I think it was UFID
-
can't remember for sure though) and got it to work. Obviously though, any
script
like this needs to be able to handle any type of error without fatally
crashing.
I also downloaded a utility (Mp3tag v2.46a) which allows users to update
metadata and
shows when the tags are bad. It shows all the of the files referred to in the
script
as being legitimate ID3v2.3 metadata tags
Original comment by mattcdav...@gmail.com
on 8 Apr 2010 at 1:07
Attachments:
I have debugged your files a bit. Couple of things noted:
//$filename =
('C:\wamp\www\ratio_blog\local\CodeRepository\debug\Light_of_Salvation.mp3');
//Fails with 'Unable to open file for reading'
This is probably due to the fact the file is called 02_Light_of_Salvation.mp3,
works
when the filename is fixed.
I couldn't reproduce any of the other errors with any of the files. I executed
your
PHP script and it returned with the following error message for all files:
Fatal error: Uncaught exception 'Zend_Media_Id3_Exception' with message 'File does
not contain ID3v2 tag'
Which seems quite appropriate after taking a quick look at the files with Hex
editor.
The files seem to have some garbage before the ID3 header:
downloads/01_Work.mp3ID3....
downloads/02_Light_Of_Salvation.mp3ID3...
According to the ID3 specification the 'ID3' (the start of the header) should be
located at the very beginning of the file. How can one otherwise determine
where to
beging to look for it and for how deep into the file to look. Here's a snippet
from
the standard.
The ID3v2 tag header, which should be the first information in the
file, is 10 bytes as follows:
ID3v2/file identifier "ID3"
ID3v2 version $03 00
ID3v2 flags %abc00000
ID3v2 size 4 * %0xxxxxxx
etc..
However, it's quite funny that Windows does actually recognize the ID3 tag
regardless.
Anyways, I fixed the files by removing that extra garbage from the beginning of
the
file and I was able to read all the files. I was also able to reproduce the
Unknown
field: _data exception you got. Here are the results.
01_Work.mp3 Works ok and contains the following frames: TENC, PRIV, PRIV, PRIV,
PRIV, PRIV, PRIV, PRIV, TPUB, COMM, COMM, TIT2, TPE1, TPE2, TCOM, TALB, TRCK,
TPOS,
TYER, TCON
01_Prologue.mp3 Produced Unknown field: _data due to a bug in the UFID class. After
a quick fix it works. File contains the following frames: TALB, TPE1, TPE2,
COMM,
TPOS, TENC, TCON, POPM, TIT2, TRCK, UFID, TYER.
02_Light_of_Salvation.mp3 Works okay, after changing the file name. File contains
the following frames: TALB, TPE1, TPE2, COMM, TPOS, TCON, TIT2, TRCK, TYER.
I have committed the fix for UFID into subversion and will also further think
about
what to do with the file name before the ID3 tag. Thanks for reporting! Try the
new
code from subversion!
Original comment by svollbehr
on 8 Apr 2010 at 2:45
Tried the updated code with the file that was producing "Unknown Data" issue
and it
works great - Thanks!.
I do have a couple questions:
1. Is there some way to check that the the files' metadata is not corrupted
(and
perhaps fix on the fly) before instantiating the object. Perhaps some regular
expression that checks whether "ID3" are the first the characters and, if not,
extracts all characters up to the pattern "ID3"? This way my entire script
won't
crash if I encounter a bad file.
2. This is probably more along the lines of a feature request, but the current
program I'm using ( getId3 from http://getid3.sourceforge.net/ ) outputs the
following fields for each file:
$ThisFileInfo['avdataoffset']
$ThisFileInfo['avdataend']
Using this information I'm able to determine the length (in seconds) of the
file with
a simple formula. This is critical for me because I'm using the script to
create a
feed for itunesU and the length of the file is one of the fields that I need to
fill
out.
Thanks again for the fix!
Original comment by mattcdav...@gmail.com
on 8 Apr 2010 at 4:26
Yes, for the first question you can just instantiate Zend_Io_FileReader and
check if
read(3) == 'ID3' (if yes, it contains an Id3v2 tag). If it is successfull you
can
just set the reader offset back to 0 and use that instance to initialize the
Id3v2 class.
$reader = new Zend_Io_FileReader('filename');
if ($reader->read(3) == 'ID3) {
// contains ID3v2
$reader->offset = 0;
$id3 = new Zend_Media_Id3v2($reader);
// ...
}
You could also try to instantiate the class within a try-catch block:
try {
$id3 = new Zend_Media_Id3v2('filename');
// ...
} catch (Zend_Media_Exception $e) {
// skip file, there is no tag
}
Unfortunately the format of the ID3 tag cannot be verified. All unknown frames
will
be parsed properly though (unless there's a bug somewhere).
As for the second question you cannot just determine the play length based on
the
number of audio bytes a file contains. The bitrate varies, frame size varies,
file
could be CBR/VBR. So I don't think any simple formula would do it. However, I
think
the feature you are longing is already implemented in Zend_Media_Mpeg_Abs (ABS
as in
Audio Bit Stream). That is a class that actually parses the MPEG audio
information
and reads the MPEG frame information. You can use that info for example to
calculate
the exact (or estimated) length of the file. Instantiate that class using the
file
name (or the reader object) as the parameter and then call the
getFormattedLengthEstimate method to get the file length estimate (quicker than
reading the exact length). If you need the exact length you can go through the
whole
file by calling getFormattedLength method.
Original comment by svollbehr
on 8 Apr 2010 at 9:21
Thanks dude - you rock! Everything's running great - including the method you
suggested for getting the file length. I'm going to switch to your library for
all my
scripts that utilize mp3 metadata.
-matt
Original comment by mattcdav...@gmail.com
on 9 Apr 2010 at 3:56
Anytime..
Original comment by svollbehr
on 9 Apr 2010 at 7:32
Original comment by svollbehr
on 6 Jun 2010 at 4:30
Original issue reported on code.google.com by
mattcdav...@gmail.com
on 7 Apr 2010 at 5:52