Filament admin panel has a File Upload field, but is it possible to upload video files with it? In this tutorial, I will demonstrate that and show the uploaded video in a custom view page using basic HTML <video>
Element.
Prepare Server for Large File Uploads
Before touching any code, first, we will prepare the web-server to be able to upload larger files, in the php.ini
file settings.
The default value for upload_max_filesize
is 2 MB and 8 MB for post_max_size
. We need to increase those values.
I'm using PHP 8.1. If yours is different, change the version to yours.
sudo nano /etc/php/8.1/fpm/php.ini
I will be uploading a 17MB video file so I will increase both upload_max_filesize
and post_max_size
to 20MB.
post_max_size = 20Mupload_max_filesize = 20M
Next, restart the PHP FPM service.
sudo service php8.1-fpm restart
Now, our PHP is ready to accept such files.
Uploading File
On the DB level, we will have one model Video
with two string fields attachment
and type
.
app/Models/Video.php:
class Video extends Model{ protected $fillable = [ 'attachment', 'type', ];}
Next, Filament. When creating a Filament Resource, we also need to create a record view.
php artisan make:filament-resource Video --view
For the form, we will have a basic File Upload field. This field will be required, will have a max upload size of 20MB, and I will preserve the original filename. The last one is optional.
app/Filament/VideoResource.php:
class VideoResource extends Resource{ // ... public static function form(Form $form): Form { return $form ->schema([ FileUpload::make('attachment') ->required() ->preserveFilenames() ->maxSize(20000), ]); } // ...}
Before uploading, we also need to set the max file size for the Livewire. First, we need to publish Livewire config.
php artisan livewire:publish --config
config/livewire.php:
return [ // ... 'temporary_file_upload' => [ 'disk' => null, // Example: 'local', 's3' Default: 'default' 'rules' => 'max:20000', 'directory' => null, // Example: 'tmp' Default 'livewire-tmp' 'middleware' => null, // Example: 'throttle:5,1' Default: 'throttle:60,1' 'preview_mimes' => [ // Supported file types for temporary pre-signed file URLs. 'png', 'gif', 'bmp', 'svg', 'wav', 'mp4', 'mov', 'avi', 'wmv', 'mp3', 'm4a', 'jpg', 'jpeg', 'mpga', 'webp', 'wma', ], 'max_upload_time' => 5, // Max duration (in minutes) before an upload gets invalidated. ], // ...];
Now upload should be working. But before creating the record, we need to get the mime type of the file and save it into the DB.
app/Filament/VideoResouce/Pages/CreateVideo.php:
<?php namespace App\Filament\Resources\VideoResource\Pages; use Illuminate\Support\Facades\Storage;use App\Filament\Resources\VideoResource;use Filament\Resources\Pages\CreateRecord; class CreateVideo extends CreateRecord{ protected static string $resource = VideoResource::class; protected function mutateFormDataBeforeCreate(array $data): array { $data['type'] = Storage::disk('public')->mimeType($data['attachment']); return $data; } }
Viewing Video
To view the video, we will use a basic HTML <video>
tag. For this, in Filament we will need to make a basic custom view page.
First, let's add the ViewRecord
page custom view path.
app/Filament/Resources/VideoRecourse/Pages/ViewVideo.php:
class ViewVideo extends ViewRecord{ protected static string $resource = VideoResource::class; protected static string $view = 'filament.pages.view-video'; }
Now let's create this view file and add a video player to it.
resources/views/filament/pages/view-video.blade.php:
<x-filament::page> <video controls> <source src="{{ asset($this->record->attachment) }}" type="{{ $this->record->type }}"> Your browser does not support the video tag. </video></x-filament::page>
After visiting the view page you will your uploaded video in the native browser video player.
That's it! As you can see, video files aren't different than any other files, they just need to have different validation for larger files.
You can learn more tips on how to work with Filament, in my 2-hour course Laravel Filament Admin: Practical Course.
If you want more Filament examples, you can find more real-life projects on our FilamentExamples.com.
Thanks for yet another great tutorial. Would it be possible to show how we would go about saving and serving files on non-public disks, in such a way that access to the file's URL is only possible for authenticated and authorized users?
I have this old article about it: https://laraveldaily.com/post/laravel-upload-file-and-hide-real-url-for-secure-download-under-uuid
Exactly what I needed! Thank you very much!
Nice !
I'm trying to upload video but getting error from livewire side Error : The files.0 failed to upload. Can any one help me with this ? I'm using the Filament 2