使用前先将mp4对应的EDL文件命名为相同的名字,如:春天.mp4, 春天.edl
只处理持续时间大于5帧的画面
批量处理指定文件夹下所有文件,处理失败的直接跳过,接着继续处理其他的
import cv2 import os import time import datetime import shutil from moviepy.editor import VideoFileClip #读取切分文件 def readQiFenWenJian(filename): with open(filename, "r", encoding='UTF-8')as f: res_list = f.readlines() print("读取到的切分文件") print(res_list) print(len(res_list)) zuizhong_res_list = [] for i in range(2,len(res_list)): if res_list[i] != '\n': zuizhong_res_list.append(res_list[i]) print(zuizhong_res_list) print(len(zuizhong_res_list)) return zuizhong_res_list # 读取一个视频文件,从帧列表中,开始算后续帧,第一个帧尾为0 def handleOneVideo(video_file,zhen_list): #获取当前时间 nowtime = time.strftime('%Y%m%d%H%M%S', time.localtime()) #创建视频文件目录 xinjianmulu = str(video_file).replace(".mp4","") createDir(file_dir=xinjianmulu) for i in range(0, len(zhen_list)): print("进入for循环") yihang_shifenmiao = [] yihangshuju = zhen_list[i] print("一行数据:") print(yihangshuju) yihang_list = yihangshuju.split(" ") print("yihang列表:") print(yihang_list) for one in yihang_list: if ":" in one: yihang_shifenmiao.append(one) print("yihang时分秒帧-列表:") print(yihang_shifenmiao) start_shifenmiao = yihang_shifenmiao[0] start_shifenmiao_list = start_shifenmiao.split(":") print("start_shifenmiao_list:") print(start_shifenmiao_list) end_shifenmiao = yihang_shifenmiao[1] end_shifenmiao_list = end_shifenmiao.split(":") print("end_shifenmiao_list:") print(end_shifenmiao_list) START_HOUR = int(start_shifenmiao_list[0]) # 开始小时 START_MIN = int(start_shifenmiao_list[1]) # 开始分钟 START_SECOND = int(start_shifenmiao_list[2]) # 开始秒数 START_TIME = START_HOUR * 3600 + START_MIN * 60 + START_SECOND # 设置开始时间(单位秒) END_HOUR = int(end_shifenmiao_list[0]) # 结束小时 END_MIN = int(end_shifenmiao_list[1]) # 结束分钟 END_SECOND = int(end_shifenmiao_list[2]) # 结束秒 END_TIME = END_HOUR * 3600 + END_MIN * 60 + END_SECOND # 设置结束时间(单位秒) video = video_file cap = cv2.VideoCapture(video) # 读取视频 FPS = cap.get(cv2.CAP_PROP_FPS) print("帧率:") print(FPS) size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))) print("大小:") print(size) TOTAL_FRAME = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) # 获取视频总帧数 print("总帧数:") print(TOTAL_FRAME) frameToStart = START_TIME * FPS+int(start_shifenmiao_list[3]) # 开始帧 = 开始时间*帧率 + 多余帧 根据达芬奇切割点自动算出开始帧 print("开始帧:") print(frameToStart) frametoStop = END_TIME * FPS + int(end_shifenmiao_list[3]) # 结束帧 = 结束时间*帧率 + 多余帧 根据达芬奇切割点自动算出开始帧 print("结束帧:") print(frametoStop) cishu = i zhenchazhi = int(frametoStop-frameToStart) #如果结束帧和开始帧相差大于5帧才进行处理 if zhenchazhi>=5: xierushipin = r'%s_%s.mp4' % (video, cishu) print("开始写入%s文件"%xierushipin) # 分批写入视频文件 videoWriter = cv2.VideoWriter( xierushipin, cv2.VideoWriter_fourcc(*'mp4v'), FPS, size) cap.set(cv2.CAP_PROP_POS_FRAMES, frameToStart) # 设置读取的位置,从第几帧开始读取视频 #如果是第0帧,则写入,如果不是从第0帧开始的,就往后推移一帧 # if frameToStart==0: # COUNT = frameToStart # else: # COUNT = frameToStart + 1, COUNT = frameToStart chushi = COUNT #定义个全局变量 global biaozhishuzhi biaozhishuzhi=True while biaozhishuzhi: print("进入while循环") success, frame = cap.read() if success: COUNT += 1 if COUNT <= frametoStop and COUNT > frameToStart: # 选取起始帧 print('correct= ', COUNT) videoWriter.write(frame) # print('mistake= ', COUNT) if COUNT > frametoStop: break if i+2 >len(zhen_list): biaozhishuzhi=False print("退出while循环") print("循环标志:%s" % str(biaozhishuzhi)) videoWriter.release() #释放写入 #获取文件时长,并移动文件到指定目录下的对应的秒数的目录下, getTimeAndMoveToMiao(filename=xierushipin, yidongdaogenmulu=xinjianmulu) print("写入%s文件完成" % xierushipin) jieshu = COUNT jilu = '第%s次剪切点,剪切开始%s到结束%s结束\n' % (str(i), str(chushi), str(jieshu)) print(jilu) with open(r'%s_%s_jilu.txt' % (video_file, nowtime), 'a+', encoding='utf-8') as f: f.write(jilu) else: miaoshu = '第%s次剪切点,结束帧%s和开始帧%s相差%s小于5帧,不进行处理\n' %(str(i),str(frametoStop),str(frameToStart),str(zhenchazhi)) print(miaoshu) with open(r'%s_%s_jilu.txt' % (video_file, nowtime), 'a+', encoding='utf-8') as f: f.write(miaoshu) print("退出for循环") #获取指定文件夹下所有MP4文件的时长 def getFileNames(path,houzui=".mp4"): return [os.path.join(path,f) for f in os.listdir(path) if f.endswith(houzui)] #如果不存在就创建 def createDir(file_dir): # 如果不存在文件夹,就创建 if not os.path.isdir(file_dir): os.mkdir(file_dir) #获取视频时长 def getTimeLong(videoFile): clip = VideoFileClip(videoFile) sicahng = clip.duration print(sicahng) # seconds clip.close() return sicahng #移动文件到指定文件夹下的yiqiege目录 def moveFile(zhidingmulu,file_path): try: # 移动文件到文件夹目录中 shutil.move(file_path, zhidingmulu) print("移动文件%s到已切割文件夹" % file_path) except Exception as e: print("移动出错:%s" % str(e)) #读取文件时长,并移动到对应秒数的文件夹中 def getTimeAndMoveToMiao(filename,yidongdaogenmulu): #文件 one = filename path = yidongdaogenmulu try: one_shichang = getTimeLong(one) print("%s文件的时长为 %s 秒"%(one,one_shichang)) zhengshu = int(one_shichang) zhengshijia1 = zhengshu+1 #移动到指定时间的文件夹 xiaoyu1miao = "%s/大于%s秒小于%s秒"% (path,str(zhengshu),str(zhengshijia1)) createDir(file_dir=xiaoyu1miao) moveFile(zhidingmulu=xiaoyu1miao, file_path=one) except Exception as e: print("%s文件的时长失败,原因:%s"%(one,str(e))) #移动到指定时间的文件夹 jieshishibai = "%s/解析失败"% path createDir(file_dir=jieshishibai) moveFile(zhidingmulu=jieshishibai, file_path=one) if __name__ == '__main__': a=datetime.datetime.now() startime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) genmulu = r"C:\4k\ceshi\daichuli" file_list = getFileNames(path=genmulu,houzui=".mp4") for one_file in file_list: try: print("处理%s文件"% str(one_file)) video_file=one_file #mp4文件 qiefenwenjian = str(video_file).replace(".mp4",".edl") zhen_list = readQiFenWenJian(filename=qiefenwenjian) print("处理MP4视频文件:%s" % one_file) print("对应的edl文件:%s" % qiefenwenjian) handleOneVideo(video_file, zhen_list) miaoshu = "处理%s文件成功"% str(one_file) print(miaoshu) with open(r'%s_处理成功.txt' % (video_file, ), 'a+', encoding='utf-8') as f: f.write(miaoshu) except Exception as e: miaoshu = "处理%s文件失败,原因%s" % (str(one_file),str(e)) print(miaoshu) with open(r'%s_处理失败.txt' % (video_file, ), 'a+', encoding='utf-8') as f: f.write(miaoshu) b = datetime.datetime.now() endtime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) cha = (b-a).seconds #时间差的计算,单位为秒 print("程序开始运行时间:") print(startime) print("程序结束运行时间:") print(endtime) print("耗时:") print(cha) print("秒") print(cha/60) print("分")