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:softMediaInfo_CLI_19.04_Windows_x64MediaInfo.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 "
")
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

原文地址:https://www.cnblogs.com/nlsoft/p/14483182.html