mirror of
https://github.com/YaoFANGUK/video-subtitle-remover.git
synced 2026-05-03 15:27:31 +08:00
- 创建PyInstaller规范文件和打包脚本 - 修复开发/打包环境路径兼容性问题 - 添加PaddleOCR运行时依赖(opencv-contrib-python, pypdfium2, pyclipper) - 支持打包后的多进程启动 - 修复图标路径和翻译文件路径 - 清理重复的模型和FFmpeg文件 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
222 lines
7.0 KiB
Python
222 lines
7.0 KiB
Python
#!/usr/bin/env python
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
基于官方 PaddleX 打包脚本改编的视频字幕去除器打包脚本
|
||
"""
|
||
|
||
import importlib.metadata
|
||
import argparse
|
||
import subprocess
|
||
import sys
|
||
import os
|
||
|
||
def get_installed_packages():
|
||
"""获取当前环境中已安装的包"""
|
||
return [dist.metadata["Name"] for dist in importlib.metadata.distributions()]
|
||
|
||
def build_package(main_file, include_cuda=False):
|
||
"""构建打包命令"""
|
||
# 基础命令
|
||
cmd = [
|
||
"pyinstaller", main_file,
|
||
"--clean",
|
||
"--noconfirm",
|
||
"--name", "VideoSubtitleRemover",
|
||
"--icon", "design/vsr.ico",
|
||
"--console", # 先启用控制台以便调试
|
||
]
|
||
|
||
# 收集数据文件
|
||
cmd += [
|
||
"--add-data", "backend/models/big-lama;backend/models/big-lama",
|
||
"--add-data", "backend/models/sttn-auto;backend/models/sttn-auto",
|
||
"--add-data", "backend/models/sttn-det;backend/models/sttn-det",
|
||
"--add-data", "backend/models/V5;backend/models/V5",
|
||
"--add-data", "backend/interface;backend/interface",
|
||
"--add-data", "backend/ffmpeg/win_x64/ffmpeg.exe;backend/ffmpeg/win_x64",
|
||
"--add-data", "config/config.json;config",
|
||
"--add-data", "design/vsr.ico;design",
|
||
]
|
||
|
||
# 收集重要包的数据和二进制文件
|
||
cmd += [
|
||
"--collect-data", "paddleocr",
|
||
"--collect-data", "skimage",
|
||
"--collect-binaries", "paddle",
|
||
"--collect-data", "opencv-python",
|
||
"--collect-data", "cv2",
|
||
]
|
||
|
||
# 隐藏导入
|
||
hidden_imports = [
|
||
# GUI 相关
|
||
"PySide6.QtCore",
|
||
"PySide6.QtGui",
|
||
"PySide6.QtWidgets",
|
||
"PySide6.QtNetwork",
|
||
"qfluentwidgets",
|
||
"qframelesswindow",
|
||
|
||
# 深度学习相关
|
||
"torch",
|
||
"torchvision",
|
||
"paddle",
|
||
"paddleocr",
|
||
"paddleocr.ppocr",
|
||
"paddleocr.ppocr.api",
|
||
"paddleocr.ppocr.utils",
|
||
|
||
# 图像处理
|
||
"cv2",
|
||
"cv2.data",
|
||
"cv2.matplotlib",
|
||
"cv2.typing",
|
||
"numpy",
|
||
"PIL",
|
||
"scipy",
|
||
"scipy.spatial",
|
||
"scipy.spatial.transform",
|
||
"scipy.ndimage",
|
||
|
||
# 视频处理
|
||
"av",
|
||
|
||
# 工具库
|
||
"tqdm",
|
||
"requests",
|
||
"configparser",
|
||
"einops",
|
||
"darkdetect",
|
||
"je_showinfilemanager",
|
||
"filesplit",
|
||
|
||
# 项目模块
|
||
"backend",
|
||
"backend.inpaint",
|
||
"backend.inpaint.lama_inpaint",
|
||
"backend.inpaint.sttn_auto_inpaint",
|
||
"backend.inpaint.sttn_det_inpaint",
|
||
"backend.inpaint.opencv_inpaint",
|
||
"backend.tools",
|
||
"backend.tools.ocr",
|
||
"backend.tools.subtitle_detect",
|
||
"backend.tools.subtitle_remover_remote_call",
|
||
"backend.tools.video_io",
|
||
"backend.tools.ffmpeg_cli",
|
||
"backend.tools.process_manager",
|
||
"backend.tools.hardware_accelerator",
|
||
"backend.tools.inpaint_tools",
|
||
"backend.tools.common_tools",
|
||
"backend.config",
|
||
"backend.scenedetect",
|
||
"ui",
|
||
"ui.home_interface",
|
||
"ui.advanced_setting_interface",
|
||
"ui.setting_interface",
|
||
"ui.component",
|
||
"ui.component.video_display_component",
|
||
"ui.component.task_list_component",
|
||
"ui.icon.my_fluent_icon",
|
||
]
|
||
|
||
for imp in hidden_imports:
|
||
cmd += ["--hidden-import", imp]
|
||
|
||
# 排除不需要的模块
|
||
excludes = [
|
||
"pytest", "unittest", "test", "tests",
|
||
"IPython", "jupyter", "notebook", "ipykernel",
|
||
"paddle.fluid.contrib", "paddle.fluid.dygraph", "paddle.fluid.optimizer",
|
||
"torch.utils.tensorboard", "torch.utils.bottleneck",
|
||
"sphinx", "docutils", "pandas", "matplotlib", "seaborn",
|
||
"scrapy", "beautifulsoup4", "lxml", "sklearn", "xgboost", "lightgbm",
|
||
]
|
||
|
||
for exc in excludes:
|
||
cmd += ["--exclude-module", exc]
|
||
|
||
# CUDA 支持
|
||
if include_cuda:
|
||
cmd += ["--collect-binaries", "nvidia"]
|
||
print("注意: 包含 NVIDIA CUDA 依赖")
|
||
|
||
# 复制重要包的元数据(只复制确实存在的包)
|
||
important_packages = ["PySide6", "paddleocr", "torch", "torchvision", "numpy", "opencv-python", "scipy", "Pillow", "opencv-contrib-python"]
|
||
installed = get_installed_packages()
|
||
|
||
for pkg in important_packages:
|
||
if pkg in installed:
|
||
try:
|
||
cmd += ["--copy-metadata", pkg]
|
||
except:
|
||
print(f"Warning: Could not copy metadata for {pkg}")
|
||
continue
|
||
|
||
# UPX 压缩
|
||
cmd += ["--upx-dir", "C:/upx"] if os.path.exists("C:/upx") else ["--noupx"]
|
||
|
||
return cmd
|
||
|
||
def main():
|
||
parser = argparse.ArgumentParser(description="视频字幕去除器打包脚本")
|
||
parser.add_argument('--file', default='gui.py', help='主文件名,默认为 gui.py')
|
||
parser.add_argument('--nvidia', action='store_true', help='包含 NVIDIA CUDA 和 cuDNN 依赖')
|
||
parser.add_argument('--console', action='store_true', help='显示控制台窗口(用于调试)')
|
||
|
||
args = parser.parse_args()
|
||
main_file = args.file
|
||
|
||
if not os.path.exists(main_file):
|
||
print(f"错误: 找不到文件 {main_file}")
|
||
sys.exit(1)
|
||
|
||
print("========================================")
|
||
print(" 视频字幕去除器 - PyInstaller 打包")
|
||
print("========================================")
|
||
print(f"主文件: {main_file}")
|
||
print(f"CUDA 支持: {'是' if args.nvidia else '否'}")
|
||
print(f"控制台: {'显示' if args.console else '隐藏'}")
|
||
print()
|
||
|
||
# 构建命令
|
||
cmd = build_package(main_file, include_cuda=args.nvidia)
|
||
|
||
# 如果不显示控制台,添加 --noconsole
|
||
if not args.console:
|
||
cmd.append("--noconsole")
|
||
|
||
print("PyInstaller 命令:")
|
||
print(" ".join(cmd))
|
||
print()
|
||
print("开始打包,这可能需要几分钟...")
|
||
print()
|
||
|
||
try:
|
||
# 执行打包,使用当前Python环境(vsr环境)
|
||
result = subprocess.run(cmd, check=True, env=os.environ.copy())
|
||
print()
|
||
print("========================================")
|
||
print(" ✓ 打包成功完成!")
|
||
print("========================================")
|
||
print(f"输出目录: dist/VideoSubtitleRemover/")
|
||
print()
|
||
print("下一步:")
|
||
print("1. 测试运行: dist/VideoSubtitleRemover/VideoSubtitleRemover.exe")
|
||
print("2. 如果测试通过,可以删除 build/ 目录以节省空间")
|
||
return 0
|
||
|
||
except subprocess.CalledProcessError as e:
|
||
print()
|
||
print("========================================")
|
||
print(" ✗ 打包失败!")
|
||
print("========================================")
|
||
print(f"错误代码: {e.returncode}")
|
||
print()
|
||
print("故障排除:")
|
||
print("1. 检查是否所有依赖都已安装: pip list")
|
||
print("2. 查看详细错误日志: build/VideoSubtitleRemover/warn-VideoSubtitleRemover.txt")
|
||
print("3. 尝试使用 --console 参数查看详细错误信息")
|
||
return 1
|
||
|
||
if __name__ == '__main__':
|
||
sys.exit(main()) |