Skip to content

Instantly share code, notes, and snippets.

@neverything
Last active October 18, 2024 08:04
Show Gist options
  • Save neverything/c9aefae00b38f8a4ba48f16f089fe9f3 to your computer and use it in GitHub Desktop.
Save neverything/c9aefae00b38f8a4ba48f16f089fe9f3 to your computer and use it in GitHub Desktop.
Set Image and Video dimension for the Spatie Laravel Media Library as custom properties: https://silvanhagen.com/writing/image-and-video-dimensions-laravel-media-library
<?php
namespace App\Actions\Media;
use Exception;
use FFMpeg\FFProbe;
use Illuminate\Support\Facades\Log;
use Spatie\Image\Image;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
class UpdateMediaInfoAction
{
public function execute(Media $media): array
{
if (! $this->isImage($media) && ! $this->isVideo($media)) {
Log::info("Skipping media id: {$media->id} as it is not an image or video");
return ['status' => 'skipped'];
}
Log::info("Attempting to update media info for id: {$media->id}", [
'mime_type' => $media->mime_type,
'file_name' => $media->file_name,
]);
if ($media->hasCustomProperty('dimensions')) {
Log::info("Media info already updated for id: {$media->id}");
return ['status' => 'already_updated'];
}
try {
$properties = $this->getMediaProperties($media);
$this->updateMediaProperties($media, $properties);
Log::info("Successfully updated media info for id: {$media->id}", $properties);
return ['status' => 'updated', 'properties' => $properties];
} catch (Exception $e) {
Log::error("Failed to update media info for media id: {$media->id}", [
'error' => $e->getMessage(),
]);
return ['status' => 'error', 'message' => $e->getMessage()];
}
}
protected function isImage(Media $media): bool
{
return str_starts_with($media->mime_type, 'image/');
}
protected function isVideo(Media $media): bool
{
return str_starts_with($media->mime_type, 'video/');
}
protected function getMediaProperties(Media $media): array
{
if ($this->isVideo($media)) {
return $this->getVideoInfo($media->getPath());
} else {
return ['dimensions' => $this->getImageDimensions($media->getPath())];
}
}
protected function getVideoInfo(string $path): array
{
$ffprobe = FFProbe::create([
'ffprobe.binaries' => config('media-library.ffprobe_path'),
]);
$dimensions = $ffprobe
->streams($path)
->videos()
->first()
->getDimensions();
$duration = $ffprobe
->format($path)
->get('duration');
return [
'dimensions' => [
'width' => $dimensions->getWidth(),
'height' => $dimensions->getHeight(),
],
'duration' => floatval($duration),
];
}
protected function getImageDimensions(string $path): array
{
$image = Image::load($path);
return [
'width' => $image->getWidth(),
'height' => $image->getHeight(),
];
}
protected function updateMediaProperties(Media $media, array $properties): void
{
foreach ($properties as $key => $value) {
$media->setCustomProperty($key, $value);
}
$media->saveQuietly();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment