如何使用ffmpeg 实现10种特效

相关特效的名字
特效id 特效名
1 向上移动
2 向左移动
3 向下移动
4 颤抖
5 摇摆
6 雨刷
7 弹入
8 弹簧
9 轻微跳动
10 跳动
特效展示(同时汇总相关命令)
pad背景显示

pad背景透明

相关命令(一会再讲这些命令,先往下看)

# 合成特效语音
ffmpeg -y -loglevel error -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/674c13b4b531438e8fa634b49ad058cf.mp3 \
-i https://file.youlai.cn/cnkfile1/M02/98/48/32150062579EF23DD585D11F069C9848.wav -i https://file.youlai.cn/cnkfile1/M02/24/39/9C49A3FAFA05F200246ECCF04A952439.wav  \
 -filter_complex "[0]volume='1'[w0]; \
  [1]adelay=27391|27391,volume='1'[w1]; [2]adelay=27391|27391,volume='1'[w2]; \
 [w0][w1][w2]amix=inputs=3:duration=first:dropout_transition=120" -f mp3 /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/674c13b4b531438e8fa634b49ad058cf_end.mp3

# 音量标准化
ffmpeg -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/674c13b4b531438e8fa634b49ad058cf_end.mp3 -af loudnorm=I=-16:LRA=11:tp=-1.5 -y /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/674c13b4b531438e8fa634b49ad058cf_stardard.mp3

#  向上移动

ffmpeg -y  -loglevel  fatal -loop 1  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/a7e7a1a96941472fa86e37e5b9e3fecc.png  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/71ba432626a0467dbcb873a196cf6e4b.mp4 \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:652.22827081866[v5];\
 [v5]pad=1304.4565416373:1304.4565416373:326.11413540933:326.11413540933:0x00F8FF@0.2[v1];\
 [v1]rotate='0*PI/180':ow='max(iw,ih)':oh=ow:c=none[v2];\
 [1][v2]overlay=\
 y='if(gte(t,0.76), if(gte(t,3.02), NAN,393.88586459067-min((t-0.76),1.2778844489612)*600 ),NAN):\
 x=-391.79900352788:shortest=1'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/a7e7a1a96941472fa86e37e5b9e3fecc.mp4

# 向左移动
 ffmpeg -y  -loglevel  fatal -loop 1  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/6bd2ed3c2cde443285f0da12e9bf03d0.png  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/a7e7a1a96941472fa86e37e5b9e3fecc.mp4 \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:388.44636971329[v5];\
 [v5]pad=776.89273942658:776.89273942658:194.22318485664:194.22318485664:0x00F8FF@0.2[v1];\
 [v1]rotate='0*PI/180':ow='max(iw,ih)':oh=ow:c=none[v2];\
 [1][v2]overlay=\
 y='if(gte(t,0.76), if(gte(t,3.02), NAN,191.61497976525),NAN):\
 x=1085.7768151434-min((t-0.76),0.95835738885612)*600 :shortest=1'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/6bd2ed3c2cde443285f0da12e9bf03d0.mp4

# 向下移动
 ffmpeg -y  -loglevel  fatal -loop 1  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/65daf9804f3e4f8f84df53724fb28736.png  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/6bd2ed3c2cde443285f0da12e9bf03d0.mp4 \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:338.29541316981[v5];\
 [v5]pad=676.59082633962:676.59082633962:169.1477065849:169.1477065849:0x00F8FF@0.2[v1];\
 [v1]rotate='0*PI/180':ow='max(iw,ih)':oh=ow:c=none[v2];\
 [1][v2]overlay=\
 y='if(gte(t,3.08), if(gte(t,4.62), NAN,-507.44311975471+min((t-3.08),0.66766169547593)*600 ),NAN):\
 x=303.65743686545:shortest=1'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/65daf9804f3e4f8f84df53724fb28736.mp4

# 颤抖
 ffmpeg -y  -loglevel  fatal -loop 1  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/9460654724694bbf83ed6c3a1f0b0c19.png  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/65daf9804f3e4f8f84df53724fb28736.mp4 \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:240[v5];\
 [v5]pad=480:480:120:120:0x00F8FF@0.2[v1];\
 [v1]rotate='59.604151827379*PI/180':ow='max(iw,ih)':oh=ow:c=none[v2];\
 [1][v2]overlay=\
 x='if(gte(t,4.68), if(gte(t,6.22), NAN,713.71212050647+mod(floor(n/3),2)*10 ),NAN ):\
 y=126.53647572709+mod(floor(n/3),2)*10:shortest=1'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/9460654724694bbf83ed6c3a1f0b0c19.mp4

# 摇摆
 ffmpeg -y  -loglevel  fatal -loop 1  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/74eed745c6574938b62688ca81d0342a.png  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/9460654724694bbf83ed6c3a1f0b0c19.mp4 \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:240[v5];\
 [v5]pad=480:480:120:120:0x00F8FF@0.2[v1];\
 [v1]rotate='318.664866283*PI/180+(15*PI/180)*sin(2*PI/0.4*t)':ow='max(iw,ih)':oh=ow:c=none[v2];\
 [1][v2]overlay=\
 x='if(gte(t,8.76), if(gte(t,13.08), NAN,122.89560094216 ),NAN ):\
 y=80.78114563749:shortest=1'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/74eed745c6574938b62688ca81d0342a.mp4

# 雨刷
ffmpeg -y  -loglevel  fatal -loop 1  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/a94137275201459a9f46b4a92b377c97.png  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/74eed745c6574938b62688ca81d0342a.mp4 \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:240[v5];\
 [v5]pad=672:672:96:96:0x00F8FF@0.2[v1];\
 [v1]rotate='0*PI/180-0.4*sin(8*PI/5*(t-13.5))':ow='max(iw,ih)':oh=ow:c=none[v2];\
 [1][v2]overlay=\
 x='if(gte(t,13.5), if(gte(t,14.798), NAN,410.69190672549 ),NAN ):\
 y=340.09427181257:shortest=1'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/a94137275201459a9f46b4a92b377c97.mp4

# 弹入

 ffmpeg -y -loop 1  -i  /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/f2292b7ca74c4f0bb2916a5bf3260182.png  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/a94137275201459a9f46b4a92b377c97.mp4 \
  -filter_complex "\
  [0]format=pix_fmts=rgba[v0];\
  [v0]scale=-1:327.36985856972[v5];\
  [v5]pad=1964.2191514183:1964.2191514183:818.4246464243:818.4246464243:0x00F8FF@0.2[v6];\
  [v6]scale=-1:'785.68766056733+2357.062981702*min(t-15.94,0.5)':eval=frame[v7];\
  [v7]rotate='189.98532547032*PI/180':ow='max(iw,ih)':oh=ow:c=none[v1];\
  [1][v1]overlay=\
  x='if(gte(t,15.94), if(gte(t,17.08), NAN,-8.7762423758301 ),NAN ):\
  y=-622.10957570916:shortest=1'[v2]" \
  -map [v2]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/f2292b7ca74c4f0bb2916a5bf3260182.mp4

# 弹簧
ffmpeg -y -loop 1  -i  /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/7d4397aa08234931b17425611094ff35.png  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/f2292b7ca74c4f0bb2916a5bf3260182.mp4 \
  -filter_complex "\
  [0]format=pix_fmts=rgba[v0];\
  [v0]scale=-1:240[v5];\
  [v5]pad=1440:1440:600:600:0x00F8FF@0.2[v6];\
  [v6]scale=-1:'\
  if(lte(t-17.72,0.5),360+2160*(t-17.72),\
  if(lte(t-18.22,0.5),1440-1728*(t-18.22),\
  if(lte(t-18.72,0.5),576+1152*(t-18.72),\
  if(lte(t-19.22,0.3),1296-960*(t-19.22),\
  1008))))
  ':eval=frame[v7];\
  [v7]rotate='0*PI/180':ow='max(iw,ih)':oh=ow:c=none[v1];\
  [1][v1]overlay=\
  x='if(gte(t,17.72), if(gte(t,20.48), NAN,253.33333333333 ),NAN ):\
  y=-360:shortest=1'[v2]" \
  -map [v2]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/7d4397aa08234931b17425611094ff35.mp4
 

