python根據達芬奇場景分析儲存的edl檔案,智慧裁切輸出4K影片畫面(不帶聲音)-自動找到MP4對應的EDL檔案並移動到指定目錄下對應的秒數資料夾下

大话人生發表於2024-03-29

使用前先將mp4對應的EDL檔案命名為相同的名字,如:春天.mp4, 春天.edl

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[2])  # 結束幀 = 結束時間*幀率 + 多餘幀 根據達芬奇切割點自動算出開始幀
        print("結束幀:")
        print(frametoStop)

        cishu = i
        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()  #釋放寫入
        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)
        #獲取檔案時長,並移動檔案到指定目錄下的對應的秒數的目錄下,
        getTimeAndMoveToMiao(filename=xierushipin, yidongdaogenmulu=xinjianmulu)

    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:
        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("")

相關文章