Cross-platform distribution, UI improvements, and performance optimizations
- PyInstaller frozen sidecar: spec file, build script, and ffmpeg path resolver for self-contained distribution without Python prerequisites - Dual-mode sidecar launcher: frozen binary (production) with dev mode fallback - Parallel transcription + diarization pipeline (~30-40% faster) - GPU auto-detection for diarization (CUDA when available) - Async run_pipeline command for real-time progress event delivery - Web Audio API backend for instant playback and seeking - OpenAI-compatible provider replacing LiteLLM client-side routing - Cross-platform RAM detection (Linux/macOS/Windows) - Settings: speaker count hint, token reveal toggles, dark dropdown styling - Loading splash screen, flexbox layout fix for viewport overflow - Gitea Actions CI/CD pipeline (Linux, Windows, macOS ARM) - Updated README and CLAUDE.md documentation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,10 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ctypes
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
|
||||
@@ -21,6 +24,77 @@ class HardwareInfo:
|
||||
recommended_compute_type: str = "int8"
|
||||
|
||||
|
||||
def _detect_ram_mb() -> int:
|
||||
"""Detect total system RAM in MB (cross-platform).
|
||||
|
||||
Tries platform-specific methods in order:
|
||||
1. Linux: read /proc/meminfo
|
||||
2. macOS: sysctl hw.memsize
|
||||
3. Windows: GlobalMemoryStatusEx via ctypes
|
||||
4. Fallback: os.sysconf (most Unix systems)
|
||||
|
||||
Returns 0 if all methods fail.
|
||||
"""
|
||||
# Linux: read /proc/meminfo
|
||||
if sys.platform == "linux":
|
||||
try:
|
||||
with open("/proc/meminfo") as f:
|
||||
for line in f:
|
||||
if line.startswith("MemTotal:"):
|
||||
# Value is in kB
|
||||
return int(line.split()[1]) // 1024
|
||||
except (FileNotFoundError, ValueError, OSError):
|
||||
pass
|
||||
|
||||
# macOS: sysctl hw.memsize (returns bytes)
|
||||
if sys.platform == "darwin":
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["sysctl", "-n", "hw.memsize"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
return int(result.stdout.strip()) // (1024 * 1024)
|
||||
except (subprocess.SubprocessError, ValueError, OSError):
|
||||
pass
|
||||
|
||||
# Windows: GlobalMemoryStatusEx via ctypes
|
||||
if sys.platform == "win32":
|
||||
try:
|
||||
|
||||
class MEMORYSTATUSEX(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("dwLength", ctypes.c_ulong),
|
||||
("dwMemoryLoad", ctypes.c_ulong),
|
||||
("ullTotalPhys", ctypes.c_ulonglong),
|
||||
("ullAvailPhys", ctypes.c_ulonglong),
|
||||
("ullTotalPageFile", ctypes.c_ulonglong),
|
||||
("ullAvailPageFile", ctypes.c_ulonglong),
|
||||
("ullTotalVirtual", ctypes.c_ulonglong),
|
||||
("ullAvailVirtual", ctypes.c_ulonglong),
|
||||
("ullAvailExtendedVirtual", ctypes.c_ulonglong),
|
||||
]
|
||||
|
||||
mem_status = MEMORYSTATUSEX()
|
||||
mem_status.dwLength = ctypes.sizeof(MEMORYSTATUSEX)
|
||||
if ctypes.windll.kernel32.GlobalMemoryStatusEx(ctypes.byref(mem_status)):
|
||||
return int(mem_status.ullTotalPhys) // (1024 * 1024)
|
||||
except (AttributeError, OSError):
|
||||
pass
|
||||
|
||||
# Fallback: os.sysconf (works on most Unix systems)
|
||||
try:
|
||||
page_size = os.sysconf("SC_PAGE_SIZE")
|
||||
phys_pages = os.sysconf("SC_PHYS_PAGES")
|
||||
if page_size > 0 and phys_pages > 0:
|
||||
return (page_size * phys_pages) // (1024 * 1024)
|
||||
except (ValueError, OSError, AttributeError):
|
||||
pass
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def detect_hardware() -> HardwareInfo:
|
||||
"""Detect available hardware and recommend model configuration."""
|
||||
info = HardwareInfo()
|
||||
@@ -28,16 +102,8 @@ def detect_hardware() -> HardwareInfo:
|
||||
# CPU info
|
||||
info.cpu_cores = os.cpu_count() or 1
|
||||
|
||||
# RAM info
|
||||
try:
|
||||
with open("/proc/meminfo") as f:
|
||||
for line in f:
|
||||
if line.startswith("MemTotal:"):
|
||||
# Value is in kB
|
||||
info.ram_mb = int(line.split()[1]) // 1024
|
||||
break
|
||||
except (FileNotFoundError, ValueError):
|
||||
pass
|
||||
# RAM info (cross-platform)
|
||||
info.ram_mb = _detect_ram_mb()
|
||||
|
||||
# CUDA detection
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user