ffmpeg 转场滤镜 GL-Transitions 74种效果
#!/bin/bash # Example of concatenating multiple mp4s together with 1-second transitions between them. gltransition=( \ "angular" \ "Bounce" \ "BowTieHorizontal" \ "BowTieVertical" \ "BowTieWithParameter" \ "burn" \ "ButterflyWaveScrawler" \ "cannabisleaf" \ "circle" \ "CircleCrop" \ "circleopen" \ "colorphase" \ "ColourDistance" \ "CrazyParametricFun" \ "crosshatch" \ "crosswarp" \ "CrossZoom" \ "cube" \ "Directional" \ "directional-easing" \ "directionalwarp" \ "directionalwipe" \ "displacement" \ "DoomScreenTransition" \ "doorway" \ "Dreamy" \ "DreamyZoom" \ "fade" \ "fadecolor" \ "fadegrayscale" \ "FilmBurn" \ "flyeye" \ "GlitchDisplace" \ "GlitchMemories" \ "GridFlip" \ "heart" \ "hexagonalize" \ "InvertedPageCurl" \ "kaleidoscope" \ "LeftRight" \ "LinearBlur" \ "luma" \ "luminance_melt" \ "morph" \ "Mosaic" \ "multiply_blend" \ "perlin" \ "pinwheel" \ "pixelize" \ "polar_function" \ "PolkaDotsCurtain" \ "Radial" \ "randomNoisex" \ "randomsquares" \ "ripple" \ "rotate_scale_fade" \ "SimpleZoom" \ "squareswire" \ "squeeze" \ "StereoViewer" \ "swap" \ "Swirl" \ "tangentMotionBlur" \ "TopBottom" \ "undulatingBurnOut" \ "WaterDrop" \ "wind" \ "windowblinds" \ "windowslice" \ "wipeDown" \ "wipeLeft" \ "wipeRight" \ "wipeUp" \ "ZoomInCircles" \ ) length=${#gltransition[@]} interval=1 tpath="/ffmpeg/gl-transitions/transitions-20201217/" tpath="/ffmpeg/transitions/" x264="-look_ahead 0 -ac 2 -c:v h264_qsv -c:a aac -profile:v high -level 3.1 -preset:v veryfast" ki="-keyint_min 72 -g 72 -sc_threshold 0" br="-b:v 3000k -minrate 3000k -maxrate 6000k -bufsize 6000k -b:a 128k -avoid_negative_ts make_zero -fflags +genpts" duration=1 function get_duration_video_ffprobe(){ duration=$(ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=duration -of default=nokey=1:noprint_wrappers=1 "$1") duration=$(echo "scale=3; $duration/1"|bc -l) } function get_duration_audio_ffprobe(){ aduration=$(ffprobe -v error -count_frames -select_streams a:0 -show_entries stream=duration -of default=nokey=1:noprint_wrappers=1 "$1") aduration=$(echo "scale=3; $aduration/1"|bc -l) } MediaInfo="D:\soft\MediaInfo_CLI_19.04_Windows_x64\MediaInfo.exe" function get_duration_video_MediaInfo(){ # duration=$($MediaInfo --Inform="Video;%Duration/String3%" "$1") duration=$($MediaInfo --Inform="Video;%Duration%" "$1") duration=$(echo "scale=3; $duration/1000"|bc -l) } function get_duration_audio_MediaInfo(){ # duration=$($MediaInfo --Inform="Video;%Duration/String3%" "$1") aduration=$($MediaInfo --Inform="Audio;%Duration%" "$1") aduration=$(echo "scale=3; $aduration/1000"|bc -l) } # ls -u *.mp4 sort by time # ls *.mp4|sort sort by name line=-1 IFS=$(echo -en "\n\b") for f in `ls *.mp4|sort`; do line=$((line+1)) get_duration_video_MediaInfo "${f}" get_duration_audio_MediaInfo "${f}" ifd=`echo "scale=0; ${aduration}*1000-${duration}*1000"|bc -l -q` ifd=${ifd/.000/} echo ${line} ${f} ${duration} - ${aduration} = $ifd if [[ ${ifd} -le 0 ]]; then duration=${aduration} fi #echo ${line} ${f} ${duration} duration_array[${line}]=${duration} filename_array[${line}]=${f} index_array[${line}]=${line} done vfstr="" for i in ${index_array[@]}; do catlen=0$(echo "scale=3; ${duration_array[$i]}-${interval}/2"|bc -l) catlen2=0$(echo "scale=3; ${duration_array[$i]}-${interval}"|bc -l) catlenhalf=0$(echo "scale=3; ${interval}/2"|bc -l) if [ ${i} -lt ${line} ] then if [ ${i} -eq 0 ] then vfstr=${vfstr}"[$i:a]atrim=0:$catlen[a$i];" else vfstr=${vfstr}"[$i:a]atrim=$catlenhalf:$catlen2[a$i];" fi else vfstr=${vfstr}"[$i:a]atrim=$catlenhalf:$catlen[a$i];" fi vfstr=${vfstr}"[$i:v]split[v${i}00][v${i}10];" done for i in ${index_array[@]}; do catlen=0$(echo ${duration_array[$i]}-${interval}|bc -l) vfstr=${vfstr}"[v${i}00]trim=0:$catlen[v${i}01];" vfstr=${vfstr}"[v${i}10]trim=$catlen:${duration_array[$i]}[v${i}11t];" vfstr=${vfstr}"[v${i}11t]setpts=PTS-STARTPTS[v${i}11];" done for ((i=0; i<$line; ++i)) ; do Index=$[i%(($length))] #Index=$[RANDOM%(($length))] echo ${gltransition[$Index]} vfstr=${vfstr}"[v${i}11][v$((i+1))01]gltransition=duration=${interval}:source=${tpath}${gltransition[$Index]}.glsl[vt${i}];" done vfstr=${vfstr}"[v001]" for ((i=0; i<$line; ++i)) ; do vfstr=${vfstr}"[vt${i}]" done vfstr=${vfstr}"[v${line}11]concat=n=$((line+2))[outv];" for i in ${index_array[@]}; do vfstr=${vfstr}"[a${i}]" done vfstr=${vfstr}"concat=n=$((line+1)):v=0:a=1[outa]" infile="" for i in ${filename_array[@]}; do infile=${infile}" -i \"$i\"" done if [ ! -d "merge" ];then mkdir merge fi echo ${vfstr} > _vfstr_.txt cmd="ffmpeg -hide_banner${infile} \ -filter_complex_script \"_vfstr_.txt\" \ -map [outv] -map [outa] ${x264} ${ki} ${br} \ -y ./merge/ffmpeg-gl-transition-concat.mp4" echo $cmd >_merge_.cmd #./_merge_.cmd echo ${cmd} bash -c "$cmd"
转场效果参考 https://v.huya.com/play/469910857.html
缺点:需要消耗大量内存,连接视频数量60个以上时可能提示内存不够
官方的 ffmpeg 不带这个滤镜,增加该滤镜参考 https://github.com/transitive-bullshit/ffmpeg-gl-transition