# 轻微跳动
ffmpeg -y  -loglevel  fatal -loop 1  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/fca4bc617a244a1f9ec9cd8cb00ac20a.png  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/7d4397aa08234931b17425611094ff35.mp4 \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:240[v5];\
 [v5]pad=480:480:120:120:0x00F8FF@0.2[v1];\
 [v1]rotate='0*PI/180+sin(PI*(2*(t-17.72)))*0.15':ow='max(iw,ih)':oh=ow:c=none[v2];\
 [1][v2]overlay=x='if(gte(t,17.72), if(gte(t,20.48), NAN,24.78953680786),NAN ):y=128.71530096945:shortest=1'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/fca4bc617a244a1f9ec9cd8cb00ac20a.mp4

# 跳动
ffmpeg -y  -loglevel  fatal -loop 1  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/724bcc836fb14a81b151df910b81935c.png  -i /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/fca4bc617a244a1f9ec9cd8cb00ac20a.mp4 \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:240[v5];\
 [v5]pad=480:480:120:120:0x00F8FF@0.2[v1];\
 [v1]rotate=0*PI/180:ow='max(iw,ih)':oh=ow:c=none[v2];\
 [1][v2]overlay=x='if(gte(t,20.481), if(gte(t,21.02), NAN,408.49325431089),NAN ):y=if(gte(t,21.019014538326),-15.08716502643,min(-15.08716502643-80.7021807489*sin((t-20.481)*3/0.269007269163),-15.08716502643)):shortest=1'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k /Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/724bcc836fb14a81b151df910b81935c.mp4

单个特效命令讲解
如何实现运动轨迹(简单版本 向左移动,向上移动,向下移动,使用简单版本)
点击进入详情页面
代码中的实现和相关的问题
那么这个时候旋转角度会出现问题,把四个角给切除了,怎么办?使用pad图层的方法
ffmpeg -y -loop 1  -i  rotate_test.png  -i 0329_short.mp4 -filter_complex "[0]format=pix_fmts=rgba[v5];[v5]rotate=30*PI/180:ow='max(iw,ih)':oh=ow:c=none[v0];[v0]scale=140:140[v1];[1][v1]overlay=x='if(gte(t,3), if(gte(t,6), NAN,1000-(t-3)*40 ),NAN ):y=200:shortest=1'[v2]" -map [v2] -c:v libx264 move.mp4

ffmpeg -y -loop 1  -i  t002.png  -i 0329_short.mp4 -filter_complex "[0]format=pix_fmts=rgba[v5];[v5]rotate=30*PI/180:ow='max(iw,ih)':oh=ow:c=none[v0];[v0]scale=140:140[v1];[1][v1]overlay=x='if(gte(t,3), if(gte(t,6), NAN,1000-(t-3)*40 ),NAN ):y=200:shortest=1'[v2]" -map [v2] -c:v libx264 move.mp4


image.png
相关代码参考
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Monolog\Utils;
use PhpOffice\PhpSpreadsheet\Shared\PasswordHasher;

/**
 * Notes:特效视频的的合成脚本
 * User: zhangguofu
 * Date: 2021/4/21
 * Time: 11:02
 * Class TxCommand
 */
class TxCommand extends Command
{

    //素材分类 默认0 1:gif动图  2:png图片
    const TYPE_GIF = 1;
    const TYPE_PNG = 2;
    const B_LEFT = 1280;//向左侧滑入起点
    const B_UP = 720;//向上滑动的起点
    const TEST_ID=128;//dev测试
//    const TEST_ID=3520;//无视频
//    const TEST_ID=3521;25个视频

    const FILE = "https://file.youlai.cn/";
    const U_FILE = "https://youlaiugc.oss-cn-shanghai.aliyuncs.com/";
    const O_SIZE=70;//默认初始化大小是70
    const HEIGHT = 720;
    const WIDTH = 1280;
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'TxCommand';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $str= "开始处理一条视频的时间开始:".date("H:i:s",time());
        echo $str;
        echo  PHP_EOL;
        $arr = $this->getTime();
//        dd($arr);
        $obj= DB::connection("mysql_dev")->table('cnk_ugc_answer')->select(['subtitle_video_url'])->where("id",self::TEST_ID)->first();
//        dd($obj);
        $base_dir = "/Users/zhangguofu/Downloads/ftest/pika_mov/testfodder/";
//        $origin_video=$this->getUuid().".mp4";//TODO 线上打开
        $origin_video='0420_short.mp4';
        $d_video=$base_dir.$origin_video;
        $video=self::U_FILE.$obj->subtitle_video_url;
        $shell = "wget {$video}  -O  {$d_video}";
//        exec($shell);//TODO 线上打开

        $wav_stardard=$this->mergeVoice($base_dir,$origin_video,$arr,app(TxCommand::class));


        foreach ($arr as &$v) {
            //这里面是,循环所有的贴纸,并一一合成,gif调整尺寸和角度,展示时间,
            //png 随机生成动效
            $v = $this->getFodderUrl($v);
            if ($v['type'] == self::TYPE_GIF) {//TODO 线上打开
                $new_viedo = $this->gifShell($v, $origin_video, $base_dir);
                $origin_video = $new_viedo;
//                dd($origin_video);

            }

            if ($v['type'] == self::TYPE_PNG) {

                $new_viedo = $this->getRandomTx($v, $origin_video, $base_dir);
                $origin_video = $new_viedo;
//                dd($origin_video);
            }
        }
        unset($v);
        $str= "----处理结束".date("H:i:s",time());
        echo $str;
        echo  PHP_EOL;
        $voice = $base_dir . $wav_stardard;
        $str = 'ffmpeg -y -loglevel error -i %s -i %s  -c:v copy -map 0:v:0 -map 1:a:0 %s';
        $video_end=$rand=$this->getUuid() ."_end.mp4";
        $des_video_end=$base_dir.$video_end;
        $voice_shell = sprintf($str, $base_dir . $origin_video, $voice, $des_video_end);
        echo $voice_shell;
        exec($voice_shell);

