有关FFmpeg的安装可参看博文:【FFmpeg】安装与配置及简单测试;
有关FFmpeg实现jpg和互转可参看博文:【FFmpeg命令行】实现jpg与yuv的相互(批量)转码。
本文重点关注使用FFmpeg对图像音视频进行裁剪。
当前目录下有个宽高为353x500的000001_353x500.jpg
图像。
图片裁剪
ffmpeg -i 000001_353x500.jpg -vf crop=350:500:0:0 000001_350x500.jpg -y
-i
表示input,后接输入文件的url;
-vf
表示裁剪,crop=350:500:0:0
意味着以坐标(0,0)为起点,对000001_353x500.jpg
图片截取宽度为350,高度为500的图片;
输出图片名为000001_350x500.jpg
;
若输出文件名已存在,-y
表示自动覆盖。
图片缩放
ffmpeg -i 000001_353x500.jpg -vf 'scale=300:300' 000001_300x300.jpg
-i
为input file;
-vf
表示裁剪参数,scale=300:300
意味着将000001_353x500.jpg
图片压缩成300x300的图片。
当前目录下有mp3文件input.mp3
,从第10秒开始,向后截取15秒音频,并保存为output.mp3
:
ffmpeg -i input.mp3 -ss 00:00:10 -t 00:00:15 -acodec copy output.mp3
-i
表示input file;
-ss
表示截取音频的起始时间,hh:mm:ss;
-t
表示time,后接需要截取的音频的时间段,hh:mm:ss;
-acodec
表示音频编解码器,copy
输入音频 的编码格式;
当前目录下有mp4文件input.mp4
,从第0秒开始,向后截取10秒视频,并保存为output.mp4
:
ffmpeg -i input.mp4 -ss 00:00:00 -t 00:00:10 -vcodec copy -acodec copy output.mp4 -y
-i
表示input file;
-ss
表示截取视频的起始时间,hh:mm:ss;
-t
表示time,后接需要截取的视频的时间,hh:mm:ss;
-vcodec
表示视频编解码器,copy
输入视频的编码格式;
-acodec
表示音频编解码器,copy
输入音频的编码格式;
-y
表示自动覆盖。
关于音视频图像的批量处理,有两种基本解决思路(当然还有更多思路)。
第一种:
集成所有命令到一个bat文件,再执行bat文件以执行每条FFmpeg命令。
具体代码实现可参考博文:【FFmpeg命令行】实现jpg与yuv的相互(批量)转码。
第二种:
每生成一条FFmpeg命令便立即执行,不通过bat批处理文件。本文采用该方案。
有时进行图像编码前需要对图像进行处理,比如使用FFmpeg的x264库,要求图像的宽和高都必须是2的倍数,使用某些HEVC编解码器,要求边是8的倍数。因此,那些不符合特定要求的图像,需要裁剪。
PythonWare公司提供了免费的图像处理工具包PIL(Python Image Library),该软件包提供了基本的图像处理功能,我们可以借用该库读取图像大小。PIL历史悠久,原来是只支持python2.x的版本的,后来移植到了python3的库pillow,我安装了python3.7,安装命令为:
pip install pillow
新键py文件,导入包,读取某一文件夹下的所有图像,并依次判断其宽高是否符合倍数关系,若不符合执行裁剪命令并自动覆盖:
import os
from PIL import Image
labelFile_path=r"F:\datasets\x264_VOC2007\label_resize2"
resize_times=2 #宽高符合倍数
if not os.path.exists(labelFile_path):
print(labelFile_path+" 不存在!")
exit(0)
#change directory
os.chdir(labelFile_path)
#读取该目录下的所有文件名,以列表存储
labelFile_list=os.listdir(labelFile_path)
#循环遍历并依次判断
for labelFile in labelFile_list:
size=Image.open(labelFile).size
#不符合倍数
if size[0]%resize_times!=0 or size[1]%resize_times!=0:
cmd_resize="ffmpeg -i "+labelFile+" -vf crop="+\
str(size[0]-size[0]%resize_times)+":"+\
str(size[1]-size[1]%resize_times)+":0:0 "\
+labelFile+" -y"
# print(cmd_resize)
os.system(cmd_resize)
手上的视频太长了,不方便做测试,通常会进行批量裁剪。
代码类似,举一反三,不再赘述。
import os
import random
#原图像目录
labelOri_path=r"F:\SDDR\datasets\surveillance\label_origin"
#裁剪后目录
labelRetime_path=r"F:\SDDR\datasets\surveillance\label"
#裁剪记录日志
log=r"F:\SDDR\datasets\surveillance/log_retime.txt"
outf=open(log,"w")
os.chdir(labelOri_path)
labelOri_list=os.listdir(labelOri_path)
for ori in labelOri_list: #xxx.mp4
#随机选择起始点(所用视频集时长都为1分钟),截取10秒
cmd_retime="ffmpeg -i "+ori+" -ss 00:00:"+\
str(random.sample(range(10,51),1)[0])+" -t 00:00:10\
-vcodec copy -acodec copy "+labelRetime_path+"/"+ori+" -y"
#执行命令
os.system(cmd_retime)
print(cmd_retime)
outf.write(cmd_retime+"\n")
outf.close()
注:批量音频裁剪与前两者类似,聪明的你一定知道怎么做啦~
更多命令可查看官方文档。