吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3169|回复: 25
收起左侧

[Python 原创] python-ffmpeg转码视频(添加视频合并)

[复制链接]
qianaonan 发表于 2024-4-6 16:01
本帖最后由 qianaonan 于 2024-4-7 12:46 编辑

视频转码1.1帖子链接:新版调用ffmpeg视频转码器:https://www.52pojie.cn/thread-1901828-1-1.html
更新:
这版视频转码器添加功能合并视频功能,支持最多三个视频合并(一个视频就别试了),合并过程中会日志输出到log.txt中,而转码视频就没有添加该代码会有cmd弹窗,懂python的可以自行添加,同目录中会生成concat.txt文件是视频合并顺序;
注:
1、三个视频顺序由三个按钮从左到右顺序进行合并(不要重叠在一起,尽量保持一个水平线上),两个视频就是按钮视频1和2,按钮下面的文本框没啥用,只是用来看选中的那些文件名。
★三个视频的要求分辨率一致,不一致会报错。
2、这次代码有可能会在合并部分有点乱,自行理解。
3、想调用显卡进行加速,奈何python读取本地配置这部分代码是真的差,我的显示器输入线插在RX6600xt上就检查不出来(不知道啥原因),而且也没有N卡进行调试,后期如果添加显卡加速代码,以a卡为主。
4、视频越大速度越慢,不是程序卡死不动,而是视频太大转码太慢,python认为是卡死了,如果添加防卡死代码,怕有人以为是秒转就关闭程序。(自己曾用4K转码程序卡死,用任务管理器终止程序后,文件目录生成了一段转码后的视频文件)
5、点击视频合并自动开始选择文件,点击合并也保存到同目录里,也就说上面的选择文件和保存目录跟视频合并没有关系。

win1164位打包有可能32位的无法使用

转载需注明来源与作者!

转载需注明来源与作者!

转载需注明来源与作者!

重要的事情说三遍!
放代码:
[Python] 纯文本查看 复制代码
# -*- coding:utf-8 -*-
import wx
import subprocess
import os
import re
import sys

def get_path(relative_path):
    try:
        base_path = sys._MEIPASS
    except AttributeError:
        base_path = os.path.abspath(".")

    return os.path.normpath(os.path.join(base_path, relative_path))
ffmpeg_path =get_path("assets/ffmpeg.exe")#资源的路径
#弹窗消息
def show_message(message):
    """
    显示消息框。

    参数:
    message (str): 要显示的消息。
    """
    app = wx.App(False)
    dlg = wx.MessageDialog(None, message, "提示", wx.OK | wx.ICON_INFORMATION)
    dlg.ShowModal()
    dlg.Destroy()
    app.MainLoop()
#转mp4
def convert_to_mp4(input_video_path, output_directory):
    """
    将输入的视频文件转换为 MP4 格式。

    参数:
    input_video_path (str): 输入视频文件的路径。
    output_directory (str): 输出目录的路径。
    """
    video_name = os.path.splitext(os.path.basename(input_video_path))[0]
    output_mp4_path = os.path.join(output_directory, f"{video_name}.mp4")
    if os.path.exists(output_mp4_path):
        show_message(f"目录中存在同名文件 '{output_mp4_path}',请删除或重命名后重试。")
        return
    result=subprocess.run([ffmpeg_path, "-i",
                           input_video_path,
                           "-c:v", "libx264",
                           "-preset", "slow",
                           "-crf", "23",
                           "-c:a", "aac",
                           "-b:a", "192k",
                           "-strict",
                           "experimental", output_mp4_path])
    if result.returncode == 0:
        show_message("转码成功!")
    else:
        show_message(f"转码失败!错误代码:{result.returncode}")
#转mp3
def convert_to_mp3(input_video_path, output_directory):
    """
    将输入的视频文件转换为 MP3 格式。

    参数:
    input_video_path (str): 输入视频文件的路径。
    output_directory (str): 输出目录的路径。
    """
    video_name = os.path.splitext(os.path.basename(input_video_path))[0]
    output_mp3_path = os.path.join(output_directory, f"{video_name}.mp3")
    if os.path.exists(output_mp3_path):
        show_message(f"目录中存在同名文件 '{output_mp3_path}',请删除或重命名后重试。")
        return
    result=subprocess.run([ffmpeg_path, "-i", input_video_path, "-vn", "-acodec", "libmp3lame", output_mp3_path])
    if result.returncode == 0:
        show_message("转码成功!")
    else:
        show_message(f"转码失败!错误代码:{result.returncode}")
