使用前先將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: 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) 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("秒")