利用ffmpeg的xfade转场滤镜把多个视频文件连接到一个文件的bash脚本
FFmpeg的xfade转场,现在一共有31种效果,2020年02月10日以后的FFmpeg代码中有效;
1 #!/bin/bash 2 # Example of concatenating multiple mp4s together with 1-second transitions between them. 3 4 transitions=( \ 5 "fade" \ 6 "wipeleft" \ 7 "wiperight" \ 8 "wipeup" \ 9 "wipedown" \ 10 "slideleft" \ 11 "slideright" \ 12 "slideup" \ 13 "slidedown" \ 14 "circlecrop" \ 15 "rectcrop" \ 16 "distance" \ 17 "fadeblack" \ 18 "fadewhite" \ 19 "radial" \ 20 "smoothleft" \ 21 "smoothright" \ 22 "smoothup" \ 23 "smoothdown" \ 24 "circleopen" \ 25 "circleclose" \ 26 "vertopen" \ 27 "vertclose" \ 28 "horzopen" \ 29 "horzclose" \ 30 "dissolve" \ 31 "pixelize" \ 32 "diagtl" \ 33 "diagtr" \ 34 "diagbl" \ 35 "diagbr" \ 36 ) 37 38 length=${#transitions[@]} 39 40 interval=1 41 42 x264="-look_ahead 0 -ac 2 -c:v h264_qsv -c:a aac -profile:v high -level 3.1 -preset:v veryfast" 43 ki="-keyint_min 72 -g 72 -sc_threshold 0" 44 br="-b:v 3000k -minrate 3000k -maxrate 6000k -bufsize 6000k -b:a 128k -avoid_negative_ts make_zero -fflags +genpts" 45 46 duration=1 47 function get_duration_video_ffprobe(){ 48 duration=$(ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=duration -of default=nokey=1:noprint_wrappers=1 "$1") 49 duration=$(echo "scale=3; $duration/1"|bc -l) 50 } 51 function get_duration_audio_ffprobe(){ 52 aduration=$(ffprobe -v error -count_frames -select_streams a:0 -show_entries stream=duration -of default=nokey=1:noprint_wrappers=1 "$1") 53 aduration=$(echo "scale=3; $aduration/1"|bc -l) 54 } 55 56 MediaInfo="D:\soft\MediaInfo_CLI_19.04_Windows_x64\MediaInfo.exe" 57 function get_duration_video_MediaInfo(){ 58 # duration=$($MediaInfo --Inform="Video;%Duration/String3%" "$1") 59 duration=$($MediaInfo --Inform="Video;%Duration%" "$1") 60 duration=$(echo "scale=3; $duration/1000"|bc -l) 61 } 62 function get_duration_audio_MediaInfo(){ 63 # duration=$($MediaInfo --Inform="Video;%Duration/String3%" "$1") 64 aduration=$($MediaInfo --Inform="Audio;%Duration%" "$1") 65 aduration=$(echo "scale=3; $aduration/1000"|bc -l) 66 } 67 68 # ls -u *.mp4 sort by time 69 # ls *.mp4|sort sort by name 70 line=-1 71 IFS=$(echo -en "\n\b") 72 for f in `ls *.mp4|sort`; do 73 line=$((line+1)) 74 get_duration_video_MediaInfo "${f}" 75 get_duration_audio_MediaInfo "${f}" 76 ifd=`echo "scale=0; ${aduration}*1000-${duration}*1000"|bc -l -q` 77 ifd=${ifd/.000/} 78 echo ${line} ${f} ${duration} - ${aduration} = $ifd 79 if [[ ${ifd} -le 0 ]]; then 80 duration=${aduration} 81 fi 82 #echo ${line} ${f} ${duration} 83 duration_array[${line}]=${duration} 84 filename_array[${line}]=${f} 85 index_array[${line}]=${line} 86 done 87 88 vfstr="" 89 for i in ${index_array[@]}; do 90 catlen=0$(echo ${duration_array[$i]}-${interval}|bc -l) 91 if [ ${i} -lt ${line} ] 92 then 93 vfstr=${vfstr}"[$i:a]atrim=0:$catlen[a$i];" 94 else 95 vfstr=${vfstr}"[$i:a]atrim=0:${duration_array[$i]}[a$i];" 96 fi 97 vfstr=${vfstr}"[$i:v]split[v${i}00][v${i}10];" 98 done 99 100 for i in ${index_array[@]}; do 101 catlen=0$(echo ${duration_array[$i]}-${interval}|bc -l) 102 vfstr=${vfstr}"[v${i}00]trim=0:$catlen[v${i}01];" 103 vfstr=${vfstr}"[v${i}10]trim=$catlen:${duration_array[$i]}[v${i}11t];" 104 vfstr=${vfstr}"[v${i}11t]setpts=PTS-STARTPTS[v${i}11];" 105 done 106 107 for ((i=0; i<$line; ++i)) ; do 108 Index=$[i%(($length))] 109 #Index=$[RANDOM%(($length))] 110 echo ${transitions[$Index]} 111 vfstr=${vfstr}"[v${i}11][v$((i+1))01]xfade=duration=${interval}:transition=${transitions[$Index]}[vt${i}];" 112 done 113 114 vfstr=${vfstr}"[v001]" 115 for ((i=0; i<$line; ++i)) ; do 116 vfstr=${vfstr}"[vt${i}]" 117 done 118 vfstr=${vfstr}"[v${line}11]concat=n=$((line+2))[outv];" 119 120 for i in ${index_array[@]}; do 121 vfstr=${vfstr}"[a${i}]" 122 done 123 vfstr=${vfstr}"concat=n=$((line+1)):v=0:a=1[outa]" 124 125 infile="" 126 for i in ${filename_array[@]}; do 127 infile=${infile}" -i \"$i\"" 128 done 129 130 if [ ! -d "merge" ];then 131 mkdir merge 132 fi 133 134 echo ${vfstr} > _vfstr_.txt 135 cmd="ffmpeg -hide_banner${infile} \ 136 -filter_complex_script \"_vfstr_.txt\" \ 137 -map [outv] -map [outa] ${x264} ${ki} ${br} \ 138 -y ./merge/ffmpeg-xfade-concat.mp4" 139 echo $cmd >_merge_.cmd 140 #./_merge_.cmd 141 142 echo ${cmd} 143 bash -c "$cmd"
更详细的参见 https://github.com/qq2225936589/xfade-ffmpeg-script
转场效果参见 https://v.huya.com/play/270325342.html