ac/media-info-bundle
Symfony bundle wrapping the mediainfo CLI to extract multimedia metadata. Configure the mediainfo binary path, then scan files to get a normalized, structured PHP array (keys lowercased). Includes a console command to export scan results (e.g., YAML).
Installation:
composer require ac/media-info-bundle:~1.2.0
config/bundles.php (Laravel) or AppKernel.php (Symfony):
AC\MediaInfoBundle\ACMediaInfoBundle::class,
mediainfo executable path in .env or config/services.php:
'mediainfo.path' => env('MEDIAINFO_PATH', '/usr/bin/mediainfo'),
First Use Case:
use AC\MediaInfoBundle\MediaInfo;
public function __construct(private MediaInfo $mediaInfo) {}
$metadata = $mediaInfo->scan(storage_path('videos/example.mp4'));
config/services.php or .env for the mediainfo path.MediaInfo.$metadata['file']['general']['title']).Metadata Extraction:
$metadata = $mediaInfo->scan($filePath);
$title = $metadata['file']['general']['title'] ?? null;
foreach (Storage::files('videos') as $file) {
$metadata = $mediaInfo->scan(storage_path($file->path()));
// Process metadata (e.g., validate, store in DB)
}
Integration with Laravel Features:
Illuminate\Http\Request to extract metadata on upload:
public function store(Request $request) {
$file = $request->file('video');
$metadata = $mediaInfo->scan($file->path());
// Save metadata to DB or validate before storage
}
use Illuminate\Console\Command;
class ExtractMetadata extends Command {
protected $signature = 'media:extract {path}';
public function handle(MediaInfo $mediaInfo) {
$metadata = $mediaInfo->scan($this->argument('path'));
$this->info(json_encode($metadata, JSON_PRETTY_PRINT));
}
}
Normalized Data Handling:
array_walk_recursive):
$flatMetadata = [];
array_walk_recursive($metadata, function($value, $key) use (&$flatMetadata) {
$flatMetadata[$key] = $value;
});
collect($metadata['file']['general'])->filter()->toArray();
$cacheKey = 'mediainfo:' . md5($filePath);
$metadata = Cache::remember($cacheKey, now()->addHours(1), function() use ($mediaInfo, $filePath) {
return $mediaInfo->scan($filePath);
});
$duration = $metadata['file']['general']['duration'] ?? 0;
if ($duration > 3600) { // >1 hour
throw new \Exception('Video too long');
}
Executable Path:
mediainfo not found. The bundle throws exceptions if the path is incorrect or the executable is missing.config/services.php or .env and ensure mediainfo is installed system-wide (sudo apt install mediainfo on Ubuntu)./usr/bin/mediainfo --version
Nested Array Structure:
count_of_stream may contain arrays (e.g., ['count_of_stream'] => ['0' => '2']), leading to confusion.$count = $metadata['file']['general']['count_of_stream'][0] ?? null;
Performance:
Character Encoding:
é, ü) may cause issues.mediainfo output is UTF-8 encoded or decode the response:
mb_convert_encoding($metadata, 'UTF-8');
mediainfo output to debug:
$rawOutput = $mediaInfo->getRawOutput($filePath);
\Log::debug('MediaInfo Raw Output:', ['output' => $rawOutput]);
mediainfo CLI:
mediainfo --Output="JSON" /path/to/file.mp4
try {
$metadata = $mediaInfo->scan($filePath);
} catch (\RuntimeException $e) {
\Log::error('MediaInfo scan failed: ' . $e->getMessage());
return response()->json(['error' => 'Invalid media file'], 400);
}
Custom Output Formats:
scan method in a decorator:
class CustomMediaInfo extends MediaInfo {
public function scan($filePath) {
$raw = parent::scan($filePath);
return json_decode($raw, true);
}
}
config/services.php:
'mediainfo' => \App\Services\CustomMediaInfo::class,
Add Metadata Transformers:
class VideoMetadataTransformer {
public function transform(array $metadata): VideoMetadata {
return new VideoMetadata(
$metadata['file']['general']['title'] ?? null,
$metadata['file']['general']['duration'] ?? 0
);
}
}
Support for Multiple mediainfo Versions:
version key in the response:
if ($metadata['version'] >= '0.8.0') {
// New format handling
}
How can I help you explore Laravel packages today?