Professioneller Karaoke-Workflow: Vom Song zur Bühne, vollautomatisiert
Eine Individual-Lösung für die automatisierte Erstellung von Karaoke-Dateien mit KI-gestützter Audiotrennung, Texterkennung und professionellem Audio-Routing. Komplett offline, ohne Cloud, ohne SaaS, ohne Kreditkarte.
Im Rahmen eines Kundenauftrags entstand eine durchdachte Toolchain, die den gesamten Prozess der Karaoke-Erstellung automatisiert. Von der Original-MP3 bis zum abspielfertigen Karaoke-Paket. Was früher händische Arbeit mit teurer Spezialsoftware erforderte, erledigt heute eine Pipeline aus Open-Source-Werkzeugen und lokalen KI-Modellen auf handelsüblicher Hardware.
Sämtliche Verarbeitung findet lokal statt. Es werden keine Audiodaten an externe Server gesendet, keine API-Keys benötigt, keine Abonnements abgeschlossen. Die eingesetzten KI-Modelle laufen vollständig auf der eigenen GPU. Das System funktioniert nach der einmaligen Einrichtung komplett ohne Internetverbindung.
Teil 1: Von Audio zum Karaoke-Format
1. Stem Separation: Gesang und Instrumente trennen mit htdemucs_ft
Jede Karaoke-Datei beginnt mit einer fundamentalen Aufgabe. Den Gesang vom Instrumental trennen. Dafür kommt Demucs zum Einsatz, ein KI-Modell aus der Forschungsabteilung von Meta (Facebook). Das Modell htdemucs_ft (Hybrid Transformer Demucs, fine-tuned) ist die aktuell beste Variante. Es kombiniert Transformer-Architektur mit klassischer Signalverarbeitung und wurde zusätzlich auf realen Musikdaten feinabgestimmt.
Das Modell läuft vollständig lokal auf der GPU. Es werden keine Audiodaten an externe Server übertragen.
Das Ergebnis sind zwei saubere Audio-Spuren: die isolierte Gesangsspur und ein vollständiges Instrumental ohne Stimme. Beide Spuren werden als hochwertige 320 kbit/s MP3-Dateien exportiert. Die Verarbeitung benötigt je nach Songlänge nur wenige Minuten.
Die Gesangsspur dient der Texterkennung im nächsten Schritt. Das Instrumental wird später die Grundlage der Karaoke-Wiedergabe.
2. Texterkennung: Wort-genaue Zeitstempel mit Faster Whisper
Aus der isolierten Gesangsspur extrahiert Faster Whisper den gesungenen Text inklusive präziser Wort-Zeitstempel. Faster Whisper ist eine optimierte Variante von OpenAIs Whisper-Modell, portiert auf das CTranslate2-Framework. Es läuft vollständig lokal auf der GPU und benötigt weder API-Key noch Internetverbindung. Für jedes erkannte Wort liefert das Modell die exakte Start- und Endzeit in Sekunden sowie einen Konfidenzwert.
Für besonders stabile Zeitstempel kann alternativ stable-ts eingesetzt werden, eine Erweiterung, die Whisper-Timestamps mithilfe von Voice Activity Detection (VAD) und Stille-Unterdrückung nachkorrigiert. Das löst ein bekanntes Whisper-Problem: falsche Zeitstempel nach langen Instrumentalpausen, bei denen das Modell vereinzelt Geisterwörter halluziniert.
Die Rohtranskription wird als JSON-Datei gespeichert und enthält den erkannten Text segmentiert in Wörter und Sätze, jeweils mit Zeitstempel und Konfidenzwert. Wörter mit niedriger Konfidenz und auffällig großen Zeitlücken zum Nachbarwort werden automatisch als potenzielle Fehlerkennungen markiert und in ihrer Zeitposition korrigiert.
In einem manuellen Zwischenschritt überarbeitet der Anwender den Rohtext. Falsch erkannte Wörter werden korrigiert, Zeilen nach der tatsächlichen Gesangsstruktur umgebrochen und Strophen, Refrains und Bridges durch Leerzeilen voneinander getrennt.
Für Songs, bei denen Whisper komplett versagt (etwa bei Growling, Screaming oder stark verzerrtem Gesang), steht ein manueller Alignment-Modus zur Verfügung. Ein Terminal-basiertes Interface (TUI) spielt den Song ab, während der Anwender mit Tastendruck den Start und das Ende jeder Textzeile markiert.
3. Alignment: Text und Timing zusammenführen
Das Alignment ist der Schritt, in dem der manuell korrigierte Songtext mit den Whisper-Zeitstempeln zusammengeführt wird. Ein Matching-Algorithmus auf Basis von Sequenzvergleichen ordnet jedes Wort des korrekten Songtexts dem zeitlich passenden Whisper-Wort zu. Das funktioniert auch dann zuverlässig, wenn Whisper den Text teilweise falsch erkannt hat.
Korrekturen, hinzugefügte oder entfernte Wörter werden dabei berücksichtigt. Der Algorithmus erkennt Einfügungen, Löschungen und Ersetzungen und interpoliert fehlende Zeitstempel anhand der Nachbarwörter. Zusätzlich erkennt eine Ausreißer-Korrektur Wörter, die Whisper zeitlich falsch platziert hat (erkennbar an niedriger Konfidenz kombiniert mit großer Zeitlücke), und korrigiert deren Position automatisch.
Das Ergebnis ist eine Enhanced LRC-Datei.
4. Enhanced LRC: Das Zwischenformat mit Wort-Level-Timing
LRC (Lyrics) ist ein weit verbreitetes, textbasiertes Format für synchronisierte Liedtexte. In der einfachen Variante enthält jede Zeile einen einzelnen Zeitstempel, der angibt, wann die Zeile eingeblendet wird.
Die erweiterte Variante, Enhanced LRC, geht einen Schritt weiter. Hier trägt jedes einzelne Wort innerhalb einer Zeile seinen eigenen Zeitstempel. Das ermöglicht das typische Karaoke-Highlighting, bei dem die Wörter einzeln und in Echtzeit farbig hervorgehoben werden, während sie gesungen werden sollen.
Eine Enhanced LRC-Zeile sieht so aus:
[01:12.50]<01:12.50>Ich <01:13.20>bin <01:13.80>froh <01:14.10>dass <01:14.60>ich
Der Zeitstempel in eckigen Klammern markiert den Zeilenstart. Die spitzen Klammern vor jedem Wort markieren den Wort-Start. Das Format ist rein textbasiert, lässt sich in jedem Editor öffnen und manuell nachjustieren.
Leerzeilen im Enhanced LRC markieren Block-Grenzen. Diese Blöcke entsprechen den Strophen und Refrains des Songs und steuern die Darstellung auf dem Karaoke-Bildschirm. Pro Block werden alle Zeilen gleichzeitig angezeigt (maximal acht), das aktive Wort wird farbig hervorgehoben. Nicht gesungene Wörter erscheinen in Weiß, das aktuell gesungene Wort wechselt zu Gelb. Wenn ein Block abgesungen ist, erscheint der nächste.
5. Von LRC zu CDG: Konvertierung ins Karaoke-Standardformat
CDG (CD+Graphics) ist das internationale Industrieformat für Karaoke. Ein Binärformat aus den 1980er Jahren, das noch heute von praktisch jedem Karaoke-Player unterstützt wird. Es definiert einen 300x216 Pixel großen Bildschirm mit 16 Farben und speichert pixelgenaue Grafik-Befehle, die 300 Mal pro Sekunde ausgewertet werden.
Die Konvertierung rendert den Text aus dem Enhanced LRC in CDG-Tiles. Jede Textzeile wird als Bitmap-Grafik berechnet, tile-weise in die CDG-Paketstruktur codiert. Die Wort-Highlights werden über XOR-Operationen realisiert. Dieser Ansatz ermöglicht es, einzelne Wörter farblich umzuschalten, ohne den gesamten Bildschirm neu aufbauen zu müssen.
Die Schriftgröße passt sich automatisch an die Blockgröße an. Wenige Zeilen ergeben eine größere, gut lesbare Schrift. Viele Zeilen pro Block führen zu einer kleineren Darstellung, die dennoch innerhalb der sicheren CDG-Ränder bleibt.
6. Multiplex-Audio: Zwei Spuren in einem Stereo-Signal
Ein wesentliches Feature professioneller Karaoke-Systeme ist die Möglichkeit, den Originalgesang stufenlos dazu zu mischen. Als Orientierungshilfe für unsichere Sänger oder zum Mitsingen.
Die Lösung ist ein Multiplex-Verfahren. Das Instrumental wird auf den linken Stereokanal gelegt, der Original-Mix mit Gesang auf den rechten. In einer einzigen Stereo-MP3 (320 kbit/s) stecken damit beide Versionen.
Am Wiedergabegerät genügt ein Balance-Regler, um stufenlos zwischen reinem Instrumental (links), gemischtem Signal (Mitte) und Originalgesang (rechts) zu überblenden.
Teil 2: Karaoke-Format und Wiedergabe
7. Wiedergabe mit OpenKJ
OpenKJ ist eine quelloffene, plattformübergreifende Karaoke-Hosting-Software, die alle beschriebenen Formate nativ unterstützt. Die beiden Ausgabedateien, CDG und Multiplex-MP3, werden in einen Song-Ordner gelegt, den OpenKJ als Datenbank einliest. Dateinamen folgen dabei dem Schema Interpret - Titel.cdg und Interpret - Titel.mp3.
Auch ohne externes Mischpult bietet OpenKJ die Möglichkeit, das Multiplex-Signal zu steuern. In den Audio-Einstellungen lässt sich wählen zwischen Left (nur Instrumental), Both (Stereo gemischt) und Right (nur Original mit Gesang). Damit ist ein vollwertiger Karaoke-Betrieb bereits mit einem Computer, einem Bildschirm und einem Mikrofon möglich.
Darüber hinaus bietet OpenKJ eine Sänger-Warteschlange, eine Web-basierte Song-Anfrage per Smartphone, automatische Pausenmusik zwischen den Songs, Tonhöhen- und Tempo-Anpassung sowie die Möglichkeit, ein eigenes Hintergrundbild oder eine Diashow auf dem Karaoke-Monitor anzuzeigen.
8. Professionelles Setup mit Mischpult und Mono-Splitter
Wer ein professionelles Mischpult betreibt, kann das Multiplex-Signal noch gezielter nutzen. Der Stereo-Ausgang der Soundkarte wird dafür in zwei Mono-Signale aufgetrennt.
Der linke Kanal (Instrumental) wird über einen Mono-Splitter auf einen Mischpult-Kanal geführt (z.B. CH1). Der rechte Kanal (Originalgesang) geht ebenfalls über einen Mono-Splitter auf einen zweiten Kanal (z.B. CH2). Beide Kanäle liegen damit einzeln am Mischpult an.
Das ermöglicht eine feingranulare Kontrolle. CH1 (Instrumental) läuft auf voller Lautstärke. CH2 (Gesang) wird nur bei Bedarf stufenlos dazu geregelt. Über die Kanalzüge lassen sich zusätzlich EQ-Einstellungen pro Kanal vornehmen. Etwa den Gesangskanal im Bassbereich absenken, um ihn dezent unter das Instrumental zu mischen.
Die Mikrofone der Sänger werden direkt am Mischpult angeschlossen und über separate Kanäle geführt. So hat der Techniker volle Kontrolle über alle Signalquellen: Instrumental, Orientierungsgesang und Live-Gesang, unabhängig voneinander mischbar.
Teil 3: Eigenes Whisper-Modell trainieren
9. Warum ein eigenes Modell?
Das vortrainierte Whisper-Modell deckt normale Sprache und sauberen Gesang gut ab. Bei speziellen Genres versagt es jedoch zuverlässig. Gutturales Growling, Screaming, Shouting oder stark dialektgefärbter Gesang werden entweder gar nicht erkannt oder komplett falsch transkribiert. Whisper halluziniert dann Textfragmente, die nichts mit dem Song zu tun haben.
Durch Fine-Tuning auf eigenen Trainingsdaten kann das Modell gezielt auf solche Gesangsstile angepasst werden. Der Vorteil: Man trainiert nicht von Null, sondern baut auf den 680.000 Stunden vortrainiertem Wissen auf und passt nur die letzten Schichten an. Das spart Rechenzeit und funktioniert bereits mit wenigen Stunden Trainingsmaterial.
10. Das Feedback-Prinzip: Vom manuellen Songtext zurück zum Trainingsdatensatz
Im bestehenden Workflow entsteht bei jedem Song ein wertvolles Datenpaar. Die Gesangsspur (Audio) und der manuell korrigierte Songtext (Ground Truth). Genau dieses Paar ist das, was Whisper zum Lernen braucht.
Der Kreislauf sieht so aus:
- Whisper transkribiert den Song (fehlerhaft)
- Der Anwender korrigiert den Text manuell
- Das korrigierte Paar (Audio + Text) wird zum Trainingsdatensatz hinzugefügt
- Nach genügend Beispielen wird das Modell nachtrainiert
- Das verbesserte Modell macht beim nächsten Song weniger Fehler
Mit jedem verarbeiteten Song wird der Trainingsdatensatz größer und das Modell besser. Nach 50 bis 100 Songs eines bestimmten Genres sollte die Erkennungsqualität deutlich steigen.
11. Trainingsdaten vorbereiten
Whisper erwartet Audiodateien im WAV-Format mit 16 kHz Abtastrate und maximal 30 Sekunden Länge pro Segment. Die bereits vorhandenen Dateien aus dem Workflow müssen dafür aufbereitet werden.
Schritt 1: Audio segmentieren
Die Gesangsspur muss in Segmente von maximal 30 Sekunden zerlegt werden. Die Zeitstempel aus der Enhanced LRC-Datei liefern die Schnittpunkte. Jeder Block (Strophe, Refrain) wird ein Segment.
# Segment aus der Gesangsspur schneiden:
ffmpeg -i gesang.mp3 -ss 12.50 -to 28.30 -ar 16000 -ac 1 segment_001.wav
ffmpeg -i gesang.mp3 -ss 30.00 -to 55.80 -ar 16000 -ac 1 segment_002.wav
Schritt 2: CSV-Datei erstellen
Whisper-Fine-Tuning erwartet eine CSV-Datei mit zwei Spalten: dem Pfad zur Audiodatei und dem zugehörigen Text.
audio,sentence
segments/segment_001.wav,"Lorem ipsum dolor sit amet, consetetur sadipscing elitr"
segments/segment_002.wav,"sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat"
Schritt 3: Dataset-Objekt erstellen
import pandas as pd
from datasets import Dataset, Audio
df = pd.read_csv("training_data.csv")
dataset = Dataset.from_pandas(df)
dataset = dataset.cast_column("audio", Audio(sampling_rate=16000))
# Train/Test Split
dataset = dataset.train_test_split(test_size=0.1)
12. Fine-Tuning mit LoRA auf 8 GB VRAM
Ein vollständiges Fine-Tuning von Whisper large-v3 würde mindestens 24 GB VRAM erfordern. Das ist auf Consumer-Hardware nicht praktikabel. Mit LoRA (Low-Rank Adaptation) und 8-bit-Quantisierung wird das Problem gelöst: Statt alle 1,6 Milliarden Parameter zu trainieren, werden die Originalgewichte eingefroren und nur kleine Adapter-Matrizen (ca. 15 Millionen Parameter, weniger als 1% des Modells) trainiert. Das reduziert den VRAM-Bedarf auf unter 8 GB bei vergleichbarer Qualität. Die resultierenden Checkpoints sind entsprechend klein, ca. 60 MB statt 6 GB.
Installation
pip install transformers datasets peft bitsandbytes accelerate \
evaluate jiwer librosa --break-system-packages
Modell und Processor laden
from transformers import WhisperForConditionalGeneration, WhisperProcessor
model_id = "openai/whisper-large-v3"
processor = WhisperProcessor.from_pretrained(model_id)
model = WhisperForConditionalGeneration.from_pretrained(
model_id,
load_in_8bit=True,
device_map="auto",
)
model.config.forced_decoder_ids = None
model.config.suppress_tokens = []
LoRA-Konfiguration
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
model = prepare_model_for_kbit_training(model)
lora_config = LoraConfig(
r=32,
lora_alpha=64,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.05,
bias="none",
)
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# Erwartete Ausgabe: trainable params: ~15M (< 1% des Gesamtmodells)
Daten vorverarbeiten
def prepare_dataset(batch):
audio = batch["audio"]
batch["input_features"] = processor.feature_extractor(
audio["array"],
sampling_rate=audio["sampling_rate"]
).input_features[0]
batch["labels"] = processor.tokenizer(batch["sentence"]).input_ids
return batch
dataset = dataset.map(prepare_dataset, remove_columns=["audio", "sentence"])
Training starten
from transformers import Seq2SeqTrainingArguments, Seq2SeqTrainer
training_args = Seq2SeqTrainingArguments(
output_dir="./whisper-finetuned",
per_device_train_batch_size=8,
gradient_accumulation_steps=2,
learning_rate=1e-3,
warmup_steps=50,
max_steps=500, # Bei 50 Songs ca. 500 Steps
fp16=True,
evaluation_strategy="steps",
eval_steps=100,
save_strategy="steps",
save_steps=100,
logging_steps=25,
generation_max_length=225,
predict_with_generate=True,
gradient_checkpointing=True,
remove_unused_columns=False,
)
trainer = Seq2SeqTrainer(
args=training_args,
model=model,
train_dataset=dataset["train"],
eval_dataset=dataset["test"],
tokenizer=processor.feature_extractor,
)
trainer.train()
Das Training dauert auf einer GPU mit 8 GB VRAM (z.B. RTX 3070, RTX 4060) ca. 2 bis 4 Stunden bei 50 Songs.
Modell speichern und verwenden
# LoRA-Adapter speichern (ca. 60 MB):
model.save_pretrained("./whisper-finetuned/best_model")
processor.save_pretrained("./whisper-finetuned/best_model")
Das feinabgestimmte Modell lässt sich anschließend in der bestehenden Pipeline nutzen:
from transformers import AutoModelForSpeechSeq2Seq, AutoProcessor, pipeline
from peft import PeftModel
base_model = AutoModelForSpeechSeq2Seq.from_pretrained("openai/whisper-large-v3")
model = PeftModel.from_pretrained(base_model, "./whisper-finetuned/best_model")
processor = AutoProcessor.from_pretrained("./whisper-finetuned/best_model")
pipe = pipeline(
"automatic-speech-recognition",
model=model,
tokenizer=processor.tokenizer,
feature_extractor=processor.feature_extractor,
device="cuda",
)
result = pipe("gesang.mp3", return_timestamps="word")
13. Konvertierung für Faster Whisper (CTranslate2)
Die bestehende Pipeline nutzt Faster Whisper, das CTranslate2-Modelle erwartet. Das feinabgestimmte HuggingFace-Modell muss dafür konvertiert werden.
pip install ctranslate2 --break-system-packages
# Zuerst LoRA-Adapter in das Basismodell mergen:
python3 -c "
from transformers import WhisperForConditionalGeneration
from peft import PeftModel
base = WhisperForConditionalGeneration.from_pretrained('openai/whisper-large-v3')
model = PeftModel.from_pretrained(base, './whisper-finetuned/best_model')
merged = model.merge_and_unload()
merged.save_pretrained('./whisper-finetuned/merged')
"
# Dann nach CTranslate2 konvertieren:
ct2-whisper-converter \
--model ./whisper-finetuned/merged \
--output_dir ./whisper-finetuned/ct2 \
--quantization int8_float16
Das konvertierte Modell kann direkt in 01_transcribe_local.py geladen werden, indem statt "large-v3" der lokale Pfad angegeben wird:
model = WhisperModel("./whisper-finetuned/ct2", device="cuda", compute_type="int8_float16")
Teil 4: Offline-Setup und Zusammenfassung
14. Offline-Setup: Betrieb ohne Internet
Die gesamte Pipeline ist so konzipiert, dass sie nach einmaliger Einrichtung komplett ohne Internetverbindung funktioniert. Das ist besonders relevant für Veranstaltungen an Orten ohne WLAN, für den Schutz urheberrechtlich sensibler Audiodaten und für den souveränen Betrieb ohne Abhängigkeit von Cloud-Diensten.
KI-Modelle vorab herunterladen
Beide KI-Modelle werden beim ersten Aufruf automatisch heruntergeladen und lokal gecacht. Für den Offline-Betrieb genügt es, die Modelle einmalig auf einem Rechner mit Internet herunterzuladen und den Cache-Ordner auf den Zielrechner zu kopieren.
Faster Whisper (Spracherkennung) cacht das Modell unter:
~/.cache/huggingface/hub/models--Systran--faster-whisper-large-v3/
Das Modell kann explizit vorab geladen werden mit:
from faster_whisper import WhisperModel
model = WhisperModel("large-v3")
Danach liegt das Modell (~3 GB) im Cache und wird bei jedem weiteren Aufruf lokal geladen.
Demucs (Stem Separation) cacht das Modell unter:
~/.cache/torch/hub/checkpoints/
Beim ersten Aufruf von Demucs werden die Modell-Checkpoints (.ht-Dateien) automatisch heruntergeladen. Für den Offline-Transfer reicht es, den gesamten checkpoints/-Ordner zu kopieren.
Python-Pakete vorab installieren
Alle Python-Abhängigkeiten lassen sich vorab als Offline-Paket sichern:
# Auf dem Rechner MIT Internet:
mkdir ~/karaoke-offline-packages
pip download demucs faster-whisper Pillow stable-ts \
-d ~/karaoke-offline-packages
# Auf dem Rechner OHNE Internet:
pip install --no-index \
--find-links ~/karaoke-offline-packages \
demucs faster-whisper Pillow stable-ts \
--break-system-packages
Systemabhängigkeiten
Die einzigen Systemabhängigkeiten neben Python sind ffmpeg (für Audiokonvertierung) und mpv (für den manuellen Alignment-Modus). Beide lassen sich über den Paketmanager der Distribution installieren und sind danach ohne Internet verfügbar:
sudo apt install ffmpeg mpv
Offline-Checkliste
Nach der einmaligen Einrichtung sollten folgende Verzeichnisse auf dem Zielrechner vorhanden sein:
| Pfad | Inhalt | Größe |
|---|---|---|
~/.cache/huggingface/hub/models--Systran--faster-whisper-large-v3/ |
Whisper-Modell | ~3 GB |
~/.cache/torch/hub/checkpoints/ |
Demucs-Modell | ~300 MB |
| Python-Umgebung mit installierten Paketen | demucs, faster-whisper, Pillow, stable-ts | ~2 GB |
/usr/bin/ffmpeg, /usr/bin/mpv |
Systemtools | vorhanden |
Sind diese Voraussetzungen erfüllt, arbeitet die gesamte Pipeline ohne jegliche Netzwerkverbindung.
Zusammenfassung
Die gesamte Pipeline läuft unter Linux, nutzt ausschließlich Open-Source-Software und lokal ausgeführte KI-Modelle. Als Hardware wird lediglich ein Rechner mit NVIDIA-GPU (ab 8 GB VRAM) benötigt. Vom Original-Song bis zur abspielfertigen Karaoke-Datei vergehen je nach Nachbearbeitungsaufwand 15 bis 30 Minuten pro Titel.
Es werden keine Cloud-Dienste, keine API-Keys, keine Abonnements und keine Kreditkarte benötigt. Die Audiodaten verlassen zu keinem Zeitpunkt den lokalen Rechner.
| Schritt | Werkzeug | Funktion |
|---|---|---|
| Stem Separation | Demucs (htdemucs_ft) | Gesang und Instrumental trennen |
| Texterkennung | Faster Whisper / stable-ts | Wort-genaue Zeitstempel |
| Alignment | SequenceMatcher / TUI | Text und Timing zusammenführen |
| Zwischenformat | Enhanced LRC | Wort-Level-Timing, editierbar |
| Konvertierung | Custom Python | LRC zu CDG mit Block-Darstellung |
| Audio-Routing | FFmpeg Multiplex | L=Instrumental, R=Original |
| Wiedergabe | OpenKJ | Karaoke-Hosting mit Song-Datenbank |
| Fine-Tuning | LoRA + PEFT | Eigenes Whisper-Modell für spezielle Genres |
Das Ergebnis ist ein reproduzierbarer, wartbarer Workflow, der sich mit jedem verarbeiteten Song selbst verbessert. Die manuellen Korrekturen fließen als Trainingsdaten zurück in das Modell. Nach einigen Dutzend Songs eines Genres kann das feinabgestimmte Modell auch gutturales Growling, Screaming und andere extreme Gesangsstile zuverlässig transkribieren.
Dieses Projekt wurde als Individual-Lösung im Kundenauftrag entwickelt. Bei Interesse an einer ähnlichen Lösung oder Anpassung auf Ihre Anforderungen stehe ich gerne zur Verfügung.
Letzte Aktualisierung: April 2026 · Feedback und Korrekturen willkommen!