添加PyInstaller打包支持和运行时路径修复

- 创建PyInstaller规范文件和打包脚本
- 修复开发/打包环境路径兼容性问题
- 添加PaddleOCR运行时依赖(opencv-contrib-python, pypdfium2, pyclipper)
- 支持打包后的多进程启动
- 修复图标路径和翻译文件路径
- 清理重复的模型和FFmpeg文件
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
yaofanguk
2026-04-10 19:23:05 +08:00
parent 293cd9bbee
commit c80e7fabc9
18 changed files with 423 additions and 33 deletions

View File

@@ -38,11 +38,15 @@ def is_video_or_image(filename):
return file_extension in video_extensions or file_extension in image_extensions
def merge_big_file_if_not_exists(dir, file, man_filename = None):
if file not in os.listdir(dir):
fs = Filesplit()
if man_filename is not None:
fs.man_filename = man_filename
fs.merge(input_dir=dir)
try:
if file not in os.listdir(dir):
fs = Filesplit()
if man_filename is not None:
fs.man_filename = man_filename
fs.merge(input_dir=dir)
except Exception as e:
print(f"Warning: Could not merge big file {file} in {dir}: {e}")
return False
def get_readable_path(path):
if sys.platform != 'win32':

View File

@@ -1,4 +1,5 @@
import os
import sys
import stat
import platform
@@ -21,16 +22,29 @@ class FFmpegCLI:
return cls._instance
def __init__(self):
os.chmod(self.ffmpeg_path, stat.S_IRWXU + stat.S_IRWXG + stat.S_IRWXO)
# 设置 FFmpeg 可执行文件权限
try:
os.chmod(self.ffmpeg_path, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
except Exception as e:
print(f"Warning: Could not set ffmpeg executable permissions: {e}")
@property
def ffmpeg_path(self):
system = platform.system()
# 确保路径正确(打包环境 vs 开发环境)
if getattr(sys, 'frozen', False):
# 打包环境BASE_DIR 指向 sys._MEIPASS
base_path = os.path.join(BASE_DIR, 'backend')
else:
# 开发环境BASE_DIR 已经是项目根目录
base_path = BASE_DIR
if system == "Windows":
ffmpeg_dir = os.path.join(BASE_DIR, 'ffmpeg', 'win_x64')
ffmpeg_dir = os.path.join(base_path, 'ffmpeg', 'win_x64')
merge_big_file_if_not_exists(ffmpeg_dir, 'ffmpeg.exe')
return os.path.join(ffmpeg_dir, 'ffmpeg.exe')
elif system == "Linux":
return os.path.join(BASE_DIR, 'ffmpeg', 'linux_x64', 'ffmpeg')
return os.path.join(base_path, 'ffmpeg', 'linux_x64', 'ffmpeg')
else:
return os.path.join(BASE_DIR, 'ffmpeg', 'macos', 'ffmpeg')
return os.path.join(base_path, 'ffmpeg', 'macos', 'ffmpeg')

View File

@@ -1,4 +1,5 @@
import os
import sys
from backend.config import config, BASE_DIR
from backend.tools.common_tools import merge_big_file_if_not_exists
from backend.tools.constant import SubtitleDetectMode
@@ -10,15 +11,34 @@ _MODEL_NAME_MAP = {
class ModelConfig:
def __init__(self):
self.LAMA_MODEL_DIR = os.path.join(BASE_DIR, 'models', 'big-lama')
self.STTN_AUTO_MODEL_PATH = os.path.join(BASE_DIR, 'models', 'sttn-auto', 'infer_model.pth')
self.STTN_DET_MODEL_PATH = os.path.join(BASE_DIR, 'models', 'sttn-det', 'sttn.pth')
# 确保模型路径正确(打包环境 vs 开发环境)
if getattr(sys, 'frozen', False):
# 打包环境BASE_DIR 指向 sys._MEIPASS
model_base = os.path.join(BASE_DIR, 'backend')
else:
# 开发环境BASE_DIR 已经是项目根目录
model_base = BASE_DIR
self.LAMA_MODEL_DIR = os.path.join(model_base, 'models', 'big-lama')
self.STTN_AUTO_MODEL_PATH = os.path.join(model_base, 'models', 'sttn-auto', 'infer_model.pth')
self.STTN_DET_MODEL_PATH = os.path.join(model_base, 'models', 'sttn-det', 'sttn.pth')
if config.subtitleDetectMode.value == SubtitleDetectMode.PP_OCRv5_MOBILE:
self.DET_MODEL_DIR = os.path.join(BASE_DIR,'models', 'V5', 'ch_det_fast')
self.DET_MODEL_DIR = os.path.join(model_base,'models', 'V5', 'ch_det_fast')
elif config.subtitleDetectMode.value == SubtitleDetectMode.PP_OCRv5_SERVER:
self.DET_MODEL_DIR = os.path.join(BASE_DIR, 'models', 'V5', 'ch_det')
self.DET_MODEL_DIR = os.path.join(model_base, 'models', 'V5', 'ch_det')
else:
raise ValueError(f"Invalid subtitle detect mode: {config.subtitleDetectMode.value}")
self.DET_MODEL_NAME = _MODEL_NAME_MAP[config.subtitleDetectMode.value]
merge_big_file_if_not_exists(self.LAMA_MODEL_DIR, 'bit-lama.pt')
# 尝试合并大文件(如果需要)
lama_file = 'big-lama.pt' # 修正文件名:实际模型文件是 big-lama.pt
lama_file_path = os.path.join(self.LAMA_MODEL_DIR, lama_file)
if not os.path.exists(lama_file_path):
merge_big_file_if_not_exists(self.LAMA_MODEL_DIR, lama_file)
# 检查合并后文件是否存在
if not os.path.exists(lama_file_path):
raise FileNotFoundError(
f"LAMA model file not found: {lama_file_path}. "
f"Please ensure the model file exists in {self.LAMA_MODEL_DIR}"
)