        dd($video_end);
        //
    }


    /**
     * Notes:根据动画id生成特效视频并返回
     * User: zhangguofu
     * Date: 2021/4/25
     * Time: 11:49
     * @param $v
     * @param $origin_video
     * @param $base_dir
     * @return string
     */
    public function getRandomTx($v, $origin_video, $base_dir)
    {
        $animation_id = $v['animation_id'];
        $video_name = '';
        switch ($animation_id) {
            case 1:
                $video_name = $this->move_up($v, $origin_video, $base_dir);
                break;
            case 2:
                $video_name = $this->move_left($v, $origin_video, $base_dir);
                break;
            case 3:
                $video_name = $this->move_down($v, $origin_video, $base_dir);
                break;
            case 4:
                $video_name = $this->chandou($v, $origin_video, $base_dir);
                break;
            case 5:
                $video_name = $this->yaobai($v, $origin_video, $base_dir);
                break;
            case 6:
                $video_name = $this->yushua($v, $origin_video, $base_dir);
                break;
            case 7:
                $video_name = $this->tanru($v, $origin_video, $base_dir);
                break;
            case 8:
                $video_name = $this->tanhuang($v, $origin_video, $base_dir);
                break;
            case 9:
                $video_name = $this->xiaotiao($v, $origin_video, $base_dir);
                break;
            case 10:
                $video_name = $this->tiaodong($v, $origin_video, $base_dir);
                break;
        }
        return $video_name;
    }


    /**
     * Notes:gif 图片调整在视频中的尺寸 和旋转角度
     * User: zhangguofu
     * Date: 2021/4/22
     * Time: 16:21
     * @param $data array 对应的相关参数
     * @param $video string 对应的要处理的视频
     * @param $base_dir string 文件所在的目录
     * @return string
     */
    public function gifShell($data, $video, $base_dir)
    {
        $video = $base_dir . $video;
        $uuid = $this->getUuid();
        $gif = $uuid;
        $gif = $gif . ".gif";
        $gif = $base_dir . $gif;
        //下载gif素材
        exec("wget -c  {$data['pic_url']} -O  {$gif}");
        $des_video_name = $uuid . ".mp4";
        $des_video = $base_dir . $des_video_name;

        $px=$data['size_x']*2;
        $py=$data['size_y']*2;
        $nx=$data['coord_x']-$data['size_x']/2;
        $ny=$data['coord_y']-$data['size_y']/2;
//        dd($px);
        //最长展示6s,超过6s不显示
        $data['et']=$data['et']-$data['bt']<6?$data['et']:$data['bt']+6;
//        dd($data['et']);
        //旋转角度 和 大小,位置
        $gif_shell = '
ffmpeg -y  -loglevel fatal -ignore_loop 0 -itsoffset %s -i %s -i %s \
-filter_complex \
"[0]format=pix_fmts=rgba[v0];[v0]scale=-1:%s[v5];\
[v5]pad=%s:%s:%s:%s:0x00F8FF@0.2[v1];\
[v1]rotate=\'%s*PI/180\':ow=\'max(iw,ih)\':oh=ow:c=none[v2];\
[1][v2]overlay=\
x=\'if(gte(t,%s), if(gte(t,%s), NAN,%s),NAN ):\
y=%s:shortest=1\'[v3]"\
 -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k  %s';
        $gif_shell=sprintf(
            $gif_shell,$data['bt'],$gif,$video,$data['size_x'],
            $px,$py,$data['size_x']/2, $data['size_y']/2,
            $data['angle'],$data['bt'],$data['et'],$nx,$ny,$des_video);
        echo $gif_shell;
        echo PHP_EOL;
        exec($gif_shell);
//        unlink($gif);
//        unlink($video);//TODO 暂时保留视频,后期删除
        return $des_video_name;
    }
    /**
     * Notes:向上移动
     * User: zhangguofu
     * Date: 2021/4/22
     * Time: 15:03
     * @param $data array 对应的相关参数
     * @param $video string 对应的要处理的视频
     * @param $base_dir string 文件所在的目录
     */
    public function move_up($data, $video, $base_dir)
    {
        $video = $base_dir . $video;
        $uuid = $this->getUuid();
        $png = $uuid;
        $png = $png . ".png";
        $png = $base_dir . $png;
        //下载gif素材
        exec("wget -c  {$data['pic_url']} -O  {$png}");
        $des_video_name = $uuid . ".mp4";
        $des_video = $base_dir . $des_video_name;

        $px=$data['size_x']*2;
        $py=$data['size_y']*2;
        $nx=$data['coord_x']-$data['size_x']/2;
        $ny=$data['coord_y']-$data['size_y']/2;
        //旋转角度 和 大小,位置
        $png_shell = '
 ffmpeg -y  -loglevel  fatal -loop 1  -i %s  -i %s \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:%s[v5];\
 [v5]pad=%s:%s:%s:%s:0x00F8FF@0.2[v1];\
 [v1]rotate=\'%s*PI/180\':ow=\'max(iw,ih)\':oh=ow:c=none[v2];\
 [1][v2]overlay=\
 y=\'if(gte(t,%s), if(gte(t,%s), NAN,%s-min((t-%s),%s)*%s ),NAN):\
 x=%s:shortest=1\'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k %s';
        //需要计算y的滑行速度,在规定时间内移动到终点
        $length = self::B_UP - $data['coord_y'];//需要滑动的距离
        $speed=600;//滑动的速度
        $time_move=$length/$speed;
//        dd($time_move);
        $png_shell = sprintf($png_shell, $png, $video, $data['size_x'],
            $px,$py,$data['size_x']/2, $data['size_y']/2,
            $data['angle'], $data['bt'], $data['et'], self::B_UP-$data['size_y']/2, $data['bt'],$time_move, $speed, $nx, $des_video);
        echo $png_shell;
        echo PHP_EOL;
        exec($png_shell);
//        unlink($png);
        //        unlink($video);//TODO 暂时保留视频,后期删除
        return $des_video_name;
    }


    /**
     * Notes:向下移动
     * User: zhangguofu
     * Date: 2021/4/22
     * Time: 15:03
     * @param $data array 对应的相关参数
     * @param $video string 对应的要处理的视频
     * @param $base_dir string 文件所在的目录
     */
    public function move_down($data, $video, $base_dir)
    {
        $video = $base_dir . $video;
        $uuid = $this->getUuid();
        $png = $uuid;
        $png = $png . ".png";
        $png = $base_dir . $png;
        //下载gif素材
        exec("wget -c  {$data['pic_url']} -O  {$png}");
        $des_video_name = $uuid . ".mp4";
        $des_video = $base_dir . $des_video_name;
        $px=$data['size_x']*2;
        $py=$data['size_y']*2;
        $nx=$data['coord_x']-$data['size_x']/2;
        $ny=$data['coord_y']-$data['size_y']/2;
        //旋转角度 和 大小,位置
        $png_shell = '
 ffmpeg -y  -loglevel  fatal -loop 1  -i %s  -i %s \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:%s[v5];\
 [v5]pad=%s:%s:%s:%s:0x00F8FF@0.2[v1];\
 [v1]rotate=\'%s*PI/180\':ow=\'max(iw,ih)\':oh=ow:c=none[v2];\
 [1][v2]overlay=\
 y=\'if(gte(t,%s), if(gte(t,%s), NAN,%s+min((t-%s),%s)*%s ),NAN):\
 x=%s:shortest=1\'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k %s';
        //需要计算y的滑行速度,在规定时间内移动到终点
        $length =$data['coord_y']+$data['size_y'];
        $speed=600;//滑动的速度
        $time_move=$length/$speed;
        $png_shell = sprintf($png_shell, $png, $video, $data['size_x'],
            $px,$py,$data['size_x']/2, $data['size_y']/2,

            $data['angle'], $data['bt'], $data['et'], -$data['size_y']*1.5, $data['bt'],$time_move, $speed, $nx, $des_video);
        echo $png_shell;
        echo PHP_EOL;
        exec($png_shell);
//        unlink($png);
        //        unlink($video);//TODO 暂时保留视频,后期删除
        return $des_video_name;
    }


    /**
     * Notes:向左移动
     * User: zhangguofu
     * Date: 2021/4/22
     * Time: 15:03
     * @param $data array 对应的相关参数
     * @param $video string 对应的要处理的视频
     * @param $base_dir string 文件所在的目录
     */
    public function move_left($data, $video, $base_dir)
    {
        $video = $base_dir . $video;
        $uuid = $this->getUuid();
        $png = $uuid;
        $png = $png . ".png";
        $png = $base_dir . $png;
        //下载gif素材
        exec("wget -c  {$data['pic_url']} -O  {$png}");
        $des_video_name = $uuid . ".mp4";
        $des_video = $base_dir . $des_video_name;
        $px=$data['size_x']*2;
        $py=$data['size_y']*2;
        $nx=$data['coord_x']-$data['size_x']/2;
        $ny=$data['coord_y']-$data['size_y']/2;
        //旋转角度 和 大小,位置
        $png_shell = '
 ffmpeg -y  -loglevel  fatal -loop 1  -i %s  -i %s \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:%s[v5];\
 [v5]pad=%s:%s:%s:%s:0x00F8FF@0.2[v1];\
 [v1]rotate=\'%s*PI/180\':ow=\'max(iw,ih)\':oh=ow:c=none[v2];\
 [1][v2]overlay=\
 y=\'if(gte(t,%s), if(gte(t,%s), NAN,%s),NAN):\
 x=%s-min((t-%s),%s)*%s :shortest=1\'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k %s';
        //需要计算y的滑行速度,在规定时间内移动到终点
        $length=self::B_LEFT-$data['coord_x'];
        $speed=600;//滑动的速度
        $time_move=$length/$speed;
        $png_shell=sprintf($png_shell,$png,$video,$data['size_x'],
            $px,$py,$data['size_x']/2, $data['size_y']/2,
            $data['angle'],$data['bt'],$data['et'],
            $ny, self::B_LEFT-$data['size_x']/2, $data['bt'], $time_move,$speed, $des_video);
        echo $png_shell;
        echo PHP_EOL;
        exec($png_shell);
//        unlink($png);
        //        unlink($video);//TODO 暂时保留视频,后期删除
        return $des_video_name;
    }


    /**
     * Notes:颤抖
     * User: zhangguofu
     * Date: 2021/4/22
     * Time: 15:03
     * @param $data array 对应的相关参数
     * @param $video string 对应的要处理的视频
     * @param $base_dir string 文件所在的目录
     */
    public function chandou($data, $video, $base_dir)
    {
        $video = $base_dir . $video;
        $uuid = $this->getUuid();
        $png = $uuid;
        $png = $png . ".png";
        $png = $base_dir . $png;
        //下载gif素材
        exec("wget -c  {$data['pic_url']} -O  {$png}");
        $des_video_name = $uuid . ".mp4";
        $des_video = $base_dir . $des_video_name;
        $px=$data['size_x']*2;
        $py=$data['size_y']*2;
        $nx=$data['coord_x']-$data['size_x']/2;
        $ny=$data['coord_y']-$data['size_y']/2;
        //旋转角度 和 大小,位置
        $png_shell = '
 ffmpeg -y  -loglevel  fatal -loop 1  -i %s  -i %s \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:%s[v5];\
 [v5]pad=%s:%s:%s:%s:0x00F8FF@0.2[v1];\
 [v1]rotate=\'%s*PI/180\':ow=\'max(iw,ih)\':oh=ow:c=none[v2];\
 [1][v2]overlay=\
 x=\'if(gte(t,%s), if(gte(t,%s), NAN,%s+mod(floor(n/3),2)*10 ),NAN ):\
 y=%s+mod(floor(n/3),2)*10:shortest=1\'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k %s';
        //需要计算y的滑行速度,在规定时间内移动到终点
        $png_shell = sprintf($png_shell, $png, $video, $data['size_x'],
            $px,$py,$data['size_x']/2, $data['size_y']/2,

            $data['angle'], $data['bt'], $data['et'],

            $nx, $ny, $des_video);
        echo $png_shell;
        echo PHP_EOL;
        exec($png_shell);
//        unlink($png);
        //        unlink($video);//TODO 暂时保留视频,后期删除
        return $des_video_name;
    }



    /**
     * Notes:无动效
     * User: zhangguofu
     * Date: 2021/4/22
     * Time: 15:03
     * @param $data array 对应的相关参数
     * @param $video string 对应的要处理的视频
     * @param $base_dir string 文件所在的目录
     */
    public function no_move($data, $video, $base_dir)
    {
        $video = $base_dir . $video;
        $uuid = $this->getUuid();
        $png = $uuid;
        $png = $png . ".png";
        $png = $base_dir . $png;
        //下载gif素材
        exec("wget -c  {$data['pic_url']} -O  {$png}");
        $des_video_name = $uuid . ".mp4";
        $des_video = $base_dir . $des_video_name;
        //pad一个两倍的透明图像
        $px=$data['size_x']*2;
        $py=$data['size_y']*2;
        $nx=$data['coord_x']-$data['size_x']/2;
        $ny=$data['coord_y']-$data['size_y']/2;
        //旋转角度 和 大小,位置
        $png_shell = '
 ffmpeg -y  -loglevel  fatal -loop 1  -i %s  -i %s \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:%s[v5];\
 [v5]pad=%s:%s:%s:%s:0x00F8FF@0.2[v1];\
 [v1]rotate=\'%s*PI/180\':ow=\'max(iw,ih)\':oh=ow:c=none[v2];\
 [1][v2]overlay=\
 y=\'if(gte(t,%s), if(gte(t,%s), NAN,%s),NAN):\
 x=%s:shortest=1\'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k %s';

        $png_shell = sprintf($png_shell, $png, $video, $data['size_x'],

            $px,$py,$data['size_x']/2, $data['size_y']/2,
            $data['angle'], $data['bt'], $data['et'], $ny, $nx,$des_video);
        echo $png_shell;
        echo PHP_EOL;
        exec($png_shell);
//        unlink($png);
        //        unlink($video);//TODO 暂时保留视频,后期删除
        return $des_video_name;
    }

    /**
     * Notes:摇摆
     * User: zhangguofu
     * Date: 2021/4/22
     * Time: 15:03
     * @param $data array 对应的相关参数
     * @param $video string 对应的要处理的视频
     * @param $base_dir string 文件所在的目录
     */
    public function yaobai($data, $video, $base_dir)
    {
        $video = $base_dir . $video;
        $uuid = $this->getUuid();
        $png = $uuid;
        $png = $png . ".png";
        $png = $base_dir . $png;
        //下载gif素材
        exec("wget -c  {$data['pic_url']} -O  {$png}");
        $des_video_name = $uuid . ".mp4";
        $des_video = $base_dir . $des_video_name;

        //pad一个两倍的透明图像
        $px=$data['size_x']*2;
        $py=$data['size_y']*2;
        //计算pad后的坐标
        $nx=$data['coord_x']-$data['size_x']/2;
        $ny=$data['coord_y']-$data['size_y']/2;
        //旋转角度 和 大小,位置
        $png_shell = '
 ffmpeg -y  -loglevel  fatal -loop 1  -i %s  -i %s \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:%s[v5];\
 [v5]pad=%s:%s:%s:%s:0x00F8FF@0.2[v1];\
 [v1]rotate=\'%s*PI/180+(15*PI/180)*sin(2*PI/0.4*t)\':ow=\'max(iw,ih)\':oh=ow:c=none[v2];\
 [1][v2]overlay=\
 x=\'if(gte(t,%s), if(gte(t,%s), NAN,%s ),NAN ):\
 y=%s:shortest=1\'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k %s';
        //需要计算y的滑行速度,在规定时间内移动到终点
        $png_shell = sprintf($png_shell, $png, $video, $data['size_x'], $px,$py,$data['size_x']/2, $data['size_y']/2,$data['angle'],$data['bt'], $data['et'],

            $nx, $ny, $des_video);
        echo $png_shell;
        echo PHP_EOL;
        exec($png_shell);
//        unlink($png);
        //        unlink($video);//TODO 暂时保留视频,后期删除
        return $des_video_name;
    }


    /**
     * Notes:跳动
     * User: zhangguofu
     * Date: 2021/4/22
     * Time: 15:03
     * @param $data array 对应的相关参数
     * @param $video string 对应的要处理的视频
     * @param $base_dir string 文件所在的目录
     */
    public function tiaodong($data, $video, $base_dir)
    {
        $video = $base_dir . $video;
        $uuid = $this->getUuid();
        $png = $uuid;
        $png = $png . ".png";
        $png = $base_dir . $png;
        //下载gif素材
        exec("wget -c  {$data['pic_url']} -O  {$png}");
        $des_video_name = $uuid . ".mp4";
        $des_video = $base_dir . $des_video_name;
        //跳动的时间计算
        $speed=$data['et']-$data['bt'];

        //向上跳动距离,y点距离定点的一半距离
        $jump=$data['coord_y']/1.3;
        $time_dur=2*$jump/600;
//        dd($time_dur);

        $px=$data['size_x']*2;
        $py=$data['size_y']*2;
        $nx=$data['coord_x']-$data['size_x']/2;
        $ny=$data['coord_y']-$data['size_y']/2;
        //旋转角度 和 大小,位置
        $png_shell = '
 ffmpeg -y  -loglevel  fatal -loop 1  -i %s  -i %s \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:%s[v5];\
 [v5]pad=%s:%s:%s:%s:0x00F8FF@0.2[v1];\
 [v1]rotate=%s*PI/180:ow=\'max(iw,ih)\':oh=ow:c=none[v2];\
 [1][v2]overlay=x=\'if(gte(t,%s), if(gte(t,%s), NAN,%s),NAN ):y=if(gte(t,%s),%s,min(%s-%s*sin((t-%s)*3/%s),%s)):shortest=1\'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k %s';
        //需要计算y的滑行速度,在规定时间内移动到终点
        $png_shell = sprintf($png_shell, $png, $video, $data['size_x'],

            $px,$py,$data['size_x']/2, $data['size_y']/2,

            $data['angle'],$data['bt'], $data['et'],

            $nx,

           $data['bt']+2*$time_dur,
            $ny,$ny,
            $jump,$data['bt'],$time_dur,$ny,$des_video);
        echo $png_shell;
        echo PHP_EOL;
        exec($png_shell);
//        unlink($png);
        //        unlink($video);//TODO 暂时保留视频,后期删除
        return $des_video_name;
    }

    public function tiaodong1($data, $video, $base_dir)
    {
        $video = $base_dir . $video;
        $uuid = $this->getUuid();
        $png = $uuid;
        $png = $png . ".png";
        $png = $base_dir . $png;
        //下载gif素材
        exec("wget -c  {$data['pic_url']} -O  {$png}");
        $des_video_name = $uuid . ".mp4";
        $des_video = $base_dir . $des_video_name;
        //跳动的时间计算
        $speed=$data['et']-$data['bt'];

        //向上跳动距离,y点距离定点的一半距离
        $jump=$data['coord_y']/1.3;
        //旋转角度 和 大小,位置
        $png_shell = '
 ffmpeg -y  -loglevel  fatal -loop 1  -i %s  -i %s \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:%s[v1];\
 [v1]rotate=%s*PI/180:ow=\'max(iw,ih)\':oh=ow:c=none[v2];\
 [1][v2]overlay=x=\'if(gte(t,%s), if(gte(t,%s), NAN,%s),NAN ):y=%s-%s*sin((t-%s)*3/%s):shortest=1\'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k %s';
        //需要计算y的滑行速度,在规定时间内移动到终点
        $png_shell = sprintf($png_shell, $png, $video, $data['size_x'], $data['angle'],$data['bt'], $data['et'],

            $data['coord_x'],

            $data['coord_y'],$jump,$data['bt'],$speed,$des_video);
        echo $png_shell;
        echo PHP_EOL;
        exec($png_shell);
//        unlink($png);
        //        unlink($video);//TODO 暂时保留视频,后期删除
        return $des_video_name;
    }



    /**
     * Notes:雨刷
     * User: zhangguofu
     * Date: 2021/4/22
     * Time: 15:03
     * @param $data array 对应的相关参数
     * @param $video string 对应的要处理的视频
     * @param $base_dir string 文件所在的目录
     */
    public function yushua($data, $video, $base_dir)
    {
        $video = $base_dir . $video;
        $uuid = $this->getUuid();
        $png = $uuid;
        $png = $png . ".png";
        $png = $base_dir . $png;
        //下载gif素材
        exec("wget -c  {$data['pic_url']} -O  {$png}");
        $des_video_name = $uuid . ".mp4";
        $des_video = $base_dir . $des_video_name;

        //pad一个两倍的透明图像,为了防止边缘溢出,再扩大0.8倍,中心点对应 移动0.4
        $px=$data['size_x']*2.8;
        $py=$data['size_y']*2.8;
        //计算pad后的坐标
        $nx=$data['size_x']*0.4;
        $ny=$data['size_y']*0.4;

        //要根据旋转角度和边长计算出 补偿距离 中心点旋转的,但是 本特效会认为是 右下角旋转,导致中心点移动,所以需要转换
        $give_data=$this->getGiveData($data);
//        dd($give_data);
        $give_nx=$give_data['x'];
        $give_ny=$give_data['y'];
        //旋转角度 和 大小,位置
        $png_shell = '
 ffmpeg -y  -loglevel  fatal -loop 1  -i %s  -i %s \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:%s[v5];\
 [v5]pad=%s:%s:%s:%s:0x00F8FF@0.2[v1];\
 [v1]rotate=\'%s*PI/180-0.4*sin(8*PI/5*(t-%s))\':ow=\'max(iw,ih)\':oh=ow:c=none[v2];\
 [1][v2]overlay=\
 x=\'if(gte(t,%s), if(gte(t,%s), NAN,%s ),NAN ):\
 y=%s:shortest=1\'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k %s';
        //需要计算y的滑行速度,在规定时间内移动到终点
        $png_shell = sprintf($png_shell, $png, $video, $data['size_x'], $px,$py,$nx,$ny,$data['angle'],$data['bt'],$data['bt'],$data['et'],$data['coord_x']-$nx-$give_nx,$data['coord_y']-$ny-$give_ny,$des_video);
        echo $png_shell;
        echo PHP_EOL;
        exec($png_shell);
//        unlink($png);
        //        unlink($video);//TODO 暂时保留视频,后期删除
        return $des_video_name;
    }


    /**
     * Notes:轻微跳动
     * User: zhangguofu
     * Date: 2021/4/22
     * Time: 15:03
     * @param $data array 对应的相关参数
     * @param $video string 对应的要处理的视频
     * @param $base_dir string 文件所在的目录
     */
    public function xiaotiao($data, $video, $base_dir)
    {
        $video = $base_dir . $video;
        $uuid = $this->getUuid();
        $png = $uuid;
        $png = $png . ".png";
        $png = $base_dir . $png;
        //下载gif素材
        exec("wget -c  {$data['pic_url']} -O  {$png}");
        $des_video_name = $uuid . ".mp4";
        $des_video = $base_dir . $des_video_name;

        //pad一个两倍的透明图像
        $px=$data['size_x']*2;
        $py=$data['size_y']*2;
        //计算pad后的坐标
        $nx=$data['coord_x']-$data['size_x']/2;
        $ny=$data['coord_y']-$data['size_y']/2;
        //旋转角度 和 大小,位置
        $png_shell = '
 ffmpeg -y  -loglevel  fatal -loop 1  -i %s  -i %s \
 -filter_complex "\
 [0]format=pix_fmts=rgba[v0];\
 [v0]scale=-1:%s[v5];\
 [v5]pad=%s:%s:%s:%s:0x00F8FF@0.2[v1];\
 [v1]rotate=\'%s*PI/180+sin(PI*(2*(t-%s)))*0.15\':ow=\'max(iw,ih)\':oh=ow:c=none[v2];\
 [1][v2]overlay=x=\'if(gte(t,%s), if(gte(t,%s), NAN,%s),NAN ):y=%s:shortest=1\'\
 [v3]" -map [v3]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k %s';
        //需要计算y的滑行速度,在规定时间内移动到终点
        $png_shell = sprintf($png_shell, $png, $video, $data['size_x'], $px,$py,$data['size_x']/2, $data['size_y']/2,$data['angle'],$data['bt'],$data['bt'] ,$data['et'],

            $nx, $ny,$des_video);
        echo $png_shell;
        echo PHP_EOL;
        exec($png_shell);
//        unlink($png);
        //        unlink($video);//TODO 暂时保留视频,后期删除
        return $des_video_name;
    }



    /**
     * Notes:弹入
     * User: zhangguofu
     * Date: 2021/4/22
     * Time: 15:03
     * @param $data array 对应的相关参数
     * @param $video string 对应的要处理的视频
     * @param $base_dir string 文件所在的目录
     */
    public function tanru($data, $video, $base_dir)
    {
        $video = $base_dir . $video;
        $uuid = $this->getUuid();
        $png = $uuid;
        $png = $png . ".png";
        $png = $base_dir . $png;
        //下载gif素材
        exec("wget -c  {$data['pic_url']} -O  {$png}");
        $des_video_name = $uuid . ".mp4";
        $des_video = $base_dir . $des_video_name;

        //pad一个两倍的透明图像
        $px=$data['size_x']*6;
        $py=$data['size_y']*6;
        //计算pad后的坐标
        $nx=$data['coord_x']-$data['size_x']*2.5;
        $ny=$data['coord_y']-$data['size_y']*2.5;

        //逻辑概述,先pad 一个比 最终尺寸大6倍的图层,然后让素材在图层居中;
        // 然后对于上述的图层 缩小 0.2倍,为什么是0.2 0.2*6=1.2 刚好可以盖住素材底,
        //然后对素材进行缩小放大的操作,最后执行  放大倍数,试的相乘等于1,还原到最终尺寸

        //  [v6]scale=-1:'720+750*min(t-1,1)':eval=frame[v7];\
        //放大20%
        $speed=$px-0.4*$px;
        //旋转角度 和 大小,位置
        $png_shell = '
 ffmpeg -y -loop 1  -i  %s  -i %s \
  -filter_complex "\
  [0]format=pix_fmts=rgba[v0];\
  [v0]scale=-1:%s[v5];\
  [v5]pad=%s:%s:%s:%s:0x00F8FF@0.2[v6];\
  [v6]scale=-1:\'%s+%s*min(t-%s,0.5)\':eval=frame[v7];\
  [v7]rotate=\'%s*PI/180\':ow=\'max(iw,ih)\':oh=ow:c=none[v1];\
  [1][v1]overlay=\
  x=\'if(gte(t,%s), if(gte(t,%s), NAN,%s ),NAN ):\
  y=%s:shortest=1\'[v2]" \
  -map [v2]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k %s
 ';
        //需要计算y的滑行速度,在规定时间内移动到终点
        // ,$px*0.4*2   0.5s
        $png_shell = sprintf($png_shell, $png, $video,$data['size_x'],$px,$py,$data['size_x']*2.5,$data['size_y']*2.5,$px*0.4,2*$speed,$data['bt'],$data['angle'],$data['bt'],$data['et'],$nx,$ny,$des_video);
        echo $png_shell;
        echo PHP_EOL;
        exec($png_shell);
//        unlink($png);
        //        unlink($video);//TODO 暂时保留视频,后期删除
        return $des_video_name;
    }



    /**
     * Notes:弹入
     * User: zhangguofu
     * Date: 2021/4/22
     * Time: 15:03
     * @param $data array 对应的相关参数
     * @param $video string 对应的要处理的视频
     * @param $base_dir string 文件所在的目录
     */
    public function tanru1($data, $video, $base_dir)
    {
        $video = $base_dir . $video;
        $uuid = $this->getUuid();
        $png = $uuid;
        $png = $png . ".png";
        $png = $base_dir . $png;
        //下载gif素材
        exec("wget -c  {$data['pic_url']} -O  {$png}");
        $des_video_name = $uuid . ".mp4";
        $des_video = $base_dir . $des_video_name;

        //pad一个两倍的透明图像
        $px=$data['size_x']*2;
        $py=$data['size_y']*2;
        //计算pad后的坐标
        $nx=$data['coord_x']-$data['size_x']/2;
        $ny=$data['coord_y']-$data['size_y']/2;


        //放大20%
        $speed=$data['size_x']*0.2;

        //旋转角度 和 大小,位置
        $png_shell = '
 ffmpeg -y -loop 1  -i  %s  -i %s \
  -filter_complex "\
  [0]format=pix_fmts=rgba[v0];\
  [v0]scale=-1:%s[v5];\
  [v5]pad=%s:%s:%s:%s:0x00F8FF@0.2[v6];\
  [v6]scale=-1:\'%s+%s*min(t-%s,1)\':eval=frame[v7];\
  [v7]rotate=\'%s*PI/180\':ow=\'max(iw,ih)\':oh=ow:c=none[v1];\
  [1][v1]overlay=\
  x=\'if(gte(t,%s), if(gte(t,%s), NAN,%s ),NAN ):\
  y=%s:shortest=1\'[v2]" \
  -map [v2]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k %s
 ';
        //需要计算y的滑行速度,在规定时间内移动到终点
        $png_shell = sprintf($png_shell, $png, $video,$data['size_x'],$px,$py,$data['size_x']/2,$data['size_y']/2,$px,$speed,$data['bt'],$data['angle'],$data['bt'],$data['et'],$nx,$ny,$des_video );
        echo $png_shell;
        echo PHP_EOL;
        exec($png_shell);
//        unlink($png);
        //        unlink($video);//TODO 暂时保留视频,后期删除
        return $des_video_name;
    }

    /**
     * Notes:弹簧
     * User: zhangguofu
     * Date: 2021/4/22
     * Time: 15:03
     * @param $data array 对应的相关参数
     * @param $video string 对应的要处理的视频
     * @param $base_dir string 文件所在的目录
     */
    public function tanhuang($data, $video, $base_dir)
    {
        $video = $base_dir . $video;
        $uuid = $this->getUuid();
        $png = $uuid;
        $png = $png . ".png";
        $png = $base_dir . $png;
        //下载gif素材
        exec("wget -c  {$data['pic_url']} -O  {$png}");
        $des_video_name = $uuid . ".mp4";
        $des_video = $base_dir . $des_video_name;

        //pad一个两倍的透明图像
        $px = $data['size_x'] * 6;
        $py = $data['size_y'] * 6;
        //计算pad后的坐标
        $nx = $data['coord_x'] - $data['size_x'] * 2.5;
        $ny = $data['coord_y'] - $data['size_y'] * 2.5;

        //逻辑概述,先pad 一个比 最终尺寸大6倍的图层,然后让素材在图层居中;
        // 然后对于上述的图层 缩小 0.2倍,为什么是0.2 0.2*6=1.2 刚好可以盖住素材底,
        //然后对素材进行缩小放大的操作,最后执行  放大倍数,试的相乘等于1,还原到最终尺寸


        $dur = 2;
        $per_dur = $dur / 20;
        $time1 = $per_dur * 5;
        $speed1 = (4.5 * $data['size_x']) / $time1;//已经有一个默认的值了,需要再增加到6个值,显示正常尺寸
        $time_start2 = $data['bt'] + $time1;
        $time_start3 = $time_start2 + $time1;
        $time_start4 = $time_start3 + $time1;
        $time4=$per_dur*3;

        $time_start5 = $time_start4 + $time4;


        $size_2 = 6 * $data['size_x'];//第一次回复至默认大小
        $speed2 = (6 * $data['size_x'] * 0.6) / $time1;

        $size_3 = 6 * $data['size_x'] * 0.4;
        $speed3 = (6 * $data['size_x'] * 0.4) / $time1;

        $size_4 = 6 * $data['size_x'] * 0.9;
        $speed4 = (6 * $data['size_x'] * 0.2) / $time4;

        $size5= 6 * $data['size_x'] * 0.7;

//        dd($speed1);
        //旋转角度 和 大小,位置
        $png_shell = ' ffmpeg -y -loop 1  -i  %s  -i %s \
  -filter_complex "\
  [0]format=pix_fmts=rgba[v0];\
  [v0]scale=-1:%s[v5];\
  [v5]pad=%s:%s:%s:%s:0x00F8FF@0.2[v6];\
  [v6]scale=-1:\'\
  if(lte(t-%s,%s),%s+%s*(t-%s),\
  if(lte(t-%s,%s),%s-%s*(t-%s),\
  if(lte(t-%s,%s),%s+%s*(t-%s),\
  if(lte(t-%s,%s),%s-%s*(t-%s),\
  %s))))
  \':eval=frame[v7];\
  [v7]rotate=\'%s*PI/180\':ow=\'max(iw,ih)\':oh=ow:c=none[v1];\
  [1][v1]overlay=\
  x=\'if(gte(t,%s), if(gte(t,%s), NAN,%s ),NAN ):\
  y=%s:shortest=1\'[v2]" \
  -map [v2]  -vcodec libx264 -ac 2 -ar 44100 -b:v 3000k %s
 ';
        //需要计算y的滑行速度,在规定时间内移动到终点
        $png_shell = sprintf($png_shell, $png, $video, $data['size_x'],
            $px, $py, $data['size_x'] * 2.5, $data['size_y'] * 2.5,
            $data['bt'],
            $time1,
            1.5*$data['size_x'],//初始化 如果刚好是 1倍的情况,有时候会盖不上,所以增加0.5,速度 减少0.5,即4.5
            $speed1,
            $data['bt'],

            $time_start2,
            $time1,
            $size_2,
            $speed2,
            $time_start2,

            $time_start3,
            $time1,
            $size_3,
            $speed3,
            $time_start3,

            $time_start4,
            $time4,
            $size_4,
            $speed4,
            $time_start4,

            $size5,

            $data['angle'],
            $data['bt'],
            $data['et'],
            $nx, $ny,
            $des_video,
        );
        echo $png_shell;
        echo PHP_EOL;
        exec($png_shell);
//        unlink($png);
        //        unlink($video);//TODO 暂时保留视频,后期删除
        return $des_video_name;
    }



    /**
     * Notes:获取素材的完整地址
     * User: zhangguofu
     * Date: 2021/4/21
     * Time: 11:13
     * @param $data
     * @return mixed
     */

    public function getFodderUrl($data)
    {

        $res = DB::connection("mysql_dev")->table('cnk_ugc_fodder')->select(['wav_url','pic_url','type'])->where(['id'=>$data['f_id']])->first();

        $data['wav_url']=self::FILE.$res->wav_url;
        $data['pic_url']=self::FILE.$res->pic_url;
        $data['type']=$res->type;
        return $data;

    }

    /**
     * Notes:计算出 由于雨刷导致中心点偏移的宽和高
     * User: zhangguofu
     * Date: 2021/5/10
     * Time: 15:05
     * @param $data
     */
    public function getGiveData($data)
    {
        $l=$data['size_x'];//边长
        $angle=$data['angle'];//旋转角度

        $angle1=45+$angle;
        $angle1=deg2rad($angle1);
        //计算对角线长度
        $l1=sqrt(2*$l*$l);
//        dd($l1);
        //对角线一半
        $l1=$l1/2;
        //根据sin和consin计算 两个直角边
//        dd(sin(deg2rad(30)));
        $duibian=$l1*sin($angle1);
        $linbian=$l1*cos($angle1);

        //先计算出 右下角 点的位子
        $dx=$data['size_x']+$data['coord_x'];
        $dy=$data['size_y']+$data['coord_y'];
        //计算出移动后 中心点坐标(雨刷右下角固定不变)
        $nx=$dx-$linbian;
        $ny=$dy-$duibian;

        // 计算原来中心点的x和y
        $ox=$data['size_x']/2+$data['coord_x'];
        $oy=$data['size_y']/2+$data['coord_y'];


        $move_y=$ny-$oy;//y轴移动距离
        $move_x=$nx-$ox;//x轴移动距离
        $data['x']=$move_x;
        $data['y']=$move_y;
//        dd($data);
        return $data;
    }


    /**
     * Notes:获取分组的时间
     * User: zhangguofu
     * Date: 2021/4/21
     * Time: 10:35
     */
    public function getTime()
    {
      $obj= DB::connection("mysql_dev")->table('cnk_ugc_video_make')->where("aid",self::TEST_ID)->first();
//      dd($obj);
      $str=$obj->real_content;
       $res=json_decode($str,1);
//        dd($res);
        $data=[];
        foreach ($res as $v){
            if ($v['status'] !=="normal"){
                continue;
            }
            if (empty($v['texture'])){
                continue;
            }
            $bt=$v['bt_number'];
            $et=$v['et_number'];
//            dd($v['texture']);
            foreach ($v['texture'] as $vv){
                $data1=$vv;
                $data2=['bt'=>$bt,'et'=>$et];
                $data_3=array_merge($data1,$data2);
                $data[]=$data_3;
            }
//            dd($data);
//            $data[]=$v;
        }
//        dd($data);
        $group =array_column($data,"id");
        $group=array_unique($group);
//        dd($group);
        $new_d=[];//得到id分组后的数组
        foreach ($group as $k=>$v){
            foreach ($data as $vv){
                if ($v===$vv['id']){
                    $new_d[$k][]=$vv;
                }
            }
        }

//        dd($new_d);
        $end_datas=[];
//        var_export($new_d);die;
        //找到分组内的最大值和最小值
        foreach ($new_d as $k=>$v){
            $e_max=0;//获取结束时间最大值
            $b_min = 99999999999999;//获取开始时间最小值
            foreach ($v as $vv) {
//                dd($e_max,$vv['et']);
//                var_export($vv);
                $e_max = max($e_max, $vv['et']);
                $b_min = min($b_min, $vv['bt']);
                //转化为数字
//                dd($e_max);
            }
//            dd($v);
            $end_data = $v[0];
            $end_data['bt'] = $b_min;//开始的最小值
            $end_data['et'] = $e_max;//结束的最大值
            $end_datas[$k] = $end_data;
        }
//        dd($end_datas);
        return $end_datas;
    }

    /**
     * Notes:返回毫秒级时间戳格式
     * User: zhangguofu
     * Date: 2021/4/21
     * Time: 15:37
     * @param $str
     * @return float|int|mixed|string
     */
    public function getNumTime($str)
    {
//        echo $str;
//        echo PHP_EOL;
        $arr = explode(".", $str);

        $time_arr = explode(':', $arr[0]);
//        dd($time_arr);
        //小时
        $h = $time_arr[0];
        //分钟
        $m = $time_arr[1];
//        dd($m);
        //秒
        $s = $time_arr[2];
        $total = $h * 3600 + $m * 60 + $s;
        //毫秒计算
        if (isset($arr[1]) && !empty($arr[1])) {
            $total = $h * 3600 + $m * 60 + $s + $arr[1] / 1000;
        }
        return $total;
    }


    /**
     * Notes:语音特效合成
     * User: zhangguofu
     * Date: 2021/5/19
     * Time: 19:08
     * @param $base_dir string 文件公共目录
     * @param $origin_video string 视频文件名
     * @param $arr array 特效音频数据
     * @param $obj TxOnlineCommand  特效音频数据
     */
    public function mergeVoice($base_dir,$origin_video,$arr,$obj)
    {
        $rand=$this->getUuid();
        $d_video=$base_dir.$origin_video;
        $wav=$rand.".mp3";
        $des_wav=$base_dir.$wav;
        $wav_end=$rand."_end.mp3";
        $des_wav_end=$base_dir.$wav_end;
        $wav_stardard=$rand."_stardard.mp3";
        $des_wav_stardard=$base_dir.$wav_stardard;

        $shell="ffmpeg -y -loglevel error -i {$d_video} -b:a 192K -vn {$des_wav}";
        exec($shell);
        $shell="ffmpeg -y -loglevel error -i {$d_video} -b:a 192K -vn {$des_wav}";
        exec($shell);
        $input='';
        $vi=1;
        $filter='';
        $filter2='';
        foreach ($arr as $v) {
            //加入音效效,
            $v = $obj->getFodderUrl($v);
            if ($v['type'] == self::TYPE_GIF) {
//              var_export($v);
                if (!empty($v['wav_url'])){
                    $time=$v['bt']*1000;
                    $input.="-i {$v['wav_url']} ";
                    $filter.=" [{$vi}]adelay=$time|$time,volume='1'[w{$vi}];";
                    $filter2.="[w{$vi}]";
                    $vi++;
                }

            }
        }
        //开始合成音效
        $str='
ffmpeg -y -loglevel error -i %s \
%s \
 -filter_complex "[0]volume=\'1\'[w0]; \
 %s \
 [w0]%samix=inputs=%s:duration=first:dropout_transition=120" -f mp3 %s
';

        if (!empty($vi)){
            $wav_shell=sprintf($str,$base_dir.$wav,$input,$filter,$filter2,$vi,$des_wav_end);
            echo $wav_shell;
            exec($wav_shell);

            $stardard_shell="ffmpeg -i $des_wav_end -af loudnorm=I=-16:LRA=11:tp=-1.5 -y $des_wav_stardard ";
            echo $stardard_shell;
            exec($stardard_shell);
        }

        return $wav_stardard;
    }


    public function getUuid()
    {
        //生成自定义文件名
//        $uuid=CnkHealthyCateService::uuid(5);
//        $random=time().$uuid;
//
        $uuid = uuid4();
        return $uuid;
    }
}

