Use editable INI configuration

This commit is contained in:
Melbar
2026-05-07 18:35:36 +02:00
parent bc6c3e83a7
commit f68d2589df
4 changed files with 159 additions and 99 deletions
+73 -17
View File
@@ -1,5 +1,6 @@
from __future__ import annotations
import configparser
import json
import math
import os
@@ -27,7 +28,7 @@ except Exception:
# 1. KONFIGURATION UND PFADE
# =============================================================================
APP_DIR = Path(__file__).resolve().parent
CONFIG_PATH = APP_DIR / "config.json"
CONFIG_PATH = APP_DIR / "config.ini"
DEFAULT_CONFIG = {
"ffmpeg": {
"ffmpeg_exe": "",
@@ -64,29 +65,84 @@ DEFAULT_CONFIG = {
}
def deep_merge_config(default: dict, override: dict) -> dict:
merged = dict(default)
for key, value in override.items():
if isinstance(value, dict) and isinstance(merged.get(key), dict):
merged[key] = deep_merge_config(merged[key], value)
else:
merged[key] = value
return merged
def write_default_config(path: Path) -> None:
path.write_text(json.dumps(DEFAULT_CONFIG, indent=2) + "\n", encoding="utf-8")
path.write_text(
"""# Amazon PVD Mezzanine Encoder Konfiguration
# Zeilen mit # sind Kommentare.
# Leere Werte bedeuten: automatisch suchen bzw. automatisch waehlen.
[ffmpeg]
# Optional: feste Pfade setzen. Leer lassen fuer automatische Suche.
ffmpeg_exe =
ffprobe_exe =
# Suchordner nach PATH. Mehrere Ordner mit Komma trennen.
search_dirs = C:\\Tools\\FFMPEG, C:\\Software
[output]
# Optional: festes Zielverzeichnis. Leer lassen fuer preferred_dirs.
base_dir =
# Erstes vorhandenes Verzeichnis wird verwendet.
preferred_dirs = F:\\VOD, H:\\VOD
[video]
# HD-PVD-MP4
hd_bitrate = 30M
hd_maxrate = 35M
hd_bufsize = 50M
hd_level = 4.1
# SD-PVD-MP4
sd_bitrate = 8M
sd_maxrate = 10M
sd_bufsize = 15M
sd_level = 3.1
# x264
preset = slow
tune = film
[audio]
# Deutscher Stereo-Ton im MP4
mp4_bitrate = 256k
sample_rate = 48000
# Audio-MOVs
pcm_codec = pcm_s24le
""",
encoding="utf-8",
)
def split_config_list(value: str) -> list[str]:
return [part.strip() for part in value.split(",") if part.strip()]
def load_config() -> dict:
if not CONFIG_PATH.exists():
write_default_config(CONFIG_PATH)
return DEFAULT_CONFIG
try:
user_config = json.loads(CONFIG_PATH.read_text(encoding="utf-8"))
except json.JSONDecodeError as exc:
raise RuntimeError(f"config.json ist ungueltig: {exc}") from exc
return deep_merge_config(DEFAULT_CONFIG, user_config)
parser = configparser.ConfigParser()
parser.read(CONFIG_PATH, encoding="utf-8")
config = {
section: dict(values)
for section, values in DEFAULT_CONFIG.items()
}
for section, defaults in DEFAULT_CONFIG.items():
if not parser.has_section(section):
continue
for key, default_value in defaults.items():
if not parser.has_option(section, key):
continue
raw_value = parser.get(section, key).strip()
if isinstance(default_value, list):
config[section][key] = split_config_list(raw_value)
else:
config[section][key] = raw_value
return config
def find_executable(name: str, configured_path: str, search_dirs: list[str]) -> str: