0

I have a very strange problem. I need to convert video files by file resolution, for example, if the video file resolution is '1920x1080' then it must convert to 1080, 720, and 480 resolutions. The converter works fine but with low-size files. For example, I have a 46 MB '1920x1080' file, and it's converting to 1080, 720, and 480. and its works fine. But I have another file which is 312 MB and its resolution is 1280x720. it must convert to 720 and 480, but when it's starting converting 720 and some point it stops, and am getting an error.

{
    "success": false,
    "message": "Encoding failed"
}

I tried everything I really don't understand why am getting this error. and why it converts low-size files and does not convert big-size files... Can please someone help me with this task...

So this is my method:

    public function convertVideo(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'video' => 'required|mimes:mp4',
                'content_type' => 'required|string',
                'content_id' => 'required|numeric',
            ]);

            if ($validator->fails()) {
                $errors = $validator->errors()->all();
                return response()->json(['error' => $errors], 400);
            }

            $instance = new File();

            // Get the uploaded file from the request
            $file = $request->file('video');
            // (show/serie/movie)
            $contentType = $request->input('content_type');
            // ID 
            $contentId = $request->input('content_id');

            // Store the uploaded video file and get its path
            $filePath = $file->storeAs('temp', $file->getClientOriginalName(), 'local');
            $filePath = storage_path('app/' . $filePath);

            // Getting video formats. ( 1080p, 720p & 480p )
            $formats  = $instance->getVideoFormats($filePath);

            // Getting movie, show or serie.
            $content = $instance->getContentForVideo($contentType, $contentId);
            $userId = $content->user_id;

            foreach ($formats as $format) {
                $message = "Started converting " . $format['resolution'] . " on " . $content->title . ' content.';
                $event = new VideoConvertor($message, $userId);
                Event::dispatch($event);

                // Convert video to formats.resolution
                $result = $instance->convertToResolution($filePath, $format);

                if ($result->success === true) {
                    $convertedVideo = VideoConversion::where('file_name', $result->convertedVideoName)->where('status', 'pending')->where('bucket_status', 'pending')->firstOrFail();

                    if ($convertedVideo) {
                        $convertedVideo->status = 'completed';
                        $convertedVideo->content_type = $contentType;
                        $convertedVideo->content_id = $contentId;
                        $convertedVideo->save();

                        // Sending notification to user (Who is uploading video) that video was converted, and we are starting uploading it on bucket. 
                        $message = $convertedVideo->resolution . " was converted for " . $content->title . ' content.';

                        $event = new VideoConvertor($message, $userId);
                        Event::dispatch($event);

                    } else {
                        return response()->json([
                            'success' => false,
                            'message' => 'Something went wrong while updating video conversion status.',
                        ], 500);
                    }
                } else if ($result->success === false) {
                    return response()->json([
                        'success' => false,
                        'message' => $result->message,
                    ], 500);
                }
            }

            // Delete the file from local storage
            unlink($filePath);

            return response()->json([
                'message' => 'Video was converted successfully.',
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'message:' =>  $e->getMessage(),
            ], 500);
        }
    }

my getVideoFormats function:

    public function getVideoFormats($filePath)
    {
        $ffprobe = FFProbe::create();

        // Get the resolution of the video
        $resolution = $ffprobe->streams($filePath)->videos()->first()->get('width') . 'x' . $ffprobe->streams($filePath)->videos()->first()->get('height');
        // Create 1080p and lower video if the resolution is higher than 1080p
        if ($resolution === '1920x1080') {
            $formats = [
                ['resolution' => '1080p', 'format' => new X264('aac', 'libx264', 'mp4'), 'event' => 'video.converted.1080p', 'dimension' => new Dimension(1920, 1080)],
                ['resolution' => '720p', 'format' => new X264('aac', 'libx264', 'mp4'), 'event' => 'video.converted.720p', 'dimension' => new Dimension(1280, 720)],
                ['resolution' => '480p', 'format' => new X264('aac', 'libx264', 'mp4'), 'event' => 'video.converted.480p', 'dimension' => new Dimension(854, 480)],
            ];
        }
        // Create 720p and lower video if the resolution is higher than 720p
        else if ($resolution === '1280x720') {
            $formats = [
                ['resolution' => '720p', 'format' => new X264('aac', 'libx264', 'mp4'), 'event' => 'video.converted.720p', 'dimension' => new Dimension(1280, 720)],
                ['resolution' => '480p', 'format' => new X264('aac', 'libx264', 'mp4'), 'event' => 'video.converted.480p', 'dimension' => new Dimension(854, 480)],
            ];
        }
        // Create 480p video if the resolution is lower than 720p
        else if ($resolution === '854x480') {
            $formats = [
                ['resolution' => '480p', 'format' => new X264('aac', 'libx264', 'mp4'), 'event' => 'video.converted.480p', 'dimension' => new Dimension(854, 480)],
            ];
        } else {
            $formats = [];
        }

        return $formats;
    }