#转avi
def convert_to_avi(input_video_path, output_directory):
    """
    将输入的视频文件转换为 AVI 格式。

    参数:
    input_video_path (str): 输入视频文件的路径。
    output_directory (str): 输出目录的路径。
    """
    video_name = os.path.splitext(os.path.basename(input_video_path))[0]
    output_avi_path = os.path.join(output_directory, f"{video_name}.avi")
    if os.path.exists(output_avi_path):
        show_message(f"目录中存在同名文件 '{output_avi_path}',请删除或重命名后重试。")
        return
    result=subprocess.run([ffmpeg_path, "-i", input_video_path, "-c:v", "libx264", "-preset", "slow", "-crf", "23", "-c:a", "pcm_s16le", output_avi_path])
    if result.returncode == 0:
        show_message("转码成功!")
    else:
        show_message(f"转码失败!错误代码:{result.returncode}")
#转wmv
def convert_to_wmv(input_video_path, output_directory):
    """
    将输入的视频文件转换为 WMV 格式。

    参数:
    input_video_path (str): 输入视频文件的路径。
    output_directory (str): 输出目录的路径。
    """
    video_name = os.path.splitext(os.path.basename(input_video_path))[0]
    output_wmv_path = os.path.join(output_directory, f"{video_name}.wmv")
    if os.path.exists(output_wmv_path):
        show_message(f"目录中存在同名文件 '{output_wmv_path}',请删除或重命名后重试。")
        return
    result=subprocess.run([ffmpeg_path, "-i", input_video_path, "-c:v", "wmv2", "-b:v", "1024k", "-c:a", "wmav2", output_wmv_path])
    if result.returncode == 0:
        show_message("转码成功!")
    else:
        show_message(f"转码失败!错误代码:{result.returncode}")
#转gif
def convert_to_gif(input_video_path, output_directory, start_time, end_time, fps=10):
    """
    将输入的视频文件转换为 GIF 格式。

    参数:
    input_video_path (str): 输入视频文件的路径。
    output_directory (str): 输出目录的路径。
    start_time (int): 视频开始时间(以秒为单位)。
    end_time (int): 视频结束时间(以秒为单位)。
    fps (int): GIF 的帧率,默认为 10。
    """
    video_name = os.path.splitext(os.path.basename(input_video_path))[0]
    output_gif_path = os.path.join(output_directory, f"{video_name}_segment.gif")
    if os.path.exists(output_gif_path):
        show_message(f"目录中存在同名文件 '{output_gif_path}',请删除或重命名后重试。")
        return
    result=subprocess.run([ffmpeg_path, "-ss", str(start_time), "-i", input_video_path, "-t", str(end_time - start_time), "-vf", f"fps={fps}", output_gif_path])
    if result.returncode == 0:
        show_message("转码成功!")
    else:
        show_message(f"转码失败!错误代码:{result.returncode}")
#转mov
def convert_to_mov(input_video_path, output_directory):
    """
    将输入的视频文件转换为 MOV 格式。

    参数:
    input_video_path (str): 输入视频文件的路径。
    output_directory (str): 输出目录的路径。
    """
    video_name = os.path.splitext(os.path.basename(input_video_path))[0]
    output_mov_path = os.path.join(output_directory, f"{video_name}.mov")
    if os.path.exists(output_mov_path):
        show_message(f"目录中存在同名文件 '{output_mov_path}',请删除或重命名后重试。")
        return
    result=subprocess.run([ffmpeg_path, "-i", input_video_path, "-c:v", "libx264", "-preset", "slow", "-crf", "23", output_mov_path])
    if result.returncode == 0:
        show_message("转码成功!")
    else:
        show_message(f"转码失败!错误代码:{result.returncode}")
