<?php



class Ffmpeg
{

    static function videoToGif($original_video_file_path, $user_id)
    {
        $fileName = uniqid() . $user_id;
        $folder = UPLOADS_FOLDER_URI . '/gif/' . $user_id;
        $genrateGifPath = $folder . $fileName . ".gif";
        if (!file_exists($folder)) {
            mkdir($folder, 0777, true);
        }



        $gif = "ffmpeg -ss 3 -t 2 -i $original_video_file_path -vf 'fps=10,scale=160:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse' -loop 0 $genrateGifPath";

        exec($gif, $output);

        return $genrateGifPath;

    }

   static function videoToThumb($original_video_file_path, $user_id)
    {

        $without_extension_file_name = pathinfo($original_video_file_path, PATHINFO_FILENAME);


        $pieces = explode('/', $original_video_file_path);

        $str = implode('/', array_slice($pieces, 0, -1));


        $thumb_path = $str . '/' . $without_extension_file_name . "thumb.png";

        $thumb_cmd = "ffmpeg -i $original_video_file_path -vf fps=3 $thumb_path";

        exec($thumb_cmd, $output);


        return $thumb_path;
    }

    static function mergeVideoWithSound($video_path, $audio)
    {

        $without_extension_file_name = pathinfo($video_path, PATHINFO_FILENAME);


        $pieces = explode('/', $video_path);

        $str = implode('/', array_slice($pieces, 0, -1));


        $with_new_audio = $str . '/' . $without_extension_file_name . "1.mp4";

        $cmd = "ffprobe -i $video_path -show_streams -select_streams a -loglevel error";
        exec($cmd, $if_audio_exist);

        if (count($if_audio_exist) > 0) {
            //replace audio

            $cmd_new = "ffmpeg -i $video_path -i $audio -c:v copy -c:a aac -shortest -map 0:v:0 -map 1:a:0 $with_new_audio";
            exec($cmd_new);


        } else {

            //add audio
            $cmd_new = "ffmpeg -i $video_path -i $audio -c:v copy -c:a aac -shortest $with_new_audio";
            exec($cmd_new);

        }

        return $with_new_audio;
    }
    static function convertVideoToAudio($original_video_file_path)
    {

        $fileName = uniqid();
        $folder = UPLOADS_FOLDER_URI . '/audio/';
        $mp3_file = $folder . $fileName . ".mp3";
        if (!file_exists($folder)) {
            mkdir($folder, 0777, true);
        }

        $cmd = "ffprobe -i $original_video_file_path -show_streams -select_streams a -loglevel error";
        exec($cmd, $output);
        if (count($output) > 0) {

            $command_new = "ffmpeg -i $original_video_file_path -b:a 192K -vn $mp3_file";
            exec($command_new, $output);
            return $mp3_file;
        } else {

            return false;
        }


    }
    static function addWaterMarkInTheUserUploadedVideo($video,$username,$user_id,$duration){
        $fileName = uniqid() . $user_id;
        $starting_time = $duration/2;
        $ending_time = $starting_time*2;
        $dir =  UPLOADS_FOLDER_URI."/watermark/";
        $watermark_with_video ="$dir.$fileName.mp4";
        if (!file_exists($dir)) {
            mkdir($dir, 0777, true);
        }
        $watermark_with_username = (new self)->addUsernameWithWatermark($username,$user_id);

        $cmd = "ffmpeg -i $video -i $watermark_with_username -filter_complex \"[0:v][1:v]overlay=x='if(between(t,1,$starting_time),10,(main_w-overlay_w))':y='if(between(t,1,$starting_time),(main_h-overlay_h)/2-10,(main_h-overlay_h))':enable='between(t,0,$ending_time)'\" $watermark_with_video";

        //$cmd = "ffmpeg -i $original_video_file_path -i $image_with_watermark -filter_complex \"[0:v][1:v] overlay=x=\$x1\$:y=\$y1\$:enable='between(t,0,3)'[first]; [first][1:v] overlay=x=\$x2\$:y=\$y2\$:enable='between(t,3,6)'[outv]; [outv] fade=out:st=6:d=1 [finalv]\" -map '[finalv]' -c:a copy $video_with_watermark 2>&1";

        exec($cmd, $output);

        if(file_exists($watermark_with_video)){
            return $watermark_with_video;
        }else{
            return false;
        }



    }