And the convertToResolution function

    public function convertToResolution($filePath, $format)
    {
        try {
            $uuid = uniqid();
            $randomVideoName = "{$uuid}-{$format['resolution']}.mp4";

            $outputPath = storage_path("app/videos/{$randomVideoName}");
            $resizeFilter = new ResizeFilter($format['dimension']);

            $ffmpeg = FFMpeg::create();
            $video = $ffmpeg->open($filePath);


            // Perform video conversion and save it to the output path
            $video->addFilter($resizeFilter)->save($format['format'], $outputPath);

            // Save the converted video file name in a separate table
            VideoConversion::create([
                'file_name' => $randomVideoName,
                'status' => 'pending',
                'bucket_status' => 'pending',
                'resolution' => $format['resolution'],
            ]);

            return (object) [
                'success' => true,
                'convertedVideoName' => $randomVideoName,
            ];
        } catch (ProcessFailedException $e) {
            Log::error('Video encoding failed: ' . $e->getMessage());
            return (object) [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        } catch (\Exception $e) {
            Log::error('Error during video conversion: ' . $e->getMessage());
            return (object) [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }

Any opinion on what the hell this convertor wants? Oh yes, and I increased memory_limit = 1G upload_max_filesize = 3G post_max_size = 3G max_execution_time = 600 in php.ini but the same result...

...................... I dd($e) and am getting this

FFMpeg\Exception\RuntimeException {#1528 ▼ // app/Models/File.php:219
  #message: "Encoding failed"
  #code: 0
  #file: "/project/backend/vendor/php-ffmpeg/php-ffmpeg/src/FFMpeg/Media/AbstractVideo.php"
  #line: 116
  -previous: Alchemy\BinaryDriver\Exception\ExecutionFailureException {#1526 ▶}
  trace: {▼
    /project/backend/vendor/php-ffmpeg/php-ffmpeg/src/FFMpeg/Media/AbstractVideo.php:116 {▶}
    /project/backend/app/Models/File.php:198 {▼
      App\Models\File->convertToResolution($filePath, $format) …
      › // Perform video conversion and save it to the output path
      › $video->addFilter($resizeFilter)->save($format['format'], $outputPath);
      › 
    }
    /project/backend/app/Http/Controllers/FileController.php:175 {▼
      App\Http\Controllers\FileController->convertVideo(Request $request) …
      › // Convert video to formats.resolution
      › $result = $instance->convertToResolution($filePath, $format);
      › 
    }
    /project/backend/vendor/laravel/framework/src/Illuminate/Routing/Controller.php:54 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:43 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Routing/Route.php:259 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Routing/Route.php:205 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Routing/Router.php:798 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:141 {▶}
    /project/backend/app/Http/Middleware/CheckRole.php:38 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:180 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php:50 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:180 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php:126 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php:92 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php:54 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:180 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php:44 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:180 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php:44 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:180 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:116 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Routing/Router.php:797 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Routing/Router.php:776 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Routing/Router.php:740 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Routing/Router.php:729 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:190 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:141 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:21 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php:31 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:180 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:21 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php:40 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:180 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php:27 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:180 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php:86 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:180 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php:62 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:180 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php:39 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:180 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:116 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:165 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:134 {▶}
    /project/backend/public/index.php:51 {▶}
    /project/backend/vendor/laravel/framework/src/Illuminate/Foundation/resources/server.php:16 {▶}
  }
}

-previous: Alchemy\BinaryDriver\Exception\ExecutionFailureException

#message: """
      ffmpeg failed to execute command '/usr/bin/ffmpeg' '-y' '-i' '/project/vod/backend/storage/app/temp/002 Advanced - Grammar - All or What for Emp ▶
      
      Error Output:
      
       ffmpeg version 4.4.2-0ubuntu0.22.04.1 Copyright (c) 2000-2021 the FFmpeg developers
        built with gcc 11 (Ubuntu 11.2.0-19ubuntu1)
        configuration: --prefix=/usr --extra-version=0ubuntu0.22.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu - ▶
        libavutil      56. 70.100 / 56. 70.100
        libavcodec     58.134.100 / 58.134.100
        libavformat    58. 76.100 / 58. 76.100
        libavdevice    58. 13.100 / 58. 13.100
        libavfilter     7.110.100 /  7.110.100
        libswscale      5.  9.100 /  5.  9.100
        libswresample   3.  9.100 /  3.  9.100
        libpostproc    55.  9.100 / 55.  9.100
      Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/project/vod/backend/storage/app/temp/002 Advanced - Grammar - All or What for Emphasis.mp4':
        Metadata:
          major_brand     : mp42
          minor_version   : 0
          compatible_brands: isomiso2avc1mp41mp42
          encoder         : Lavf53.32.100
        Duration: 00:11:32.61, start: 0.000000, bitrate: 2182 kb/s
        Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1989 kb/s, 25 fps, 25 tbr, 25 tbn, 50 tbc (default)
          Metadata:
            handler_name    : VideoHandler
            vendor_id       : [0][0][0][0]
        Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 189 kb/s (default)
          Metadata:
            handler_name    : SoundHandler
            vendor_id       : [0][0][0][0]
      Stream mapping:
        Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
        Stream #0:1 -> #0:1 (aac (native) -> aac (native))
      Press [q] to stop, [?] for help
      [libx264 @ 0x558dbd591a40] using SAR=1/1
      [libx264 @ 0x558dbd591a40] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2 AVX512
      [libx264 @ 0x558dbd591a40] profile High, level 4.0, 4:2:0, 8-bit
      [libx264 @ 0x558dbd591a40] 264 - core 163 r3060 5db6aa6 - H.264/MPEG-4 AVC codec - Copyleft 2003-2021 - http://www.videolan.org/x264.html - options: cabac=1 ref ▶
      Output #0, mp4, to '/project/vod/backend/storage/app/videos/646b1879e764b-720p.mp4':
        Metadata:
          major_brand     : mp42
          minor_version   : 0
          compatible_brands: isomiso2avc1mp41mp42
          encoder         : Lavf58.76.100
        Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 1000 kb/s, 25 fps, 12800 tbn (default)
          Metadata:
            handler_name    : VideoHandler
            vendor_id       : [0][0][0][0]
            encoder         : Lavc58.134.100 libx264
          Side data:
            cpb: bitrate max/min/avg: 0/0/1000000 buffer size: 0 vbv_delay: N/A
        Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
          Metadata:
            handler_name    : SoundHandler
            vendor_id       : [0][0][0][0]
            encoder         : Lavc58.134.100 aac
      frame=    3 fps=0.0 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A speed=   0x    \rframe=   94 fps=0.0 q=28.0 size=       0kB time=00:00:03.88 bitrate=   0 ▶
      """
    #code: 0
    #file: "/project/vod/backend/vendor/php-ffmpeg/php-ffmpeg/src/Alchemy/BinaryDriver/ProcessRunner.php"
    #line: 94
    -previous: Symfony\Component\Process\Exception\ProcessTimedOutException {#1526 ▶}
    #command: "'/usr/bin/ffmpeg' '-y' '-i' '/project/vod/backend/storage/app/temp/002 Advanced - Grammar - All or What for Emphasis.mp4' '-vcodec' 'libx264' '- ▶"
    #errorOutput: """
      ffmpeg version 4.4.2-0ubuntu0.22.04.1 Copyright (c) 2000-2021 the FFmpeg developers
        built with gcc 11 (Ubuntu 11.2.0-19ubuntu1)
        configuration: --prefix=/usr --extra-version=0ubuntu0.22.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu - ▶
        libavutil      56. 70.100 / 56. 70.100
        libavcodec     58.134.100 / 58.134.100
        libavformat    58. 76.100 / 58. 76.100
        libavdevice    58. 13.100 / 58. 13.100
        libavfilter     7.110.100 /  7.110.100
        libswscale      5.  9.100 /  5.  9.100
        libswresample   3.  9.100 /  3.  9.100
        libpostproc    55.  9.100 / 55.  9.100
      Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/project/vod/backend/storage/app/temp/002 Advanced - Grammar - All or What for Emphasis.mp4':
        Metadata:
          major_brand     : mp42
          minor_version   : 0
          compatible_brands: isomiso2avc1mp41mp42
          encoder         : Lavf53.32.100
        Duration: 00:11:32.61, start: 0.000000, bitrate: 2182 kb/s
        Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1989 kb/s, 25 fps, 25 tbr, 25 tbn, 50 tbc (default)
          Metadata:
            handler_name    : VideoHandler
            vendor_id       : [0][0][0][0]
        Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 189 kb/s (default)
          Metadata:
            handler_name    : SoundHandler
            vendor_id       : [0][0][0][0]
      Stream mapping:
        Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
        Stream #0:1 -> #0:1 (aac (native) -> aac (native))
      Press [q] to stop, [?] for help
      [libx264 @ 0x558dbd591a40] using SAR=1/1
      [libx264 @ 0x558dbd591a40] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2 AVX512
      [libx264 @ 0x558dbd591a40] profile High, level 4.0, 4:2:0, 8-bit
      [libx264 @ 0x558dbd591a40] 264 - core 163 r3060 5db6aa6 - H.264/MPEG-4 AVC codec - Copyleft 2003-2021 - http://www.videolan.org/x264.html - options: cabac=1 ref ▶
      Output #0, mp4, to '/project/vod/backend/storage/app/videos/646b1879e764b-720p.mp4':
        Metadata:
          major_brand     : mp42
          minor_version   : 0
          compatible_brands: isomiso2avc1mp41mp42
          encoder         : Lavf58.76.100
        Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 1000 kb/s, 25 fps, 12800 tbn (default)
          Metadata:
            handler_name    : VideoHandler
            vendor_id       : [0][0][0][0]
            encoder         : Lavc58.134.100 libx264
          Side data:
            cpb: bitrate max/min/avg: 0/0/1000000 buffer size: 0 vbv_delay: N/A
        Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
          Metadata:
            handler_name    : SoundHandler
            vendor_id       : [0][0][0][0]
            encoder         : Lavc58.134.100 aac
      frame=    3 fps=0.0 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A speed=   0x    \rframe=   94 fps=0.0 q=28.0 size=       0kB time=00:00:03.88 bitrate=   0 ▶
      """
Boychik
  • 61
  • 7
  • 1
    you are catching the exception, log more info then just the message, like file, line, trace or even previous exception, then you will know where it was thrown and perhaps why. – Kazz May 22 '23 at 05:28
  • I changed return (object) [ 'success' => false, 'message' => $e, ]; but now am getting empty {} – Boychik May 22 '23 at 06:49
  • It's hard to say, without more information from the exception. In addition, do you have the correct codecs installed with FFMpeg to transcode the large uploaded file? Is the file corrupted during upload? Do you have sufficient disk space where the file is being uploaded? – Matthew Setter May 22 '23 at 06:53
  • i added dd($e) and i added in my question what am getting there... i have disk space and i just installed FFMpeg no extra codecs. – Boychik May 22 '23 at 06:57
  • I installed this codecs libx264-dev , libmp3lame-dev and libfdk-aac-dev but getting same error... – Boychik May 22 '23 at 07:10
  • you can see there is previous exception `Alchemy\BinaryDriver\Exception\ExecutionFailureException` there is the cause – Kazz May 22 '23 at 07:21
  • Kazz what does that mean? Where i must search problem? or how can I fix the problem? – Boychik May 22 '23 at 07:26
  • I added -previous: Alchemy\BinaryDriver\Exception\ExecutionFailureException details in question... – Boychik May 22 '23 at 07:33
  • manually execute the command which fails, you will get error info. oh there is another previous exception `Symfony\Component\Process\Exception\ProcessTimedOutException` but the fail occur at frame 3 so that is weird. have you tried another video input ? just in case of file corruption – Kazz May 22 '23 at 17:41

1 Answers1

0

I added timeout when creating FFMpeg and now it can convert large files.

      $ffmpeg = FFMpeg::create(array(
                'timeout'          => 0, // The timeout for the underlying process
            ));
Boychik
  • 61
  • 7
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 24 '23 at 12:57