相关问题总结和思考
旋转之后左上角的位置怎么确定?

声音加入,音量标准统一


KKView远程控制

2024远程控制领域的新晋黑马,安全连接,KKView远程控制,远程好帮手。其全功能免费不限设备数量政策,在办公一族迅速传播,争相使用。其一键看远程桌面,一键打开远程手机电脑摄像头,无限制急速文件传输,远程终端,远程关机重启等39项功能彻底打破办公居家时间空间限制,实现连接自由,深受用户好评。KKView官网或华为等各大应用市场可下载使用。
在这里插入图片描述

KKView远程控制一键远程控制,可无插件控制安卓手机、电脑

曲折历史
png展示行不行?gif展示行不行?运动行不行?旋转行不行?抖动行不行?

作者:张清柏
链接:https://www.jianshu.com/p/e21f9df6678b

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/641789.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Pandas高效数据清洗与转换技巧指南【数据预处理】

三、数据处理 1.合并数据&#xff08;join、merge、concat函数&#xff0c;append函数&#xff09; Concat()函数使用 1.concat操作可以将两个pandas表在垂直方向上进行粘合或者堆叠。 join属性为outer&#xff0c;或默认时&#xff0c;返回列名并集&#xff0c;如&#xff…

day34 贪心算法 455.分发饼干 376. 摆动序列

