Your Guide to Laravel Excellence

Convert mp4 to m3u8 using FFMpeg for Laravel with AWS S3

Convert mp4 to m3u8 using FFMpeg for Laravel with AWS S3

In this easy-to-follow tutorial we will learn how to convert mp4 video to m3u8 for streaming, deal for smooth streaming experiences, we'll be utilizing a video uploaded to an AWS S3 bucket.To convert a video , we need FFmpeg package.First we need to install and configure this package then we utilize this package and convert our videos , you can convert videos in many formats , for that check documentation

Install and Configure laravel-ffmpeg

composer require pbmedia/laravel-ffmpeg

// config/app.php
'providers' => [
   ...
   ProtoneMedia\LaravelFFMpeg\Support\ServiceProvider::class,
   ...
];

'aliases' => [
   ...
   'FFMpeg' => ProtoneMedia\LaravelFFMpeg\Support\FFMpeg::class
   ...
];

php artisan vendor:publish --provider="ProtoneMedia\LaravelFFMpeg\Support\ServiceProvider"

Creating Laravel Routes and Controller

php artisan make:controller UploadFileController

Route::get('/transcode-file', [UploadFileController::class, 'transcodeUploadedFile']);

Implementing MP4 to M3U8 Conversion Logic

In this image,the video is uploaded on AWS S3 Bucket and we highlighted the key, this key we are using in our controller logic.We have saved this key in our DB you can also pass static key name.We use video that is uploaded on AWS , we convert that and then we will store it in AWS S3 Bucket

public function transcodeUploadedFile(Request $request)
{
    $vedio = AWSVedioDetail::whereNotNull('key')->first();

    $Videofile =  $vedio->key;

    $lowBitrate = (new X264)->setKiloBitrate(144);
    $midBitrate = (new X264)->setKiloBitrate(240);
    $high1Bitrate = (new X264)->setKiloBitrate(360);
    $high2Bitrate = (new X264)->setKiloBitrate(480);
    $high3Bitrate = (new X264)->setKiloBitrate(720);
    $high4Bitrate = (new X264)->setKiloBitrate(1080);

    $uniqueFilename = Str::random(7);
    $bitrate = $lowBitrate->getKiloBitrate();
    $timestamp = now()->format('YmdHis');

    $play_link = "stream-transcoded-videos/hls-{$uniqueFilename}/{$bitrate}_{$timestamp}.m3u8";

    FFMpeg::fromDisk('s3')
        ->open($Videofile)
        ->exportForHLS()
        ->toDisk('s3')
        ->addFormat($lowBitrate, function ($media) {
            $media->scale(192, 144);
        })
        ->addFormat($midBitrate, function ($media) {
            $media->scale(320, 240);
        })
        ->addFormat($high1Bitrate, function ($media) {

            $media->scale(480, 360);
        })
        ->addFormat($high2Bitrate, function ($media) {
            $media->scale(640, 480);
        })
        ->addFormat($high3Bitrate, function ($media) {
            $media->scale(1280, 720);
        })
        ->addFormat($high4Bitrate, function ($media) {
            $media->scale(1920, 1080);
        })
        ->save($play_link);
    $play_url = Storage::disk('s3')->url($play_link);
    $converted_at = Carbon::now();
    $updated= $vedio->update([
        'converted_at' => $converted_at,
        'play_link' =>   env('AWS_BUCKET_URL'). $play_url,
    ]);
    
    return "$play_url .<br> $updated";
}

Recommeded Posts

CRUD with Alpine.js, Tailwind CSS, and jQuery DataTable Modals

CRUD with Alpine.js, Tailwind CSS, and jQuery DataTable Modals

Learn how to build a full CRUD system using Alpine.js, Tailwind CSS, and jQuery DataTable, complete with modals for better user experience.

3 months ago Read article →
How to Add Two-Factor Authentication (2FA) in Laravel Fortify

How to Add Two-Factor Authentication (2FA) in Laravel Fortify

How to Add Two-Factor Authentication (2FA) in Laravel Fortify

3 months ago Read article →
How to Use Lateral Joins in Laravel for Fetching Limited Records

How to Use Lateral Joins in Laravel for Fetching Limited Records

How to Use Lateral Joins in Laravel for Fetching Limited Records

3 months ago Read article →
Per-Second Rate Limiting in Laravel 11

Per-Second Rate Limiting in Laravel 11

Per-Second Rate Limiting in Laravel 11

3 months ago Read article →