refactor(gui): streamline FFmpeg path setup and remove installer dialog

This commit is contained in:
wood chen 2024-11-16 09:05:36 +08:00
parent f037cf9ddd
commit 8788f0b0b9

250
gui.py
View File

@ -7,7 +7,7 @@ import os
import webbrowser import webbrowser
from threading import Thread from threading import Thread
import ffmpeg import ffmpeg
import traceback # 用于打印详细错误信息 import traceback
# 根据平台选择拖放实现 # 根据平台选择拖放实现
PLATFORM = platform.system().lower() PLATFORM = platform.system().lower()
@ -24,250 +24,20 @@ elif PLATFORM == "darwin": # macOS
else: # Linux or others else: # Linux or others
SUPPORT_DND = None SUPPORT_DND = None
# 设置 FFmpeg 路径
if getattr(sys, "frozen", False):
# 运行在 PyInstaller 打包后的环境
ffmpeg_path = os.path.join(sys._MEIPASS, "ffmpeg")
else:
# 运行在开发环境
ffmpeg_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "ffmpeg")
class FFmpegInstaller: if ffmpeg_path not in os.environ["PATH"]:
@staticmethod os.environ["PATH"] = ffmpeg_path + os.pathsep + os.environ["PATH"]
def get_ffmpeg_path():
if getattr(sys, "frozen", False):
# 运行在 PyInstaller 打包后的环境
return os.path.join(sys._MEIPASS, "ffmpeg")
else:
# 运行在开发环境
return os.path.join(os.path.dirname(os.path.abspath(__file__)), "ffmpeg")
# 设置 FFmpeg 路径
ffmpeg_path = get_ffmpeg_path()
if ffmpeg_path not in os.environ["PATH"]:
os.environ["PATH"] = ffmpeg_path + os.pathsep + os.environ["PATH"]
@staticmethod
def check_ffmpeg():
"""检查是否可以使用FFmpeg"""
try:
ffmpeg_path = FFmpegInstaller.get_ffmpeg_path()
if ffmpeg_path and os.path.exists(ffmpeg_path):
# 使用打包的FFmpeg
if platform.system().lower() == "windows":
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
result = subprocess.run(
[ffmpeg_path, "-version"],
capture_output=True,
startupinfo=startupinfo,
)
else:
result = subprocess.run(
[ffmpeg_path, "-version"], capture_output=True
)
return result.returncode == 0
# 尝试系统PATH中的FFmpeg
if platform.system().lower() == "windows":
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
result = subprocess.run(
["ffmpeg", "-version"], capture_output=True, startupinfo=startupinfo
)
else:
result = subprocess.run(["ffmpeg", "-version"], capture_output=True)
return result.returncode == 0
except FileNotFoundError:
return False
except Exception as e:
print(f"FFmpeg检测出错: {str(e)}")
return False
@staticmethod
def get_system_info():
"""获取系统信息"""
system = platform.system().lower()
is_64bits = sys.maxsize > 2**32
return system, is_64bits
def show_installation_dialog(self):
"""显示安装向导对话框"""
system, is_64bits = self.get_system_info()
dialog = tk.Toplevel()
dialog.title("FFmpeg 安装向导")
dialog.geometry("500x400")
dialog.transient() # 设置为模态窗口
# 添加说明文本
ttk.Label(
dialog,
text="未检测到 FFmpeg需要先安装 FFmpeg 才能继续使用。",
wraplength=450,
).pack(padx=20, pady=10)
if system == "windows":
self._setup_windows_installer(dialog)
elif system == "darwin": # macOS
self._setup_macos_installer(dialog)
elif system == "linux":
self._setup_linux_installer(dialog)
else:
self._setup_manual_installer(dialog)
dialog.focus_set()
return dialog
def _setup_windows_installer(self, dialog):
"""Windows安装方式"""
ttk.Label(dialog, text="Windows 安装方式:", font=("", 10, "bold")).pack(
padx=20, pady=5
)
# 方式1: Chocolatey
choco_frame = ttk.LabelFrame(dialog, text="方式1使用 Chocolatey推荐")
choco_frame.pack(padx=20, pady=5, fill="x")
ttk.Label(
choco_frame,
text="1. 首先安装 Chocolatey在管理员权限的 PowerShell 中运行:",
wraplength=450,
).pack(padx=5, pady=5)
choco_cmd = """Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))"""
cmd_text = ttk.Entry(choco_frame, width=50)
cmd_text.insert(0, choco_cmd)
cmd_text.pack(padx=5, pady=5)
ttk.Button(
choco_frame,
text="复制命令",
command=lambda: self._copy_to_clipboard(choco_cmd),
).pack(pady=5)
ttk.Label(choco_frame, text="2. 然后安装 FFmpeg运行").pack(padx=5, pady=5)
ffmpeg_cmd = "choco install ffmpeg"
cmd_text2 = ttk.Entry(choco_frame, width=50)
cmd_text2.insert(0, ffmpeg_cmd)
cmd_text2.pack(padx=5, pady=5)
ttk.Button(
choco_frame,
text="复制命令",
command=lambda: self._copy_to_clipboard(ffmpeg_cmd),
).pack(pady=5)
# 方式2: 直接下载
direct_frame = ttk.LabelFrame(dialog, text="方式2直接下载")
direct_frame.pack(padx=20, pady=5, fill="x")
ttk.Label(direct_frame, text="从官方网站下载并手动配置环境变量:").pack(
padx=5, pady=5
)
ttk.Button(
direct_frame,
text="打开下载页面",
command=lambda: webbrowser.open("https://ffmpeg.org/download.html"),
).pack(pady=5)
def _setup_macos_installer(self, dialog):
"""macOS安装方式"""
ttk.Label(dialog, text="macOS 安装方式:", font=("", 10, "bold")).pack(
padx=20, pady=5
)
# 方式1: Homebrew
brew_frame = ttk.LabelFrame(dialog, text="方式1使用 Homebrew推荐")
brew_frame.pack(padx=20, pady=5, fill="x")
ttk.Label(
brew_frame, text="1. 首先安装 Homebrew在终端运行", wraplength=450
).pack(padx=5, pady=5)
brew_cmd = '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'
cmd_text = ttk.Entry(brew_frame, width=50)
cmd_text.insert(0, brew_cmd)
cmd_text.pack(padx=5, pady=5)
ttk.Button(
brew_frame,
text="复制命令",
command=lambda: self._copy_to_clipboard(brew_cmd),
).pack(pady=5)
ttk.Label(brew_frame, text="2. 然后安装 FFmpeg运行").pack(padx=5, pady=5)
ffmpeg_cmd = "brew install ffmpeg"
cmd_text2 = ttk.Entry(brew_frame, width=50)
cmd_text2.insert(0, ffmpeg_cmd)
cmd_text2.pack(padx=5, pady=5)
ttk.Button(
brew_frame,
text="复制命令",
command=lambda: self._copy_to_clipboard(ffmpeg_cmd),
).pack(pady=5)
def _setup_linux_installer(self, dialog):
"""Linux安装方式"""
ttk.Label(dialog, text="Linux 安装方式:", font=("", 10, "bold")).pack(
padx=20, pady=5
)
# Ubuntu/Debian
ubuntu_frame = ttk.LabelFrame(dialog, text="Ubuntu/Debian")
ubuntu_frame.pack(padx=20, pady=5, fill="x")
ubuntu_cmd = "sudo apt update && sudo apt install ffmpeg"
cmd_text = ttk.Entry(ubuntu_frame, width=50)
cmd_text.insert(0, ubuntu_cmd)
cmd_text.pack(padx=5, pady=5)
ttk.Button(
ubuntu_frame,
text="复制命令",
command=lambda: self._copy_to_clipboard(ubuntu_cmd),
).pack(pady=5)
# CentOS/RHEL
centos_frame = ttk.LabelFrame(dialog, text="CentOS/RHEL")
centos_frame.pack(padx=20, pady=5, fill="x")
centos_cmd = "sudo yum install epel-release && sudo yum install ffmpeg"
cmd_text2 = ttk.Entry(centos_frame, width=50)
cmd_text2.insert(0, centos_cmd)
cmd_text2.pack(padx=5, pady=5)
ttk.Button(
centos_frame,
text="复制命令",
command=lambda: self._copy_to_clipboard(centos_cmd),
).pack(pady=5)
def _setup_manual_installer(self, dialog):
"""手动安装说明"""
ttk.Label(
dialog, text="请访问 FFmpeg 官方网站下载并安装:", wraplength=450
).pack(padx=20, pady=10)
ttk.Button(
dialog,
text="打开 FFmpeg 官方网站",
command=lambda: webbrowser.open("https://ffmpeg.org/download.html"),
).pack(pady=10)
def _copy_to_clipboard(self, text):
"""复制文本到剪贴板"""
dialog = tk.Toplevel()
dialog.withdraw()
dialog.clipboard_clear()
dialog.clipboard_append(text)
dialog.update()
dialog.destroy()
messagebox.showinfo("提示", "命令已复制到剪贴板!")
class VideoToGifConverter: class VideoToGifConverter:
def __init__(self): def __init__(self):
self.check_ffmpeg_installation()
# 创建主窗口 # 创建主窗口
if SUPPORT_DND == "tkdnd": if SUPPORT_DND == "tkdnd":
self.root = TkinterDnD.Tk() self.root = TkinterDnD.Tk()