贪心算法理论基础 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 贪心一般解题步骤&#xff08;贪心无套路&#xff09;&#xff1a; 将问题分解为若干个子问题找出适合的贪心策略求解每一个子问题的最优解将局部最优解堆叠成全局最优解 455.分发饼干 …

2024年最全的信息安全、数据安全、网络安全标准分享(可下载)

以上是资料简介和目录&#xff0c;如需下载&#xff0c;请前往星球获取&#xff1a;https://t.zsxq.com/Gz1a0

Unity3D雨雪粒子特效(Particle System)

系列文章目录 unity工具 文章目录 系列文章目录&#x1f449;前言&#x1f449;一、下雨的特效1-1.首先就是创建一个自带的粒子系统,整几张贴图,设置一下就能实现想要的效果了1-2 接着往下看视频效果 &#x1f449;二、下雪的特效&#x1f449;三、下雪有积雪的效果3-1 先把控…

基于Android studio 订餐、外卖系统

目录 项目介绍 图片展示 运行环境 获取方式 项目介绍 具有登录&#xff0c;注册&#xff0c;修改密码&#xff0c;查看关于开发信息(可以填写自己的信息) 我的&#xff1a;可以查看菜品详情&#xff0c;填写份数&#xff0c;加入购物车&#xff0c; 购物车&#xff1a;可…