    static function addUsernameWithWatermark($username,$user_id){
        $fileName = uniqid() . $user_id;
        $font_name = 'roboto-bold.ttf';
        $font_path = FONT_FOLDER_URI . '/' . $font_name;
        $watermark = WATERMARK_IMAGE_URI;
        $dir =  UPLOADS_FOLDER_URI."/watermark/";
        $watermark_with_username ="$dir.$fileName.png";
        if (!file_exists($dir)) {
            mkdir($dir, 0777, true);
        }
        $cmd_image = "ffmpeg -i $watermark -vf \"drawtext=text='@$username':fontsize=14:fontcolor=white:fontfile=$font_path:x=12:y=80\" $watermark_with_username";
        exec($cmd_image, $output);
        if(file_exists($watermark_with_username)){
            return $watermark_with_username;
        }else{
            return false;
        }



    }

    static function addWaterMarkInLastClip($username,$user_id){
        $fileName = uniqid() . $user_id;

        $dir =  UPLOADS_FOLDER_URI."/watermark/";
        $watermark_with_video ="$dir.$fileName.mp4";
        if (!file_exists($dir)) {
            mkdir($dir, 0777, true);
        }

        $watermark_video = WATERMARK_VIDEO_URI;
        $cmd_video_watermark = "ffmpeg -i $watermark_video -vf \"drawtext=text='@$username':x=400:y=1110:fontsize=30:fontcolor=white:enable='gte(t,1)'\" -c:a copy $watermark_with_video";


        exec($cmd_video_watermark, $output);

        if(file_exists($watermark_with_video)){
            return $watermark_with_video;
        }else{
            return false;
        }



    }



    static function combineVideoWithOriginal($user_video_with_watermark,$video_with_last_clip_watermark){
        $fileName = uniqid();


        $dir =  UPLOADS_FOLDER_URI."/watermark/";
        $video =$dir.$fileName.".mp4";
        if (!file_exists($dir)) {
            mkdir($dir, 0777, true);
        }
        $user_video_with_watermark = realpath($user_video_with_watermark);
        $video_with_last_clip_watermark = realpath($video_with_last_clip_watermark);

        if (!$user_video_with_watermark || !$video_with_last_clip_watermark) {
            die("Error: One or more video files do not exist.");
        }
// Create a temporary text file listing the videos
        $file_list = $dir.'file_list.txt';

        file_put_contents($file_list, "file '" . $user_video_with_watermark . "'\nfile '" . $video_with_last_clip_watermark . "'");

// Build the FFmpeg command
        $cmd_combine = "ffmpeg -f concat -safe 0 -i " . $file_list . " -c:v libx264 -crf 23 -preset fast -c:a aac -b:a 192k " . $video . " 2>&1";

// Execute the command
        exec($cmd_combine,$output);
       

// Cleanup: Remove the temporary file list
        unlink($file_list);

        $cmd_combine = "ffmpeg -i $user_video_with_watermark -i $video_with_last_clip_watermark -filter_complex '[0:v]scale=720:1280,setsar=1[v0]; [1:v]scale=720:1280,setsar=1[v1]; [v0][0:a][v1][1:a]concat=n=2:v=1:a=1[outv][outa]' -map '[outv]' -map '[outa]' $video";


        exec($cmd_combine, $output);

        if(file_exists($video)){
            return $video;
        }else{
            return false;
        }



    }

