python端对视频的分帧、帧合成处理
用于简单对视频进行分帧和帧合成处理,并保存了原视频的音频,能够在帧合成之后还原音频
一、python-MoviePy实现视频中音频和视频轨道分离
1.引入相关包和库文件
from moviepy.editor import AudioFileClip
其他信息参考 Movie-Py官方文档
2.分离音频轨道并单独保存
def Audio_Video_Detach(video_path):
audio=AudioFileClip(video_path)#分离视频中的音频轨道
audio.write_audiofile(AUDIO_PATH+'.mp3')#保存该音频的路径并设置音频的指定格式
video_path为传入视频的路径
AUDIO_PATH为全局变量保存音频的路径
二、python-OpenCV实现视频分帧
1.找到视频所在文件夹进行文件夹的遍历
2.读取视频第一帧并执行写入文件操作,将第一帧以指定图像格式(.jpg/.png等)按照命名规则写入指定路径下
3.循环所有帧写入所有图片即完成了一个视频的分帧
代码如下:
def cut():#裁剪mp4
num=1 #帧计数变量
if (os.path.exists(CUT_PATH)==0):
os.mkdir(CUT_PATH)
filepath = VIDEO_PATH # 视频所在文件夹
pathDir = os.listdir(filepath)
for allDir in pathDir:
videopath = VIDEO_PATH + allDir
vc = cv2.VideoCapture(videopath)
FPS=vc.get(5)#vc.get下面有不同的参数指定输出视频头文件中不同的信息
COUNT=vc.get(7)
print('FPS=',FPS)
print('COUNT=',COUNT)#总帧数
c = 1
if vc.isOpened():
rval, frame = vc.read()
else:
rval = False
timeF = 1 # 视频帧计数间隔频率 *s
while rval:
rval, frame = vc.read()
if frame is not None:
if c % timeF == 0: # 每隔timeF帧进行存储操作
cv2.imwrite(CUT_PATH + '/' + '%06d.jpg' % num, frame)#cut文件夹下面设置路径,每一帧的名字为按序的6位数字存放(000000.jpg,000001.jpg,0000002.jpg......)这样的形式
num = num + 1
print('finish:%d' % num)
c = c + 1
cv2.waitKey(1)
vc.release()
根据个人需要修改代码:
4.文件操作
(1)CUT_PATH #裁剪分帧的保存位置
(2)VIDEO_PATH #mp4视频文件保存位置
(3)cv2.imwrite的操作:保存每一帧的路径和每一帧图像的名字
其中%6d为了配合之后的帧合成操作,对图像名称进行按序命名
5.vc.get参数详解:
cv2.VideoCapture.get(0) 视频文件的当前位置(播放)以毫秒为单位
cv2.VideoCapture.get(1) 基于以0开始的被捕获或解码的帧索引
cv2.VideoCapture.get(2) 视频文件的相对位置(播放):0=电影开始,1=影片的结尾。
cv2.VideoCapture.get(3) 在视频流的帧的宽度
cv2.VideoCapture.get(4) 在视频流的帧的高度
cv2.VideoCapture.get(5) 帧速率
cv2.VideoCapture.get(6) 编解码的4字-字符代码
cv2.VideoCapture.get(7) 视频文件中的帧数
cv2.VideoCapture.get(8) 返回对象的格式
cv2.VideoCapture.get(9) 返回后端特定的值,该值指示当前捕获模式
cv2.VideoCapture.get(10) 图像的亮度(仅适用于照相机)
cv2.VideoCapture.get(11) 图像的对比度(仅适用于照相机)
cv2.VideoCapture.get(12) 图像的饱和度(仅适用于照相机)
cv2.VideoCapture.get(13) 色调图像(仅适用于照相机)
cv2.VideoCapture.get(14) 图像增益(仅适用于照相机)(Gain在摄影中表示白平衡提升)
cv2.VideoCapture.get(15) 曝光(仅适用于照相机)
cv2.VideoCapture.get(16) 指示是否应将图像转换为RGB布尔标志
cv2.VideoCapture.get(17) × 暂时不支持
cv2.VideoCapture.get(18) 立体摄像机的矫正标注(目前只有DC1394 v.2.x后端支持这个功能)
三、帧合成为视频
1.找到待合成视频的帧文件夹
2.读取第一张图片并取得第一张图片的长宽信息(图片分帧已经按序存放,故不存在图片的排序问题。若未按序存放则需要对文件夹遍历后对所有文件按照名称进行排序,在上述分帧中已经保证了图片在文件夹中是按序存放)
3.由第一张图片的信息生成视频,根据图片的大小,创建写入对象
4.遍历所有图片将其写入生成的.mp4文件中得到合成视频
代码如下:
def generate(id,fps):#合成mp4
img = cv2.imread(SAVE_PATH + '%06d.jpg' % 1) # 读取第一张图片
imgInfo = img.shape
size = (imgInfo[1], imgInfo[0]) # 获取图片宽高度信息
print(size)
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
video_name='123.mp4'
print('视频路径',video_name)
videoWrite = cv2.VideoWriter(video_name, fourcc, fps, size)# 根据图片的大小,创建写入对象 (文件名,支持的编码器,帧,视频大小(图片大小))
# videoWrite = cv2.VideoWriter('0.mp4',fourcc,fps,(1920,1080))上面的样例
files = os.listdir(SAVE_PATH)
out_num = len(files)
print(out_num)
for i in range(1, out_num+1): #range(1,3)从1到3,不包含3,即1,2
fileName = SAVE_PATH + '%06d.jpg' % i # 循环读取所有的图片,假设以数字顺序命名
print(fileName)
img = cv2.imread(fileName)
videoWrite.write(img) # 将图片写入所创建的视频对象
根据个人需要修改代码:
(1)SAVE_PATH #待合成视频的诸帧保存路径
(2)video_name #生成视频的名字
四、python-MoviePy实现视频中音频和视频轨道合成,即视频与原音频的合成
由诸帧合成的视频只有图像而没有声音,这时候需要将第一步中保存的音频与其进行合成
同样使用到python-MoviePy中的Audio_Video_Generation函数
代码如下:
def Audio_Video_Generation(input_video,input_audio,output):
ffmpeg_os='ffmpeg -i {} -i {} -c:v copy -c:a aac -strict experimental {}'.format(input_video,input_audio,output)//设置在命令行中需要执行的字符串
os.system(ffmpeg_os)//执行命令
根据个人需要修改代码:
(1)input_video #合成的视频
(2)input_audio #第一步中保存的音频文件(上述为.mp3文件)
(3)output #音频、视频合成后的最终结果文件(如:Linux下设置为 /home/audio_video/123.mp4)