ElasticSearch操作之重置密码脚本

ElasticSearch操作之重置密码脚本 #!/bin/bash # 使用样例 ./ES密码重置.sh 旧密码 新密码# 输入旧密码 es_old_password$1# 设置新的密码变量 es_password$2# 正确响应 es_reponse{"acknowledged":true}# 检查Elasticsearch是否在运行 if pgrep -f elasticsearch &g…

Java订餐系统源码 springboot点菜系统源码

Java订餐系统源码 springboot点菜系统源码 源码下载地址&#xff1a;https://download.csdn.net/download/xiaohua1992/89341358 功能介绍&#xff1a; 前台登录&#xff1a;前台登录&#xff1a; ①首页&#xff1a;菜品信息推荐、菜品信息展示、查看更多 ②菜品信息&…

IPIDEA与您分享:代理IP究竟是如何保护用户隐私的?

在信息化、网络化的今天&#xff0c;互联网已成为人们生活中不可或缺的一部分。无论是日常沟通、学习工作&#xff0c;还是娱乐休闲&#xff0c;网络都扮演着举足轻重的角色。然而&#xff0c;随着网络活动的增加&#xff0c;网络安全问题也日益凸显&#xff0c;为了保护个人隐…

Vue速成学习笔记

这两天速成了一下Vue&#xff0c;在这里记录一下相关的笔记&#xff0c;之后有时间详细学Vue的时候再来回顾一下&#xff01; 一、Vue理解 1、Vue的核心特征&#xff1a;双向绑定。 在网页中&#xff0c;存在视图和数据。在Vue之前&#xff0c;需要使用JavaScript编写复杂的逻…

