首页 > 编程语言 >python根据达芬奇场景分析保存的edl文件,智能裁切输出4K视频画面(不带声音)-自动找到MP4对应的EDL文件并移动到指定目录下对应的秒数文件夹下-只处理大于5帧的剪切点的画面

python根据达芬奇场景分析保存的edl文件,智能裁切输出4K视频画面(不带声音)-自动找到MP4对应的EDL文件并移动到指定目录下对应的秒数文件夹下-只处理大于5帧的剪切点的画面

时间:2024-03-29 16:15:50浏览次数:29  
标签:str 裁切 list 画面 shifenmiao file print path 对应

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

 

标签:str,裁切,list,画面,shifenmiao,file,print,path,对应
From: https://www.cnblogs.com/jingzaixin/p/18104029

相关文章

  • python获取视频时长并移动到对应时长的文件夹下
    importosimportshutilfrommoviepy.editorimportVideoFileClip#获取所有文件defgetAllFiles(fire_dir):filepath_list=[]forroot,folder_names,file_namesinos.walk(fire_dir):forfile_nameinfile_names:file_path=root+os......
  • OpenCV模板匹配(匹配图片中对应元素)
    OpenCV模板匹配(匹配图片中对应元素)模板匹配方法单个元素进行匹配并绘制矩形框效果代码模板匹配方法模板是被查找目标的图像,查找模板在原始图像中的哪个位置的过程就叫模板匹配。OpenCV提供的matchTemplate()方法就是模板匹配方法,其语法如下:result=cv2.matchTemp......
  • SAP BW4中CP与CP对应系统视图的字段关系
     可以发现CP:ZA1SD_M05的视图0BW:BIA:ZA1SD_M05的字段后续都加上的KEY,一般情况下去掉_KEY就是CP的源字段,不确定的话可以打开  可以看出来源字段及目标字段是那个。 ......
  • 车辆信息快速查找API:轻松查询车牌号对应车辆的详细资料
     车辆信息的快速查找对于许多人来说是非常有用的。无论是想要购买一辆二手车,还是需要了解某辆车的详细信息,这个需求在现实生活中经常会遇到。那么,有没有一种快速方便的方法来实现这个功能呢?答案是有的,就是通过车辆信息快速查找API。在这篇博文中,我们将介绍一个车辆信息快速查......
  • C# 01 画面跳转、消息框
    一、2个画面互相跳转form1:privatevoidlabel1_Click(objectsender,EventArgse){//次画面を非表示隐藏此画面显示2画面this.Visible=false;Form2f2=newForm2();f2.Show();}form2:privatevoidbutton2_Cli......
  • 关于使用向日葵等远程软件,关闭主机显示器后远程画面缩小的解决办法
    【方法一】修改分辨率直接在桌面上,右键【显示设置】>>>【显示器分辨率】>>>改成更大的分辨率即可。(当然这个方法的前提是:修改分辨率的选项是可选的而不是灰色的,并且你的鼠标可以下拉并点击到修改分辨率的选择框)【方法二】修改注册表1.打开主机和显示器,在桌面上右键>>>显示设置>>......
  • 与Android Gradle Plugin对应的Gradle版本和Android Studio版本
    Gradle版本和AndroidGradlePlugin对应版本Gradle版本AndroidGradlePlugin版本8.4(Alpha版)8.6-rc-18.38.48.28.28.18.08.08.07.47.57.37.47.27.3.37.17.27.07.04.2.0+6.7.1AndroidStudio版本和AndroidGradlePlugin对应版本AndroidStudio版本AndroidGradlePlugi......
  • Redis第二课,1.set key value(设置对应的key和value)2.get key(得到value值)Redis全局
    Redis的启动 redis-cli目录1.setkeyvalue(设置对应的key和value)2.getkey(得到value值)Redis全局命令(支持很多的数据结构)3.keys(用来查询当前服务器匹配的key)生产环境/线上环境4.exist(判定key是否存在):判定key是否存在​编辑5.DEL  key 返回删掉的key......
  • Redis第三弹,定时删除1.优先级队列(堆)2.基于时间轮实现的定时器​编辑Type指令(返回key对
    目录定时删除1.优先级队列(堆)2.基于时间轮实现的定时器​编辑Type指令(返回key对应的数据类型)redis的数据类型hsetkeyfieldvalue(这里是使用hash作为数据结构)小结定时删除redis并未实现定时器的方式,实现定时器的方式,实现过期key删除,若多个key过期,也可通过一个......
  • Android混淆后的bug日志通过mapping文件找对应行号
    背景由于项目中提测以及线上的apk都是经过混淆处理的,因此拿到日志后也无法正常查看崩溃日志的行号这个原因是因为混淆了文件,输出的日志是对应不上源文件的,为了正确找到行号需要用到mapping.txt文件配置开启保留行号和源文件要想利用mapping文件找到对应的行号,则还需要在混淆......