    function addWaterMarkAndText($original_video_file_path, $user_id, $username, $duration)
    {




        if ($duration < 1) {

            $duration = (new self)->getDurationOfVideoFile($original_video_file_path);
        }

        if(file_exists(WATERMARK_VIDEO_URI)) {


            $video_with_last_clip_watermark = (new self)->addWaterMarkInLastClip($username, $user_id);


            $user_video_with_watermark = (new self)->addWaterMarkInTheUserUploadedVideo($original_video_file_path, $username, $user_id, $duration);


            $final_video = (new self)->combineVideoWithOriginal($user_video_with_watermark, $video_with_last_clip_watermark);

            unlink($user_video_with_watermark);
            unlink($video_with_last_clip_watermark);

            return $final_video;

        }else{

            $fileName = uniqid() . $user_id;
            $font_name = 'roboto-bold.ttf';
            $font_path = FONT_FOLDER_URI . '/' . $font_name;
            $watermark = WATERMARK_IMAGE_URI;
            $folder = TEMP_UPLOADS_FOLDER_URI . '/video/' . $user_id . '/';
            $video_with_watermark = $folder . $fileName . ".mp4";
            if (!file_exists($folder)) {
                mkdir($folder, 0777, true);
            }

            $ext = pathinfo($watermark, PATHINFO_EXTENSION);

            if ($ext == "png" || $ext == "jpeg") {


                $cmd = "ffmpeg -i $original_video_file_path -i $watermark -filter_complex \"[0:v][1:v]overlay=10:10,drawtext=fontfile='$font_path':text='@$username':fontcolor=#ffffff:fontsize=18:y=40:x=13\" -c:a copy -movflags +faststart $video_with_watermark";

            } else {




                $cmd = "ffmpeg -i $original_video_file_path -ignore_loop 0 -i $watermark -filter_complex \"[0:v][1:v]overlay=x=10:y=10:format=auto:enable='lte(t,$duration)':shortest=1[bg];[bg][1:v]overlay=x=main_w-overlay_w-10:y=main_h-overlay_h-20:format=auto:enable='gte(t,$duration)':shortest=1,drawtext=fontfile='$font_path':text='@$username':fontsize=18:fontcolor=white:x=13:y=40:enable='lte(t,$duration)',drawtext=fontfile='$font_path':text='@$username':fontsize=18:fontcolor=white:x=w-tw-10:y=h-th-10:enable='gte(t,$duration)',format=yuv420p[v]\" -map \"[v]\" -c:v libx264 -crf 18 -map 0:a? -c:a copy -movflags +faststart $video_with_watermark";
            }

            exec($cmd, $output);


            return $video_with_watermark;
        }





    }

    static function duet($video1_path, $video2_path, $duet)
    {



        $without_extension_file_name = pathinfo($video1_path, PATHINFO_FILENAME);


        $pieces = explode('/', $video1_path);

        $str = implode('/', array_slice($pieces, 0, -1));


        $duetMergePathOutput = $str . '/' . $without_extension_file_name . "duet.mp4";


        $command_new = "ffmpeg -i $video1_path   -i $video2_path   -filter_complex '[0:v]pad=iw*2:ih[int];[int][1:v]overlay=W/2:0[vid]'   -map [vid]   -c:v libx264   -crf 23   -preset veryfast $duetMergePathOutput";


        exec($command_new);


        return $duetMergePathOutput;
    }

    static function duetVertical($video1_path, $video2_path)
    {


        $without_extension_file_name = pathinfo($video1_path, PATHINFO_FILENAME);


        $pieces = explode('/', $video1_path);

        $str = implode('/', array_slice($pieces, 0, -1));


        $duetMergePathOutput_top = $str . '/' . $without_extension_file_name . "temptop.mp4";
        $duetMergePathOutput_bottom = $str . '/' . $without_extension_file_name . "tempbottom.mp4";
        $duetMergePathOutput_final = $str . '/' . $without_extension_file_name . "duet.mp4";


        $command_top = "ffmpeg -i $video1_path -s 720x640 -c:a copy $duetMergePathOutput_top";
        $command_bottom = "ffmpeg -i $video2_path -s 720x640 -c:a copy $duetMergePathOutput_bottom";
        exec($command_top);
        exec($command_bottom);

        $command_final = "ffmpeg -i $duetMergePathOutput_top -i $duetMergePathOutput_bottom -filter_complex '[0:v][1:v]vstack=inputs=2[v]' -map '[v]' -map 1:a $duetMergePathOutput_final";
        // $command_final = "ffmpeg -i $command_top -i $command_bottom -lavfi vstack $duetMergePathOutput_final";

        exec($command_final);


        return $duetMergePathOutput_final;
    }

    static function getDurationOfVideoFile($video_url)
    {

        $cmd = "ffprobe -i $video_url -show_format  -v quiet | sed -n 's/duration=//p'";
        exec($cmd, $output);
        $duration = number_format((float)$output[0], 1, '.', '');
        return $duration;
    }
    static function getDurationofAudioFile($filepath)
    {

        $duration = shell_exec("ffmpeg -i \"" . $filepath . "\" 2>&1");


        preg_match("/Duration: (\d{2}:\d{2}:\d{2}\.\d{2})/", $duration, $matches);

        $time = explode(':', $matches[1]);
        $hour = $time[0];
        $minutes = $time[1];
        $seconds = round($time[2]);

        $total_seconds = 0;
        $total_seconds += 60 * 60 * $hour;
        $total_seconds += 60 * $minutes;

        return $minutes . ":" . $seconds;

    }

}
?>