vue 打印、自定义打印、页面打印、隐藏页眉页脚

花了一天时间搞了个打印功能&#xff0c;现则将整体实现过程进行整理分享。先来看看效果图&#xff1a; 1、页面展示为&#xff1a; 2、重组页面打印格式为&#xff1a;这里重组页面的原因是客户要求为一行两列打印 &#xff01;内容过于多的行则独占一行显示完整。 整体实现&…

「探讨」:什么是网络审计?好用的网络审计系统推荐【图文详解】

网络是企业运营、政府管理、个人生活不可或缺的基础设施。 然而网络安全问题却日益凸显&#xff0c;数据泄露、网络攻击、欺诈行为等风险日益严重。 一、网络审计的定义 网络审计&#xff0c;又称信息技术审计或电子审计&#xff0c;是指审计人员运用专业技能和工具&#xff…

给我瞅瞅呀

专业 流程&#xff08;一条龙服务&#xff09; 需求沟通-需求分析-产品架构-ue原型-ui设计-产品研发-产品测试-产品交付-产品运维 保障 1、按需定制&#xff0c;签订功能清单&#xff0c;根据功能报价 2、价格透明&#xff0c;签订合同保障&#xff0c;保障客户合法权益 3、源…

智慧校园建设的进阶之路

智慧校园的建设现已到达了老练的阶段&#xff0c;许多学校设备充满着数字化信息&#xff0c;进出宿舍楼&#xff0c;校园一卡通体系会记载下学生信息&#xff0c;外来人员闯入会报警&#xff0c;翻开电脑就能查到学生是否在宿舍等……学生的学习和日子都充满了数字化的痕迹。但…

