FFmpeg是多媒体领域的万能工具。只要涉及音视频领域的处理,基本上没有它做不了的事情!通俗点讲,从视频录制、视频编辑再到播放,它都能做!
前段时间做了个短视频自动化脚本项目,需要自动处理音视频(包括一些合成、拼接、转场、调色等等),当时做的时候找各种命令还是很痛苦的,因此对用到的所有处理命令做了个汇总,方便以后使用。
目录
一、获取音频时长
二、获取视频信息
三、 获取视频时长
四、多个视频合并
五、视频提取视频(保留无音频的视频) 视频地址 导出地址
六、合成 音频 + 视频
七、合成 音频 + 视频 保留原声
八、 添加字幕
十、 分割视频 视频地址 导出地址 开始位置 持续时长
十一、 视频添加水印图片(png全透明)
十二、 视频添加mov动画(mov全透明)
十三、修改视频帧数
十四、修改亮度 s饱和度 b 亮度
十五 图片转视频
十六、图片添加文字 图片地址 水印文本 字体大小 导出图片地址
十七、视频音量修改 视频地址 音频 导出地址
十八、视频添加图片水印 视频地址 图片地址 导出视频地址
十九、视频提取音频(保留音频) 视频地址 音频地址
二十、音频淡入淡出
二十一、 合并视频 (多个写入文件)
二十二、视频画中画 (图片+视频)
def __getAudioLength(self, path):
clip = AudioFileClip(path)
duration = clip.duration
clip.close()
return duration
def __getVideoInfo(self, videoPath):
cap = cv2.VideoCapture(videoPath)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) # 分辨率-宽度
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # 分辨率-高度
fps = int(cap.get(cv2.CAP_PROP_FPS)) # 帧速率
return {
'width': width,
'height': height,
'fps': fps
}
def __getVideoLength(self, path):
try:
clip = VideoFileClip(path)
duraton = clip.duration
clip.close()
return duraton
except:
print('===================== 无法获取时长.....')
return 2
def __mergeAllVideo(self, resPathList, outPath):
video_clip_list = []
singleList = []
for resP in resPathList:
print(resP)
clip = VideoFileClip(resP)
video_clip_list.append(clip)
singleList.append(clip)
video = concatenate_videoclips(video_clip_list)
video.to_videofile(outPath, remove_temp=True)
video.close()
for single in singleList:
single.close()
def __getNoAudioWithVideo(self, videoPath, outPath):
command = f'ffmpeg -y -i "{videoPath}" -vcodec copy -an "{outPath}"'
os.system(command)
def __composeAudioAndVideo(self, videoPath, audioPath, outPath, timer):
command = f'ffmpeg -y -i "{videoPath}" -i "{audioPath}" -c:v copy -c:a aac -strict experimental -t {timer} "{outPath}"'
os.system(command)
def __composeAudioAndVideo2(self, videoPath, audioPath, outPath, timer):
command = fr'ffmpeg -hide_banner -i "{videoPath}" -i "{audioPath}" -filter_complex "amix=inputs=2:duration=first:dropout_transition=0" -c:a "aac" -t {timer} -y "{outPath}"'
os.system(command)
def __addVideoWithSrt(self, videoPath, srtPath, outPath):
srtPath = srtPath.replace('\\', '/')
command = f'''ffmpeg -i "{videoPath}" -lavfi subtitles='"{srtPath}"':force_style='Fontname=华康POP3体W12,Outline=1.5,Fontsize=13,Alignment=2,MarginV=80' -y "{outPath}"'''
os.system(command)
def __cutVideo(self, videoPath, outPath, startTime, length):
# command = f'ffmpeg -y -ss {startTime} -t {length} -i "{videoPath}" -vcodec copy -acodec copy "{outPath}"'
command = f'ffmpeg -y -ss {startTime} -t {length} -i "{videoPath}" "{outPath}"'
os.system(command)
def __addPngWithVideo(self, videoPath, pngPath, outPath, startTime, endTime):
command = f'''ffmpeg -hide_banner -i "{videoPath}" -i "{pngPath}" -filter_complex "overlay=enable='between(t,{startTime},{endTime})'" -y "{outPath}"'''
os.system(command)
def __addMovWithVideo(self, videoPath, movPath, outPath, startTime, endTime):
command = f'''ffmpeg -hide_banner -i "{videoPath}" -i "{movPath}" -filter_complex "overlay=enable='between(t,{startTime},{endTime})'" -y "{outPath}"'''
os.system(command)
def __setVideoFps(self, videoPath, outPath, fps):
command = f'ffmpeg -y -i "{videoPath}" -r {fps} "{outPath}"'
os.system(command)
def __setBrightness(self, videoPath, outPath, s, b):
command = f'ffmpeg -i {videoPath} -vf hue=s={s}:b={b} "{outPath}"'
os.system(command)
def createVideoVithPicture(self, picPath, videoPath, s):
command = f'ffmpeg -y -ss 0 -t {s} -f lavfi -i color=c=0x000000:s=1920x1080:r=30 -i "{picPath}" -filter_complex "[1:v]scale=1920:1080[v1];[0:v][v1]overlay=0:0[outv]" -map [outv] -c:v libx264 "{videoPath}"'
os.system(command)
def addTextWithPicture(self, picPath, list, outPath):
# 打开底版图片
img = Image.open(picPath)
for item in list:
text = item['text']
fontSize = item['fontSize']
# fontType = item['fontType']
color = item['color']
x = item['x']
y = item['y']
font = ImageFont.truetype(r'C:\Windows\Fonts\simsun.ttc', fontSize)
# font = ImageFont.truetype(fontType, fontSize)
# 在图片上添加文字
draw = ImageDraw.Draw(img)
draw.text((x, y), text, color, font=font)
# 保存
img.save(outPath)
def setVideoVolume(self, videoPath, vol, outPath):
command = f'ffmpeg -y -i "{videoPath}" -filter:a "volume={vol}" "{outPath}"'
os.system(command)
def addPngWithVideo(self, videoPath, picPath, outPath):
command = f'ffmpeg -y -i "{videoPath}" -i "{picPath}" -filter_complex overlay=main_w-overlay_w:main_h-overlay_h "{outPath}"'
os.system(command)
def getAudioWithVideo(self, videoPath, audioPath):
command = fr'ffmpeg -y -i "{videoPath}" "{audioPath}"'
os.system(command)
def fadeAudio(self, audioPath, outPath):
command = f'ffmpeg -y -i "{audioPath}" -af afade=t=in:ss=0:d=2 "{outPath}'
os.system(command)
def addVideoWithFFMPEG(self, videoList, outPath):
tsList = [] # 转换为ts文件
for video in videoList:
tsFile = os.path.basename(video).replace('.mp4', '.ts')
path = os.path.dirname(outPath)
command = f'ffmpeg -y -i "{video}" -vcodec copy -acodec copy -vbsf h264_mp4toannexb "{os.path.join(path, tsFile)}"'
os.system(command)
tsList.append(os.path.join(path, tsFile))
command = f'ffmpeg -y -i "concat:{"|".join(tsList)}" -acodec copy -vcodec copy -absf aac_adtstoasc "{outPath}"'
os.system(command)
for ts in tsList: os.remove(ts)
def addVideoWithPic(self, picPath, videoPath, outPath, w, h, x, y):
command = f'ffmpeg -y -i "{picPath}" -i "{videoPath}" -filter_complex [1:v]scale={w}:{h}[v1];[0:v][v1]overlay={x}:{y} "{outPath}"'
os.system(command)