How to upload video in Laravel in the best way?

Lets go through a Laravel 8 upload video example. This example will help you upload video to database in Laravel 8. Lets create a basic example of Laravel 8 video upload with preview.

In this tutorial, we will create two routes one for get and another for the post method. we created a simple form with file input. So you have to simply select video and then it will upload in “video” directory of public folder of your Laravel project.

Step 1: Install Laravel 8 and Create new Project

The first step is to assure you work with Laravel 8 and create a new project with it.

composer create-project --prefer-dist laravel/upload_video blog

Step 2: Create new Routes

Next, we will add new two routes in routes/web.php file. One to generate input form and another for the post method.

Route::get('upload-video', [ UploadVideoController ::class, 'getUploadVideoForm' ])->name('video.upload');
Route::post('upload-video', [ UploadVideoController ::class, 'uploadVideo' ])->name('video.upload.post');

Step 3: Create new Controller

In the third step we will create a new UploadVideoController under the app/Http/Controllers directory, where we will define the two method uploadVideo() and getUploadVideoForm(). So one method handles get method another one for post.

<?php
 
namespace App\Http\Controllers;
 
use App\Models\Video;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
 
class UploadVideoController extends Controller
{
    public function getUploadVideoForm()
    {
        return view('upload-video');
    }
 
    public function uploadVideo(Request $request)
   {
        $this->validate($request, [
            'title' => 'required|string|max:255',
            'video' => 'required|file|mimetypes:video/mp4',
        ]);
 
        $fileName = $request->video->getClientOriginalName();
        $filePath = 'videos/' . $fileName;
 
        $isFileUploaded = Storage::disk('public')->put($filePath, file_get_contents($request->video));
 
        // File URL to access the video in frontend
        $url = Storage::disk('public')->url($filePath);
 
        if ($isFileUploaded) {
            $video = new Video();
            $video->title = $request->title;
            $video->path = $filePath;
            $video->save();
 
            return back()
            ->with('success','Video has been successfully uploaded.');
        }
 
        return back()
            ->with('error','Unexpected error occured');
    }
}

The getUploadVideoForm() method returns the view where a user can upload the video. Meanwhile, the uploadVideo() method deals with the uploaded video from the view. It validates the video type, checks the mimes types and its maximum size. Then stores the video to the public path specified for the project. The video URL is saved to access the video in frontend. A success message returns with the image path, if the process goes smoothly without errors.

Step 4: Create new blade file

The blade view that is returned in the getUploadVideoForm() method is coded as shown below.

<!DOCTYPE html>
<html>
   <head>
      <title>Laravel Video Upload Form - scratchcoding.dev</title>
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
   </head>
   <body>
      <div class="container mt-5">
         <div class="panel panel-primary">
            <div class="panel-heading">
               <h2>Laravel Video Upload Form- scratchcoding.dev</h2>
            </div>
            <div class="panel-body">
               @if ($message = Session::get('success'))
                   <div class="alert alert-success alert-block">
                      <button type="button" class="close" data-dismiss="alert">×</button>
                      <strong>{{ $message }}</strong>
                   </div>
               @endif
 
               @if (count($errors) > 0)
               <div class="alert alert-danger">
                  <strong>Whoops!</strong> There were some problems with your input.
                  <ul>
                     @foreach ($errors->all() as $error)
                     <li>{{ $error }}</li>
                     @endforeach
                  </ul>
               </div>
               @endif
 
               <form action="{{ route('store.video') }}" method="POST" enctype="multipart/form-data">
                  @csrf
                  <div class="row">
 
                     <div class="col-md-12">
                        <div class="col-md-6 form-group">
                           <label>Title:</label>
                           <input type="text" name="title" class="form-control"/>
                        </div>
                        <div class="col-md-6 form-group">
                           <label>Select Video:</label>
                           <input type="file" name="video" class="form-control"/>
                        </div>
                        <div class="col-md-6 form-group">
                           <button type="submit" class="btn btn-success">Save</button>
                        </div>
                     </div>
                  </div>
               </form>
            </div>
         </div>
      </div>
   </body>
</html>

The blade file above views the upload video option to the user. In addition, it has two separate divs that pop up required messages. One for success and one for error. The error directive will display any error messages.

Video MIME types details

The following mime types can be added to validate for a specific video formats.

Video TypeExtensionMime Type
Flash.flvvideo/x-flv
QuickTime.movvideo/quicktime
3GP Mobile.3gpvideo/3gpp
A/VInterleave.avivideo/x-msvideo
MPEG-4.mp4video/mp4
Windows Media.wmvvideo/x-ms-wmv
iPhone Segment.tsvideo/MP2T
iPhone Index.m3u8application/x-mpegURL