全域运营是本地生活服务的新模式吗?

最近&#xff0c;本地生活赛道又出现了一个新的说法&#xff0c;即全域运营是本地生活的下半场。事实上&#xff0c;这一论断并非空穴来风&#xff0c;而是有真凭实据。 作为多家互联网大厂重点布局的业务板块&#xff0c;本地生活的火爆程度早已有目共睹。根据多家互联网大厂…

【字典树 马拉车算法】336. 回文对

本文涉及知识点 字典树 马拉车算法 336. 回文对 给定一个由唯一字符串构成的 0 索引 数组 words 。 回文对 是一对整数 (i, j) &#xff0c;满足以下条件&#xff1a; 0 < i, j < words.length&#xff0c;i ! j &#xff0c;并且words[i] words[j]&#xff08;两个字…

huggingface 笔记:PretrainModel

1 from_pretrained 从预训练模型配置中实例化一个 PyTorch 预训练模型默认情况下&#xff0c;模型使用 model.eval() 设置为评估模式&#xff08;Dropout 模块被禁用&#xff09; 要训练模型&#xff0c;应该首先使用 model.train() 将其设置回训练模式 1.1 主要参数 pretra…

Python 渗透测试:Redis 数据库 弱密码测试.(6379端口)

什么是 Redis 数据库 Redis (Remote Dictionary Server) 是一个开源的、内存中的数据结构存储系统&#xff0c;它可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构,如字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等&#xff0…

抖音运营_如何做出优质的短视频

目录 一 短视频内容的构成 1 图像 2 字幕 3 声音 4 特效 5 描述 6 评论 二 短视频的热门类型 1 颜值圈粉类 2 知识教学类 3 幽默搞笑类 4 商品展示类 5 才艺技能类 6 评论解说类 三 热门短视频的特征 1 产生共鸣 2 正能量 3 紧跟热点话题 4 富有创意 四 短视…

Android 项目中自定义多个 RadioButton 并排一列选择效果实现

文章目录 1、静态版实现1.1、实现要求1.2、实现步骤1.3、代码实现1.4、代码实现说明1.5、结论 2、项目版实现(动态)1、先看效果图2、main的布局文件3、定义RadioButton的属性4、最后在代码中生成我想要的东东5、说明 3、后续优化方向 1、静态版实现 1.1、实现要求 我们需要在…

Java:图书管理系统

目录 一.book 1.在book包中的Book 类用来定义和引用书的名字&#xff0c;作者&#xff0c;价格&#xff0c;类型等。 2.在book包中的第二个类是BookList是用来构建书架&#xff0c;和书架上的初始书本&#xff0c; 二、ioperations 1.AddOperation (增加图书) 2.BorrowOp…