使用前先将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("")

 

posted on 2024-03-29 17:25  大话人生  阅读(25)  评论(0编辑  收藏  举报