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:
2026-04-11 12:01:02 +02:00
parent 7319ff6299
commit 05ff5765bf
5 changed files with 350 additions and 3 deletions
+16 -1
View File
@@ -1,6 +1,8 @@
"""Whisper-Transkription via faster-whisper."""
import logging
import sys
from pathlib import Path
import numpy as np
from faster_whisper import WhisperModel
@@ -8,11 +10,24 @@ from faster_whisper import WhisperModel
logger = logging.getLogger(__name__)
def _model_cache_dir() -> str | None:
"""Im gebündelten Modus: Modell neben der EXE cachen (portable).
Im Entwicklungsmodus: None → HuggingFace-Standard-Cache."""
if getattr(sys, "frozen", False):
cache = Path(sys.executable).parent / "models"
try:
cache.mkdir(exist_ok=True)
return str(cache)
except OSError:
return None # Fallback auf HuggingFace-Standard-Cache
return None
class Transcriber:
def __init__(self, model_name: str = "small", compute_type: str = "int8", language: str = "de"):
self.language = language
logger.info("Lade Whisper-Modell '%s' (compute_type=%s)...", model_name, compute_type)
self.model = WhisperModel(model_name, compute_type=compute_type)
self.model = WhisperModel(model_name, compute_type=compute_type, download_root=_model_cache_dir())
logger.info("Modell geladen")
def transcribe(self, audio: np.ndarray) -> str: