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 Add the package via Composer:
composer require james-heinrich/getid3
Requires PHP 5.3+ (or 5.0.5+ for older versions). Ensure your server has at least 8MB memory (12MB recommended for full functionality).
Basic Usage Initialize the library and analyze a file:
use getID3;
$getID3 = new getID3;
$fileInfo = $getID3->analyze('path/to/file.mp3');
title, artist, bitrate, duration).Key Files to Reference
/demos/demo.basic.php: Minimal example for single-file analysis./demos/demo.browse.php: Directory scanning with recursive file handling./structure.txt: Documentation of the returned data structure (critical for understanding keys like $fileInfo['id3v2']['title']).Single-File Metadata Extraction
$getID3 = new getID3;
$fileInfo = $getID3->analyze('audio.mp3');
// Access nested data:
$title = $fileInfo['id3v2']['title'][0] ?? $fileInfo['id3v1']['title'];
$duration = $fileInfo['playtime_seconds'];
Batch Processing (Directory Scanning)
$getID3 = new getID3;
$files = glob('storage/media/*');
foreach ($files as $file) {
$fileInfo = $getID3->analyze($file);
// Store in DB or cache:
cache()->put("media:{$file}", $fileInfo);
}
demo.browse.php as a template for recursive directory traversal.Writing Tags (Modifying Files)
$getID3 = new getID3;
$getID3->tagging = true; // Enable writing
$getID3->tagging_options = ['overwrite_tags' => true];
$getID3->tagging_options['id3v2_version'] = 4;
$getID3->tagging_options['id3v2_3_flags'] = ['TALB' => 'overwrite'];
$getID3->tagging_options['id3v2_4_flags'] = ['TIT2' => 'overwrite'];
$fileInfo = $getID3->analyze('audio.mp3');
$fileInfo['id3v2']['title'] = ['New Title'];
$getID3->tagging->tag_file('audio.mp3', $fileInfo);
Error Handling
try {
$fileInfo = $getID3->analyze('corrupt.mp3');
} catch (Exception $e) {
// Log or notify user:
Log::error("getID3 Error: " . $e->getMessage());
return response()->json(['error' => 'Invalid file'], 400);
}
$fileInfo['error']).Laravel Service Provider
Bind getID3 as a singleton for dependency injection:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton('getID3', function () {
return new \getID3();
});
}
Use in controllers:
public function uploadMedia(Request $request)
{
$getID3 = app('getID3');
$fileInfo = $getID3->analyze($request->file('media')->path());
// ...
}
Caching Metadata Cache results to avoid reprocessing:
$cacheKey = 'media:metadata:' . md5($filePath);
$fileInfo = cache()->get($cacheKey);
if (!$fileInfo) {
$getID3 = new getID3;
$fileInfo = $getID3->analyze($filePath);
cache()->put($cacheKey, $fileInfo, now()->addHours(1));
}
Remote Files Download first, then analyze (as shown in the README):
$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);
Database Storage Normalize metadata for storage (e.g., flatten nested arrays):
$metadata = [
'title' => $fileInfo['id3v2']['title'][0] ?? null,
'artist' => $fileInfo['id3v2']['artist'][0] ?? null,
'duration' => $fileInfo['playtime_seconds'] ?? 0,
'bitrate' => $fileInfo['audio']['bitrate'] ?? 0,
];
Media::create($metadata);
Memory Limits
memory_limit in php.ini or process files in chunks:
ini_set('memory_limit', '256M');
demo.mysql.php as a reference for chunked processing.32-bit PHP Limitations
Nested Data Structure
$fileInfo['id3v2']['TXXX'][0]['description']).demo.browse.php to inspect your specific file’s structure. Example:
$title = data_get($fileInfo, 'id3v2.title.0') ?? data_get($fileInfo, 'id3v1.title');
Tag Writing Quirks
$getID3->tagging_options['strict'] = true;$fileInfo['warning'] (1.x) or exceptions (2.x).Remote File Handling
try {
$tempFile = tempnam(sys_get_temp_dir(), 'getid3_');
file_put_contents($tempFile, file_get_contents($remoteUrl));
$fileInfo = $getID3->analyze($tempFile);
} catch (\Exception $e) {
unlink($tempFile ?? null);
throw $e;
}
Timezone Handling
playtime_seconds may not match user expectations due to timezone offsets.$duration = Carbon::createFromTimestamp($fileInfo['playtime_seconds']);
Inspect Raw Output
Dump the full $fileInfo array to debug:
dd($fileInfo); // Laravel
// or
print_r($fileInfo); // Raw PHP
['error'], ['warning'], and nested keys like ['id3v2'], ['audio'].Common Errors
Could not seek to byte 0: File is locked or unreadable.
Fix: Close file handles or check permissions.ID3v2 header not found: File lacks tags or is corrupted.
Fix: Use fallback tags (e.g., $fileInfo['id3v1']).Unsupported format: File type not listed in the README.
Fix: Check supported formats.Performance
How can I help you explore Laravel packages today?