# 函数集合
def function_dispatcher(number,input_video_path,output_directory,start_time,end_time):
    """
    根据用户选择的数字执行相应的视频转换函数。

    参数:
    number (int): 用户选择的数字,代表要执行的转换函数。
    input_video_path (str): 输入视频文件的路径。
    output_directory (str): 输出目录的路径。
    start_time (int): 视频开始时间(以秒为单位)。
    end_time (int): 视频结束时间(以秒为单位)。
    """
    functions = {
        0: convert_to_mp4,
        1: convert_to_avi,
        2: convert_to_wmv,
        3: convert_to_mp3,
        4: convert_to_gif,
        5: convert_to_mov,
    }
    if number in functions:
        if number == 4:  # 如果选中的是转换为 GIF
            if start_time is not None and end_time is not None:
                functions[number](input_video_path, output_directory, start_time, end_time)
            else:
                # 在这种情况下,可以选择不传递 start_time 和 end_time 参数,或者传递默认值
                functions[number](input_video_path, output_directory, 0, None)
        else:
            functions[number](input_video_path, output_directory)
#gif所需视频长度格式
def convert_time_to_seconds(time_str):
    """
    将时间字符串转换为秒数。

    参数:
    time_str (str): 表示时间的字符串,可以是 HH:MM:SS 格式或整数表示的秒数。

    返回:
    int: 转换后的秒数。
    """
    if isinstance(time_str, int) or time_str.isdigit():
        # 如果输入是整数或者全是数字,则直接解析为整数,代表秒数
        return int(time_str)
    elif ':' in time_str:
        # 如果输入包含冒号,则尝试将其解析为时间格式
        parts = time_str.split(':')
        if len(parts) == 3:
            try:
                hours = int(parts[0])
                minutes = int(parts[1])
                seconds = int(parts[2])
                # 计算总秒数
                return hours * 3600 + minutes * 60 + seconds
            except ValueError:
                # 如果解析失败,则说明时间格式不正确
                raise ValueError("Invalid time format")
        else:
            # 如果冒号数量不是三个,则抛出异常
            raise ValueError("Invalid time format")
    else:
        # 如果既不是整数,也不是带冒号的时间格式,则抛出异常
        raise ValueError("Invalid time format")
