最近用ffmpeg做了一批视频模板供公司业务使用,结合shell脚本实现,常用的功能有如下几个:
- scale:缩放
- pad:填补
- drawtext:加文字
- ffprobe:获取视频一些属性
简单说几个可以实现的和未解决的:
1、scale之后出现尺寸与指定值不一致:需要设置setsar,前文有提到:https://blog.csdn.net/sayhelen/article/details/12427481422
2、pad和scale一起使用时,需要注意顺序,pad默认会补黑边,怎么样让最终结果即实现缩放又实现补透明呢?
第一,要先设置scale,在设置pad
第二,pad可以设置补的颜色和透明度,即颜色可以设置为RRGGBBAA,把A设置为0(即透明度100%即可,设置什么颜色都不重要了)
如下代码,实现载入图片按合适尺寸,顺时针/逆时针转动旋转效果:
input="xxx.jpeg"
output="rotate.mp4"
background="xxx.mp4"
let T=2
let RT=${T}*2
ffmpeg -loop 1 -t "${T}s" -i ${input} -i ${background} \
-filter_complex "[0]scale=720:-1,setsar=1[vr];\
[vr]scale=w='iw-(hypot(iw,ih)-iw)/(${T}*25)*n':h=-1:eval=frame,\
pad='hypot(iw,ih)':ow:(iw-ow)/2:(ih-oh)/2:color=0x00000000,\
rotate=a=n*PI/6/(${T}*25):ow='hypot(iw,ih)':oh=ow:c=0x00000000,split[vzi][vzo];\
[vzo]reverse[vs];[vzi][vs]concat=n=2:a=0:v=1[v1];\
[1][v1]overlay=(W-w)/2:(H-h)/2:shortest=1" \
-r 25 -t ${RT} -y ${output}
3、drawtext设置字号、颜色、边框等常规样式及行间距等都可以,换行常见有2种解法:
1)用textfile在外部txt文件里换行
2)定义多个drawtext,各自计算y值
还有一种说加换行符,我一直没找到怎么录入这个符号能起作用。
未解决的问题是设置斜体效果,部分情况下可以实现加粗(不是通过字体,而是用textfile形式设置bold属性)
4、ffprobe可以打印视频属性,我常用它来获取视频时长和宽高信息,我自己写了一个getMediaInfo.sh脚本获取某个目录下全部视频文件的帧率、码率、时长和宽高值,全文如下:
#!/bin/sh
# 使用while循环读取$1文本
outfile="/Users/xxx/Desktop/"
function read_dir(){
for file in `ls $1`
do
if [ -d $1"/"$file ] #注意此处之间⼀定要加上空格,否则会报错
then
read_dir $1"/"$file
elif [ -n $file ]; then
#判断是否读取到的数据是空行
#提取fps, width, height等
tmp_v=`echo $1"/"$file`
fps=`ffprobe -v quiet -select_streams v:0 -show_entries stream=avg_frame_rate -of default=noprint_wrappers=1:nokey=1 $tmp_v`
vrate=`ffprobe -v quiet -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 $tmp_v`
arate=`ffprobe -v quiet -select_streams a -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 $tmp_v`
duration=`ffprobe -v quiet -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $tmp_v`
size=`ffprobe -v quiet -select_streams v:0 -show_entries stream=height,width -of csv=s=x:p=0 $tmp_v`
outcome="$file $fps $vrate $arate $duration $size"
# outcome="$file $fps"fps" $vrate"kbps" $arate"kbps" $duration"s" $size"
echo $outcome
else
echo "current file is null"
# x=$x,"'"$tmp_v"'"
fi
echo $outcome >> ${outfile}/mediainfo.txt
done
}
read_dir $outfile