When I upload a well-formed MP3 file, Laravel 4 tells me it\'s not audio/mp3
but application/octet-stream
, which makes this validation fails:
It's probably because of mp3
file's mime type is audio/mpeg
or could be that, it fails to recognize the mime_content_type
and tells application/octet-stream
as a generic/fallback type. You may try this rule (example given below) instead (not tested/sure), because audio/mpeg
is the correct mime type for mp3
according to rfc3003:
array('trackfile' => 'required|mimes:audio/mpeg,mp3')
Also, you may manually check the mime
type using something like this:
$file = Input::file('upload');
if($file->getMimeType() == 'audio/mpeg') {
// valid
}
else {
// invalid
}
Update:
Specially, for mp3
files, you may also use a library getID3 which is similar to Php PECL extension id3, if you use it, you will be also able to use ID3 tag
of the file and can get information such as title
, artist
, album
, year
, genre
etc.
If you use it, you have to download it manually from the given link (getid3
) and put it in a folder inside app
, maybe app/libs/
and just put the getid3
folder from the extracted source into the libs
folder then in your composer.json
file add an entry inside classmap
of autoload
section like:
// ...
"app/tests/TestCase.php",
"app/libs/getid3"
Then run composer dump-autoload
from terminal/command prompt and you are ready to use it. To use it symply try this:
$file = Input::file('upload'); // assumed name of the file input is upload
$path = $path = $file->getRealPath();
$id3 = new getID3();
$tags = $id3->analyze($path);
if(is_array($tags) && array_key_exists('audio', $tags)) {
// valid
dd($tag['tags']);
}
For a valid mp3
file You'll get an array like this:
array (size=2) 'id3v1' =>
array (size=6)
'title' =>
array (size=1)
0 => string '46. Piya Basanti' (length=16)
'artist' =>
array (size=1)
0 => string '(Freshmaza.com)' (length=15)
'album' =>
...
If you have already installed or can install the PECL
extension using (from terminal) following command:
pear install pecl/id3
Then you may normally use
$tags = id3_get_tag( "path/to/example.mp3" );
print_r($tag);
The above example will output something similar to:
Array
(
[title] => DN-38416
[artist] => Re:\Legion
[album] => Reflections
[year] => 2004
[genre] => 19
)
Check Php manual.
Edit
Built-in validator was still considering some mp3's as application/octet-stream, wether you converted the original file with this or that software.
I finally used the MimeReader class by user Shane, which totally works. I'm still wondering why is it so hard to detect a right mime type though.
I implemented it as a validator in Laravel:
MimeReader.phps
in app/libraries/MimeReader.php
(watch the extension)Extend the Laravel Validator
(I put it in my BaseController
constructor)
Validator::extend('audio', function($attribute, $value, $parameters)
{
$allowed = array('audio/mpeg', 'application/ogg', 'audio/wave', 'audio/aiff');
$mime = new MimeReader($value->getRealPath());
return in_array($mime->get_type(), $allowed);
});
app/lang/[whatever]/validation.php
(in my case, the key is audio
)audio
as a rule ! Example: 'file' => 'required|audio'
, where file
refers to Input::file('file')
Laravel was considering audio/mpeg
files to be .mpga
and not .mp3
. I corrected it in MimeTypeExtensionGuesser.php
(in the Symfony library), along with audio/ogg
that were considered as .oga
. Maybe the audio mime-type depends on what software encoder was used.
Other method is to bypass the validator and check the mime-type directly into the controller using Input::file('upload')->getMimeType()
like Sheikh Heera said.