Laravel Filament: How To Upload Video Files

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.

viewing video page


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 = 20M
upload_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.

viewing video page


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.

avatar

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?

👍 1
avatar

Exactly what I needed! Thank you very much!

Like our articles?

Become a Premium Member for $129/year or $29/month
What else you will get:
  • 55 courses (987 lessons, total 46 h 42 min)
  • 77 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord

Recent Premium Tutorials