#转换时间字符串
def format_duration(duration):
    """
    格式化视频持续时间为 HH:MM:SS 格式的字符串。

    参数:
    duration (float): 视频的持续时间(以秒为单位)。

    返回:
    str: 格式化后的时间字符串。
    """
    hours = int(duration // 3600)
    minutes = int((duration % 3600) // 60)
    seconds = int(duration % 60)
    return f'{hours:02d}:{minutes:02d}:{seconds:02d}'
#获取视频长度
def chixu_video(input_video_path):
    """
    获取视频文件的持续时间,并将其格式化为 HH:MM:SS 的字符串。

    参数:
    input_video_path (str): 视频文件的路径。

    返回:
    str: 格式化后的视频持续时间字符串。
    """
    if not input_video_path:
        return "00:00:00"
    # 运行 FFmpeg 命令获取视频时长信息
    command = [ffmpeg_path, '-i', input_video_path]
    result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
    output = result.stderr
    # 使用正则表达式从输出中提取视频时长信息
    duration_match = re.search(r'Duration:\s*(\d+):(\d+):(\d+)', output)
    if duration_match:
        hours = int(duration_match.group(1))
        minutes = int(duration_match.group(2))
        seconds = int(duration_match.group(3))
        formatted_duration = f"{hours:02d}:{minutes:02d}:{seconds:02d}"
        return formatted_duration
    else:
        return "00:00:00"

#视频合并
def merge_videos(video1_path, video2_path, video3_path, output_dir=None):
    # 如果未提供输出目录,则默认保存在视频文件所在目录
    if output_dir is None:
        output_dir = os.path.dirname(video1_path)

    # 输出文件路径
    output_path = os.path.join(output_dir, '合并视频.mp4')

    # 检查输出目录是否已存在合并视频文件
    if os.path.exists(output_path):
        show_message(f"合并视频文件 '{output_path}' 已存在,无法执行合并操作。")
        return

    # 生成concat.txt文件,包含要合并的视频文件路径
    concat_file = os.path.join(output_dir, 'concat.txt')
    with open(concat_file, 'w') as f:
        for path in [video1_path, video2_path, video3_path]:
            f.write(f"file '{path}'\n")

    # 使用FFmpeg执行合并命令
    log_file = os.path.join(output_dir, 'log.txt')
    with open(log_file, 'w') as log:
        command = [ffmpeg_path, '-n', '-f', 'concat', '-safe', '0', '-i', concat_file, '-c', 'copy', output_path]
        result = subprocess.run(command, stdout=log, stderr=subprocess.STDOUT)

    # 根据FFmpeg的返回代码显示消息
    if result.returncode == 0:
        show_message("合并成功!")
    else:
        show_message(f"合并失败!错误代码:{result.returncode},ffmpeg输出日志在同目录log.txt文件中")

    # 删除临时生成的concat.txt文件




    #-------------------------UI界面----------------------------


class DragButton(wx.Button):
    def __init__(self, parent, id=wx.ID_ANY, label="", pos=wx.DefaultPosition, size=wx.DefaultSize, style=0):
        super().__init__(parent, id, label=label, pos=pos, size=size, style=style)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_MOTION, self.OnMotion)
        self.dragging = False

    def OnLeftDown(self, event):
        self.CaptureMouse()
        self.dragStartPos = event.GetPosition()
        self.dragging = True
        self.Raise()  # 当按钮被点击时,将其置于最顶层

    def OnLeftUp(self, event):
        if self.HasCapture():
            self.ReleaseMouse()
        self.dragging = False

    def OnMotion(self, event):
        if event.Dragging() and event.LeftIsDown() and self.dragging:
            newPos = event.GetPosition() - self.dragStartPos + self.GetPosition()
            self.Move(newPos)


class Frame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title='原创:吾爱qianaonan', size=(437, 255), name='frame', style=541072384)
        self.启动窗口 = wx.Panel(self)
        self.Centre()
        self.编辑框1 = wx.TextCtrl(self.启动窗口, size=(293, 29), pos=(8, 5), value='', name='text', style=16)
        self.按钮1 = wx.Button(self.启动窗口, size=(80, 32), pos=(315, 3), label='选择文件', name='button')
        self.标签1 = wx.StaticText(self.启动窗口, size=(80, 24), pos=(10, 44), label='转换成', name='staticText',
                                   style=2321)
        self.单选框2 = wx.RadioButton(self.启动窗口, size=(58, 24), pos=(8, 72), name='radioButton', label='MP4')
        self.单选框3 = wx.RadioButton(self.启动窗口, size=(40, 24), pos=(73, 72), name='radioButton', label='AVI')
        self.单选框4 = wx.RadioButton(self.启动窗口, size=(58, 24), pos=(136, 72), name='radioButton', label='WMV')
        self.单选框5 = wx.RadioButton(self.启动窗口, size=(61, 24), pos=(209, 72), name='radioButton', label='MP3')
        self.单选框6 = wx.RadioButton(self.启动窗口, size=(42, 24), pos=(275, 72), name='radioButton', label='GIF')
        self.单选框7 = wx.RadioButton(self.启动窗口, size=(80, 24), pos=(327, 72), name='radioButton', label='MOV')
        self.按钮2 = wx.Button(self.启动窗口, size=(80, 32), pos=(317, 107), label='保存目录', name='button')
        self.编辑框2 = wx.TextCtrl(self.启动窗口, size=(293, 29), pos=(8, 107), value='', name='text', style=16)
        self.按钮3 = wx.Button(self.启动窗口, size=(80, 32), pos=(240, 157), label='开始转换', name='button')
        self.Bind(wx.EVT_BUTTON, self.OnSelectFile, self.按钮1)  # 绑定选择文件按钮的事件
        self.Bind(wx.EVT_BUTTON, self.OnSelectFolder, self.按钮2)
        self.按钮3.Bind(wx.EVT_BUTTON, self.按钮3_按钮被单击)
        self.标签2 = wx.StaticText(self.启动窗口, size=(195, 60), pos=(15, 143),
                                   label='请谨慎使用gif转换,一般是视频过\n长会导致程序卡死\n视频越长花费时间越长',
                                   name='staticText', style=17)
        self.标签2.SetForegroundColour((255, 0, 0, 255))
        self.标签3 = wx.StaticText(self.启动窗口, size=(80, 17), pos=(254, 56), label='10帧/秒', name='staticText',
                                   style=2321)
        self.编辑框3 = wx.TextCtrl(self.启动窗口, size=(80, 18), pos=(303, 35), value='', name='text', style=0)
        self.编辑框3.SetForegroundColour((128, 128, 128, 255))
        self.编辑框4 = wx.TextCtrl(self.启动窗口, size=(80, 18), pos=(304, 54), value='', name='text', style=0)
        self.编辑框4.SetForegroundColour((128, 128, 128, 255))
        self.编辑框4.Bind(wx.EVT_KILL_FOCUS, self.编辑框4_失去焦点)
        self.编辑框4.Bind(wx.EVT_SET_FOCUS, self.onSetFocus)
        self.标签5 = wx.StaticText(self.启动窗口, size=(26, 17), pos=(269, 38), label='开始', name='staticText',
                                   style=2321)
        self.标签6 = wx.StaticText(self.启动窗口, size=(28, 14), pos=(268, 56), label='结束', name='staticText',
                                   style=2321)
        self.按钮4 = wx.Button(self.启动窗口, size=(80, 32), pos=(330, 157), label='视频合并', name='button')
        self.按钮4.Bind(wx.EVT_BUTTON, self.按钮4_按钮被单击)
        self.编辑框3.Hide()
        self.编辑框4.Hide()
        self.标签5.Hide()
        self.标签6.Hide()
        self.单选框2.Bind(wx.EVT_RADIOBUTTON, self.onRadioButton)
        self.单选框3.Bind(wx.EVT_RADIOBUTTON, self.onRadioButton)
        self.单选框4.Bind(wx.EVT_RADIOBUTTON, self.onRadioButton)
        self.单选框5.Bind(wx.EVT_RADIOBUTTON, self.onRadioButton)
        self.单选框6.Bind(wx.EVT_RADIOBUTTON, self.onRadioButton)
        self.单选框7.Bind(wx.EVT_RADIOBUTTON, self.onRadioButton)
        #-----------------------------------------视频合并页面-------------------------------------------
        self.编辑框5 = wx.TextCtrl(self.启动窗口,size=(293, 29),pos=(8, 294),value='',name='text',style=0)
        self.按钮8 = wx.Button(self.启动窗口,size=(80, 32),pos=(318, 292),label='合成',name='button')
        self.按钮5 = DragButton(self.启动窗口, size=(80, 32), pos=(37, 225), label='视频1')
        self.按钮6 = DragButton(self.启动窗口, size=(80, 32), pos=(144, 225), label='视频2')
        self.按钮7 = DragButton(self.启动窗口, size=(80, 32), pos=(257, 225), label='视频3')
        self.按钮8.Bind(wx.EVT_BUTTON, self.OnButton4Click)
        self.标签7 = wx.StaticText(self.启动窗口, size=(401, 16), pos=(9, 272),
                                   label='以上按钮调整视频顺序,下面文本尽看选中文件的文件名',
                                   name='staticText', style=2321)
        self.标签7.SetForegroundColour((255, 0, 0, 255))

    def InitUI(self):
        # 初始化 UI
        # 添加按钮、编辑框等控件
        self.list_path = []  # 将 list_path 定义为类的成员变量

    def 按钮4_按钮被单击(self, event):
        self.SetSize(437, 371)
        wildcard = "Video Files (*.mp4;*.avi;*.wmv;*.mov)|*.mp4;*.avi;*.wmv;*.mov|All Files (*.*)|*.*"  # 文件类型过滤器
        dialog = wx.FileDialog(self, "选择文件", wildcard=wildcard,
                               style=wx.FD_OPEN | wx.FD_MULTIPLE)
        # dialog.SetMaxFiles(3)
        if dialog.ShowModal() != wx.ID_OK:
            dialog.Destroy()
            return

        paths = dialog.GetPaths()  # 获取所有选中文件的路径列表
        dialog.Destroy()

        if len(paths) >= 4:  # 假设我们只允许最多5个文件被选中
            wx.MessageBox("你只能选中3个视频", "Error")
            paths = paths[:3]  # 如果选择的文件超过3个,只保留前三个文件
        if len(paths) == 2:
            self.按钮7.Hide()
        if len(paths) == 3:
            self.按钮7.Show()
        # 处理文件,例如打开文件、读取内容等
        filenames = [os.path.basename(path) for path in paths]  # 提取文件名列表
        filenames_text = "\n".join([filename + "|" for filename in filenames])# 将文件名列表连接为单个字符串,用换行符分隔
        self.编辑框5.SetValue(filenames_text)  # 将连接后的文件名字符串设置为编辑框的值
        self.list_path = list(paths)
    def OnButton4Click(self, event):
        # 获取按钮5、按钮6和按钮7的位置信息
        pos5 = self.按钮5.GetPosition()
        pos6 = self.按钮6.GetPosition()
        pos7 = self.按钮7.GetPosition()
        #print(self.list_path[0],self.list_path[1],self.list_path[2])
        # 检查按钮5、6、7的 x 坐标值,以确定它们的从左到右位置顺序
        a = self.list_path[0]
        b = self.list_path[1]
        if len(self.list_path)>=3:
            c = self.list_path[2]
        else:
            c=None
        #print(self.list_path)
        if len(self.list_path)==3:
            if pos5.x < pos6.x and pos6.x < pos7.x:
                #按钮5-按钮6-按钮7
                merge_videos(a,b,c)
            elif pos5.x < pos7.x and pos7.x < pos6.x:
                #按钮5-按钮7-按钮6
                merge_videos(a, c, b)
            elif pos6.x < pos5.x and pos5.x < pos7.x:
                #按钮6-按钮5-按钮7
                merge_videos(b, a, c)
            elif pos6.x < pos7.x and pos7.x < pos5.x:
                #按钮6-按钮7-按钮5
                merge_videos(b, c, a)
            elif pos7.x < pos5.x and pos5.x < pos6.x:
                #按钮7-按钮5-按钮6
                merge_videos(c, a, b)
            elif pos7.x < pos6.x and pos6.x < pos5.x:
                #按钮7-按钮6-按钮5
                merge_videos(c, b, a)
            else:
                show_message("按钮重叠")
        elif len(self.list_path)==2:
            if pos5.x<pos6.x:
                merge_videos(a,b,c)
            else:
                merge_videos(b,a,c)
        else:
            show_message("一个视频你合个啥????")

    def 编辑框4_失去焦点(self,event):
        self.编辑框4.SetValue(str(chixu_video(self.编辑框1.GetValue())))
    def onSetFocus(self, event):
        self.编辑框4.SetValue("")  # 清空文本框的值
        self.编辑框4.SetForegroundColour(wx.BLACK)  # 设置黑色
    def onRadioButton(self, event):
        selectedRadioButton = event.GetEventObject()
        if selectedRadioButton in [self.单选框6] and selectedRadioButton.GetValue():
            self.标签3.Hide()
            self.编辑框3.Show()
            self.编辑框4.Show()
            self.编辑框3.SetValue('0')
            self.编辑框4.SetValue(str(chixu_video(self.编辑框1.GetValue())))
            self.标签5.Show()
            self.标签6.Show()
        else:
            self.标签3.Show()
            self.编辑框3.Hide()
            self.编辑框4.Hide()
            self.标签5.Hide()
            self.标签6.Hide()
    def GetSelectedRadioButtonIndex(self):
        radio_buttons = [self.单选框2, self.单选框3, self.单选框4, self.单选框5, self.单选框6, self.单选框7]
        for i, button in enumerate(radio_buttons):
            if button.GetValue():
                return i
        return None
    def OnSelectFile(self, event):
        wildcard = "Video Files (*.mp4;*.avi;*.wmv;*.mov)|*.mp4;*.avi;*.wmv;*.mov|All Files (*.*)|*.*"  # 文件类型过滤器
        dialog = wx.FileDialog(self, "选择文件", wildcard=wildcard,
                               style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE)
        if dialog.ShowModal() == wx.ID_CANCEL:
            return
        paths = dialog.GetPaths()
        directories = paths  # 提取文件路径
        self.编辑框1.SetValue("\n".join(directories))  # 在编辑框中显示目录,使用换行分隔多个目录
        if self.单选框6.GetValue():
            self.编辑框4.SetValue(str(chixu_video(self.编辑框1.GetValue())))
        dialog.Destroy()
    def OnSelectFolder(self, event):
        dialog = wx.DirDialog(self, "选择文件夹", style=wx.DD_DEFAULT_STYLE | wx.DD_DIR_MUST_EXIST)
        if dialog.ShowModal() == wx.ID_CANCEL:
            return
        folder_path = dialog.GetPath()
        self.编辑框2.SetValue(folder_path)  # 在编辑框2中显示所选文件夹路径
        dialog.Destroy()
    def 按钮3_按钮被单击(self, event):
        if self.编辑框1.GetValue().strip() == '' :
            wx.MessageBox('你有东西没选中,请重新设置', '警告', wx.OK | wx.ICON_WARNING)
            return

        if self.GetSelectedRadioButtonIndex() is None:
            wx.MessageBox('你有东西没选中,请重新设置', '警告', wx.OK | wx.ICON_WARNING)
            return
        selected_index = self.GetSelectedRadioButtonIndex()  # 输出单选项位置位置
        input_path1 = self.编辑框1.GetValue()
        if self.编辑框2.GetValue().strip()=='未选择目录则是源文件相同目录':
            output_directory1=os.path.dirname(self.编辑框1.GetValue())
        else:
            output_directory1 = self.编辑框2.GetValue()
        start_time_str = self.编辑框3.GetValue()
        end_time_str = self.编辑框4.GetValue()
        if start_time_str.strip() == '' or end_time_str.strip() == '':
            start_time = None
            end_time = None
        else:
            start_time = convert_time_to_seconds(start_time_str)
            end_time = convert_time_to_seconds(end_time_str)
        function_dispatcher(selected_index, input_path1, output_directory1, start_time, end_time)
class myApp(wx.App):
    def OnInit(self):
        self.frame = Frame()
        self.frame.Show(True)
        return True

if __name__ == '__main__':
    app = myApp()
    app.MainLoop()


老规矩百度云链接:链接:https://pan.baidu.com/s/11g01x-vXlqIH-5rueezlGQ?pwd=0bdo
蓝奏云链接:https://wwm.lanzout.com/i1YKR1u3rm9i

免费评分

参与人数 3吾爱币 +8 热心值 +3 收起 理由
why3316 + 1 + 1 谢谢@Thanks!
silenter6speake + 1 谢谢@Thanks!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

爱飞的猫 发表于 2024-4-6 21:06
wasm2023 发表于 2024-4-6 20:17
我是想用py判断,并且能过滤坏掉的视频

调用 ffprobe 查询媒体文件信息,报错就是坏的。

可以顺便捕捉并解析 stdout/stderr 的文本输出,得到媒体文件的宽度高度
XTCharles 发表于 2024-4-6 16:08
inthelove95 发表于 2024-4-6 16:17
ZCCHNS 发表于 2024-4-6 16:43
谢谢楼主 但是我没办法使用
centenary 发表于 2024-4-6 18:38

感谢分享 辛苦了
wasm2023 发表于 2024-4-6 18:40
楼主,请问判断一个文件夹的视频是否为同一分辨率咋写呢
 楼主| qianaonan 发表于 2024-4-6 20:02
wasm2023 发表于 2024-4-6 18:40
楼主,请问判断一个文件夹的视频是否为同一分辨率咋写呢

win11文件属性里面有啊
wasm2023 发表于 2024-4-6 20:17
qianaonan 发表于 2024-4-6 20:02
win11文件属性里面有啊

我是想用py判断,并且能过滤坏掉的视频

点评

调用 ffprobe 查询媒体文件信息,报错就是坏的。 可以顺便捕捉并解析 stdout/stderr 的文本输出,得到媒体文件的宽度高度  详情 回复 发表于 2024-4-6 21:06
 楼主| qianaonan 发表于 2024-4-6 20:28
wasm2023 发表于 2024-4-6 20:17
我是想用py判断,并且能过滤坏掉的视频

放大图看,绝大部分坏掉的视频是无法显示缩略图
starryskyhello 发表于 2024-4-6 21:06
厉害,学到了。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-15 11:31

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表