james-heinrich/getid3
PHP library for reading and parsing audio/video file metadata. Extracts tags (ID3, APE, Lyrics3) and technical info from many formats including MP3, AAC/MP4, FLAC, Ogg (Vorbis/Opus), WAV/AIFF, AVI/ASF, MKV, and more.
Installation
composer require james-heinrich/getid3
Ensure your PHP version meets requirements (≥5.3.0 for Laravel compatibility).
Basic Usage
use getID3\getid3;
$getID3 = new getid3();
$fileInfo = $getID3->analyze('path/to/audio.mp3');
title, artist, duration).$fileInfo is a nested associative array (see /structure.txt in the package).Where to Look First
/demos/demo.basic.php to see minimal parsing./structure.txt for the returned data schema.Batch Processing
$files = Storage::files('media/audio');
$metadata = [];
foreach ($files as $file) {
$getID3 = new getid3();
$metadata[$file] = $getID3->analyze(storage_path('app/' . $file));
}
Storage facade for filesystem access.Tag Writing
$getID3->tagging->tag_file(
'path/to/file.mp3',
[
'title' => 'New Title',
'artist' => 'New Artist',
]
);
Remote Files
$tempFile = tempnam(sys_get_temp_dir(), 'getid3_');
file_put_contents($tempFile, file_get_contents('http://example.com/audio.mp3'));
$getID3 = new getid3();
$fileInfo = $getID3->analyze($tempFile);
unlink($tempFile);
Http facade or Storage::disk('s3')->download().Validation & Error Handling
try {
$fileInfo = $getID3->analyze($filePath);
if (isset($fileInfo['error'])) {
throw new \Exception('File parsing error: ' . $fileInfo['error'][0]);
}
} catch (\Exception $e) {
Log::error($e->getMessage());
}
Log::error() and return user-friendly messages.Media model:
public function updateFromFile($filePath) {
$getID3 = new getid3();
$this->metadata = $getID3->analyze($filePath);
$this->duration = $this->metadata['playtime_seconds'] ?? 0;
$this->save();
}
ScanMediaJob::dispatch($filePath)->onQueue('media');
event(new MediaMetadataExtracted($fileInfo, $filePath));
Memory Limits
memory_limit.memory_limit in php.ini or process files in chunks:
ini_set('memory_limit', '256M');
app('config')->set('memory_limit', '256M') in a service provider.File Paths & Permissions
getid3 may fail silently if paths are invalid or permissions are denied.if (!file_exists($filePath) || !is_readable($filePath)) {
throw new \RuntimeException("File not accessible: {$filePath}");
}
Corrupt Files
error or warning keys in $fileInfo:
if (isset($fileInfo['error'])) {
return response()->json(['error' => 'Invalid file'], 400);
}
Remote File Handling
Http client with retries:
try {
$response = Http::timeout(30)->get($remoteUrl);
file_put_contents($tempFile, $response->body());
} catch (\Exception $e) {
Log::error("Failed to download remote file: {$e->getMessage()}");
}
ID3v2 Tag Conflicts
getid3's built-in validation before writing:
$getID3->tagging->validate_tags([
'title' => 'Valid Title',
'artist' => 'Valid Artist',
]);
Enable Verbose Output:
$getID3->setOption('verbose', true);
Inspect Raw Data:
dd($fileInfo); // Laravel's dump and die
/structure.txt to understand missing fields.Check File Formats:
if (isset($fileInfo['mime_type'])) {
Log::debug("File MIME type: {$fileInfo['mime_type']}");
}
Custom Metadata Fields
$fileInfo['custom'] = [
'bitrate_kbps' => $fileInfo['audio']['bitrate_mode'] ?? 0,
'is_vbr' => $fileInfo['audio']['bitrate_mode'] === 'vbr',
];
Plugin System
getid3/module.tag.id3v2.php (advanced).$this->app->singleton('getid3.parser.custom', function () {
return new CustomParser();
});
Caching
$cacheKey = 'media.metadata.' . md5($filePath);
$fileInfo = Cache::remember($cacheKey, now()->addHours(1), function () use ($getID3, $filePath) {
return $getID3->analyze($filePath);
});
Laravel Service Provider
getid3 as a singleton for dependency injection:
$this->app->singleton('getid3', function () {
return new \getID3\getid3();
});
public function __construct(private getid3 $getID3) {}
$getID3->setOption('useid3v2', true); // Prefer ID3v2 over ID3v1
$getID3->setOption('skip_analyze', ['mime', 'filename']); // Skip expensive checks
$getID3->setOption('skip_analyze', ['video']);
How can I help you explore Laravel packages today?