feat: Windows-Packaging mit PyInstaller (ZIP ohne Python-Installation)
Fügt Build-Infrastruktur hinzu, mit der whisper-local als selbständiges Windows-ZIP-Paket ohne Python-Installation bereitgestellt werden kann. - whisper_local.spec: PyInstaller onedir-Konfiguration für Windows 64-bit mit allen nativen DLLs (ctranslate2/CUDA, pywin32, PortAudio, onnxruntime, av/FFmpeg) und Hidden Imports für platform-bedingte Backends - build.ps1: Build-Skript das versioniertes ZIP erstellt (.\build.ps1 -Clean) - transcriber.py: portabler Modell-Cache neben der EXE im gebündelten Modus - pyproject.toml: pyinstaller>=6.0 als [build]-Abhängigkeitsgruppe, v1.0.0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
# whisper_local.spec
|
||||
# PyInstaller-Build-Konfiguration für whisper-local (Windows 64-bit, onedir)
|
||||
#
|
||||
# Ausführen: uv run pyinstaller whisper_local.spec --noconfirm
|
||||
# Oder via: .\build.ps1
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from PyInstaller.utils.hooks import collect_data_files
|
||||
|
||||
block_cipher = None
|
||||
|
||||
SP = Path(".venv/Lib/site-packages")
|
||||
|
||||
# ── Binaries ──────────────────────────────────────────────────────────────────
|
||||
# ctranslate2: Haupt-DLL, CUDA (cudnn) und Intel OpenMP
|
||||
# DLLs landen in ctranslate2/, damit ctranslate2's os.add_dll_directory() greift
|
||||
binaries_list = [
|
||||
(str(SP / "ctranslate2/ctranslate2.dll"), "ctranslate2"),
|
||||
(str(SP / "ctranslate2/cudnn64_9.dll"), "ctranslate2"),
|
||||
(str(SP / "ctranslate2/libiomp5md.dll"), "ctranslate2"),
|
||||
|
||||
# pywin32: COM- und WinTypes-DLLs müssen neben der EXE liegen
|
||||
(str(SP / "pywin32_system32/pythoncom313.dll"), "."),
|
||||
(str(SP / "pywin32_system32/pywintypes313.dll"), "."),
|
||||
|
||||
# sounddevice / PortAudio
|
||||
(str(SP / "_sounddevice_data/portaudio-binaries/libportaudio64bit.dll"),
|
||||
"_sounddevice_data/portaudio-binaries"),
|
||||
(str(SP / "_sounddevice_data/portaudio-binaries/libportaudio64bit-asio.dll"),
|
||||
"_sounddevice_data/portaudio-binaries"),
|
||||
|
||||
# onnxruntime (für Silero VAD in faster-whisper)
|
||||
(str(SP / "onnxruntime/capi/onnxruntime.dll"),
|
||||
"onnxruntime/capi"),
|
||||
(str(SP / "onnxruntime/capi/onnxruntime_providers_shared.dll"),
|
||||
"onnxruntime/capi"),
|
||||
]
|
||||
|
||||
# av/FFmpeg: DLL-Namen enthalten Hashes — per Glob gesammelt
|
||||
av_libs_dir = SP / "av.libs"
|
||||
binaries_list += [(str(dll), "av.libs") for dll in av_libs_dir.glob("*.dll")]
|
||||
|
||||
# ── Datas ─────────────────────────────────────────────────────────────────────
|
||||
datas_list = [
|
||||
# Silero VAD ONNX-Modell (benötigt von faster-whisper)
|
||||
(str(SP / "faster_whisper/assets/silero_vad_v6.onnx"),
|
||||
"faster_whisper/assets"),
|
||||
|
||||
# sv_ttk Theme (TCL-Skripte + PNG-Spritesheets)
|
||||
(str(SP / "sv_ttk/sv.tcl"), "sv_ttk"),
|
||||
(str(SP / "sv_ttk/theme"), "sv_ttk/theme"),
|
||||
|
||||
# Beispiel-Konfiguration als Referenz
|
||||
("config.example.toml", "."),
|
||||
]
|
||||
|
||||
# certifi CA-Bundle für HTTPS (huggingface_hub Modell-Download)
|
||||
datas_list += collect_data_files("certifi")
|
||||
|
||||
# ── Hidden Imports ────────────────────────────────────────────────────────────
|
||||
# Alle Module hinter sys.platform-Guards oder lazy imports (importlib, __import__)
|
||||
hidden_imports_list = [
|
||||
# Eigene Windows-Backends (hinter sys.platform == "win32" Guards)
|
||||
"whisper_local.hotkey._pynput",
|
||||
"whisper_local.inserter._win32",
|
||||
"whisper_local.tray._tray",
|
||||
"whisper_local.tray._icon",
|
||||
"whisper_local.tray._settings",
|
||||
"whisper_local.tray._theme",
|
||||
|
||||
# pynput: Backend wird per importlib dynamisch gewählt
|
||||
"pynput.keyboard._win32",
|
||||
"pynput.mouse._win32",
|
||||
"pynput._util",
|
||||
"pynput._util.win32",
|
||||
"pynput._util.win32_vks",
|
||||
|
||||
# pywin32
|
||||
"win32api",
|
||||
"win32con",
|
||||
"win32gui",
|
||||
"win32clipboard",
|
||||
"pywintypes",
|
||||
|
||||
# pystray Windows-Backend + Utility-Unterpaket (relative imports)
|
||||
"pystray._win32",
|
||||
"pystray._util",
|
||||
"pystray._util.win32",
|
||||
|
||||
# tkinter: lazy import in tray/_settings.py
|
||||
"tkinter",
|
||||
"tkinter.ttk",
|
||||
|
||||
# sv_ttk und darkdetect
|
||||
"sv_ttk",
|
||||
"darkdetect",
|
||||
|
||||
# onnxruntime Inference Collection
|
||||
"onnxruntime.capi.onnxruntime_inference_collection",
|
||||
|
||||
# huggingface_hub für Modell-Download zur Laufzeit
|
||||
"huggingface_hub",
|
||||
"huggingface_hub.file_download",
|
||||
"huggingface_hub.utils",
|
||||
]
|
||||
|
||||
# ── Excludes ──────────────────────────────────────────────────────────────────
|
||||
excludes_list = [
|
||||
# Linux-only (nicht installiert auf Windows)
|
||||
"evdev",
|
||||
"whisper_local.hotkey._evdev",
|
||||
"whisper_local.inserter._wayland",
|
||||
# Build- und Test-Infrastruktur
|
||||
"pytest",
|
||||
"pytest_asyncio",
|
||||
"hatchling",
|
||||
# Nicht benötigt im gebündelten Binary
|
||||
"unittest",
|
||||
"doctest",
|
||||
"pdb",
|
||||
]
|
||||
|
||||
# ── Analysis ──────────────────────────────────────────────────────────────────
|
||||
a = Analysis(
|
||||
["whisper_local/__main__.py"],
|
||||
pathex=["."],
|
||||
binaries=binaries_list,
|
||||
datas=datas_list,
|
||||
hiddenimports=hidden_imports_list,
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=excludes_list,
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False,
|
||||
)
|
||||
|
||||
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
[],
|
||||
exclude_binaries=True, # onedir-Modus: DLLs bleiben separat
|
||||
name="whisper-local",
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=False, # UPX mit CUDA-DLLs deaktiviert
|
||||
console=False, # kein Konsolenfenster (Tray-App)
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
||||
|
||||
coll = COLLECT(
|
||||
exe,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
strip=False,
|
||||
upx=False,
|
||||
upx_exclude=[],
|
||||
name="whisper-local",
|
||||
)
|
||||
Reference in New Issue
Block a user