- C++ 84%
- Shell 13.2%
- CMake 1.6%
- PowerShell 1.2%
Rekursive Ordnersuche und das Nachbauen der Quellstruktur im Zielordner. Erste Fassung, die sich von einer bereits veroeffentlichten Vorgaengerin (0.1.2) ueber den regulaeren Weg selbst aktualisieren laesst - bisher ging das nur mit einem Testbau, dessen Version kuenstlich heruntergesetzt war. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| .vscode | ||
| packaging | ||
| scripts | ||
| src | ||
| .gitignore | ||
| check.sh | ||
| CMakeLists.txt | ||
| PLAN_AUTOUPDATE.md | ||
| README.md | ||
ngenMediaConvert
Medienkonverter mit grafischer Oberfläche und Kommandozeile: Dateien per
Drag & Drop aus dem Dateimanager ablegen, Zielformat und Zielordner wählen,
konvertieren – oder dasselbe im Skript mit --cli.
Die eigentliche Umwandlung erledigt FFmpeg, die Oberfläche ist Qt 6 (C++).
Funktionen
- Drag & Drop aus Windows Explorer, Nautilus, Dolphin, Thunar & Co. – Dateien und Ordner (Ordner werden eine Ebene tief nach Mediendateien durchsucht)
- Zielformat frei wählbar: MP4/H.264, MKV/H.265, WebM/VP9, MKV ohne Neukodierung, GIF, MP3, M4A, Opus, FLAC, WAV, PNG, JPEG, WebP
- Zielordner frei wählbar – alternativ „neben der Quelldatei speichern“
- Ordner rekursiv durchsuchen – wahlweise nur eine Ebene tief oder der ganze Baum, auch für abgelegte Ordner
- Unterordner der Quelle übernehmen: wahlweise werden die letzten N
Ordnerebenen oberhalb der Quelldatei im Zielordner nachgebaut, sodass
…/album/2024/lied.wavals<ziel>/album/2024/lied.mp3landet - Warteschlange mit Fortschrittsbalken pro Datei und Gesamtfortschritt
- Abbrechen jederzeit; halbfertige Ausgabedateien werden entfernt
- Quelldateien werden nie überschrieben; bei Namenskollision wird
wahlweise überschrieben oder ein freier Name
Name (1).extgewählt - Kommandozeilenbetrieb mit
--cli– ohne Oberfläche, ohne Anzeigeserver, mit Fortschrittsanzeige und sinnvollen Exit-Codes - Windows „Senden an" und Linux-„Öffnen mit": übergebene Dateien landen in der Warteschlange, Folgeaufrufe in einem Fenster statt in vielen
- FFmpeg nachladen, wenn keines im System ist – auf Knopfdruck oder mit
--install-ffmpeg, ohne Administratorrechte - Selbst-Aktualisierung für AppImage und Windows: Prüfsumme zwingend, still
im Hintergrund, abschaltbar – ein
.debbleibt Sache vonapt - Protokoll mit der vollständigen FFmpeg-Ausgabe für die Fehlersuche
- Einstellungen (Format, Zielordner, Fenstergröße) bleiben erhalten
- Startparameter werden übernommen → funktioniert als „Öffnen mit“-Ziel
Voraussetzungen
| Qt | 6.5 oder neuer (Modul Widgets) |
| Compiler | C++17 (getestet mit GCC 15) |
| Build | CMake 3.19+ |
| Laufzeit | ffmpeg und ffprobe – im PATH, neben der Anwendung oder nachgeladen |
ffprobe wird nur für die Laufzeitermittlung gebraucht. Fehlt es, läuft die
Konvertierung trotzdem – der Fortschrittsbalken zeigt dann „unbestimmt“ an.
Abhängigkeiten installieren
# Debian / Ubuntu
sudo apt install build-essential cmake qt6-base-dev ffmpeg
Bauen
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)
./build/ngenMediaConvert
Bedienung
Voreingestellt sind MP3 192 kbit/s und der Musik-Ordner als Ziel; beides merkt sich das Programm, sobald man es ändert.
- Dateien oder Ordner auf das Fenster ziehen (oder Hinzufügen …)
- Zielformat auswählen
- Zielordner wählen – oder Neben der Quelldatei speichern ankreuzen
- Konvertieren
Die Spalte Ziel zeigt vorab den Dateinamen, der entstehen wird. Bereits erfolgreich konvertierte Zeilen werden bei einem erneuten Lauf übersprungen, sodass man nach einem Abbruch einfach weitermachen kann.
Kommandozeile
ngenMediaConvert --list-formats # verfügbare Ziel-IDs
ngenMediaConvert --cli -f mp3_320 konzert.mkv # neben der Quelldatei
ngenMediaConvert --cli -f mp4_h264 -o ~/Videos *.mov # in einen Zielordner
ngenMediaConvert --cli -f flac -y -v Aufnahmen/ # überschreiben, mit FFmpeg-Log
ngenMediaConvert --cli -f mp3_192 -o ~/Musik -r --keep-dirs 2 Alben/ # Baum mit Struktur
ngenMediaConvert --check-update # Exit 0 = es gibt etwas
| Option | Wirkung |
|---|---|
-c, --cli |
ohne Oberfläche konvertieren |
-f, --format <id> |
Zielformat; die IDs zeigt --list-formats |
-o, --output-dir <ordner> |
Zielordner (wird bei Bedarf angelegt); ohne Angabe: neben der Quelldatei |
-y, --overwrite |
vorhandene Zieldateien überschreiben |
-r, --recursive |
übergebene Ordner mit allen Unterordnern durchsuchen |
--keep-dirs <n> |
n Ordnerebenen oberhalb der Quelldatei im Zielordner nachbauen (0 = aus); nur zusammen mit -o |
-v, --verbose |
FFmpeg-Ausgabe nach stderr durchreichen |
--install-ffmpeg |
FFmpeg herunterladen und ins Anwendungsdatenverzeichnis legen |
--check-update |
nach einer neueren Fassung sehen; Exit 0 heißt „es gibt eine" |
--self-update |
neuere Fassung holen, Prüfsumme prüfen und einspielen |
Ordner als Argument werden eine Ebene tief nach Mediendateien aufgelöst, mit
-r durch den ganzen Baum; symbolischen Verknüpfungen wird dabei nicht
gefolgt. -r zusammen mit --keep-dirs nimmt eine verschachtelte Sammlung
samt Struktur mit.
Strg+C bricht sauber ab: FFmpeg wird beendet und die halbfertige
Ausgabedatei entfernt.
Exit-Codes: 0 alles konvertiert · 1 mindestens eine Datei
fehlgeschlagen · 2 Aufruffehler (Format/Eingabe/Zielordner) ·
3 FFmpeg nicht gefunden · 130 abgebrochen.
Aus dem Dateimanager heraus
Übergebene Dateien landen direkt in der Warteschlange. Ruft die Shell das
Programm dabei mehrfach auf – Windows „Senden an" zerlegt große Auswahlen,
weil die Befehlszeile begrenzt ist –, reichen die Folgeaufrufe ihre Dateien an
das bereits offene Fenster weiter. --new-instance erzwingt ein eigenes.
Windows:
powershell -ExecutionPolicy Bypass -File packaging\SendTo-einrichten.ps1
Legt eine Verknüpfung in shell:sendto an; danach steht ngenMediaConvert im
Kontextmenü unter Senden an. -Entfernen nimmt sie wieder heraus.
Linux: packaging/ngenMediaConvert.desktop nach
~/.local/share/applications/ kopieren – der Eintrag erscheint dann unter
Öffnen mit. In Thunar lässt sich zusätzlich unter Bearbeiten →
Benutzerdefinierte Aktionen ein Eintrag mit dem Befehl
ngenMediaConvert %F anlegen.
Aufbau
| Datei | Aufgabe |
|---|---|
src/main.cpp |
Anwendungsstart, Weiche zwischen Oberfläche und Kommandozeile |
src/Cli.* |
Kommandozeilenbetrieb: Optionen, Fortschritt, Exit-Codes |
src/MainWindow.* |
Oberfläche, Warteschlangen-Tabelle, Einstellungen |
src/DropArea.* |
Ablagefläche für Drag & Drop |
src/SingleInstance.* |
Folgeaufrufe ans laufende Fenster weiterreichen |
src/PathUtils.* |
Pfadauflösung und Zielnamen – gemeinsam für GUI und CLI |
src/Converter.* |
FFmpeg-Aufruf, Fortschrittsauswertung, Warteschlange |
src/FfmpegInstaller.* |
FFmpeg nachladen, entpacken, ablegen |
src/Presets.* |
Zielformate und ihre FFmpeg-Argumente |
FFmpeg läuft als asynchroner QProcess; der Fortschritt kommt über
-progress pipe:1 und wird gegen die von ffprobe ermittelte Laufzeit
gerechnet. Dadurch kommt die Anwendung ohne eigene Threads aus.
Die Entscheidung GUI oder Kommandozeile fällt vor dem Anlegen der
Anwendung: mit --cli entsteht nur eine QCoreApplication, sonst scheiterte
der Start auf einem Rechner ohne X11/Wayland. Beide Wege teilen sich
PathUtils und Converter, damit Zielnamen und Umwandlung nicht
auseinanderlaufen.
Ein Format ergänzen
Ein Eintrag in buildPresets() in src/Presets.cpp genügt –
Anzeigename, Dateiendung und die FFmpeg-Argumente, die zwischen Eingabe und
Ausgabedatei stehen. Kein Shell-Quoting nötig, jedes Argument ist ein
eigener Listeneintrag.
Pakete bauen
Alle Skripte laufen im selben Container wie die CI – „ein Skript, zwei
Aufrufer". Nötig sind nur podman oder docker.
| Befehl | Ergebnis |
|---|---|
scripts/build-deb-local.sh |
.deb (Abhängigkeiten via dpkg-shlibdeps) |
scripts/build-appimage-local.sh |
dist/…AppImage (~35 MB, Qt gebündelt) |
scripts/build-windows-local.sh |
…-windows-x86_64.zip (~31 MB) |
WITH_FFMPEG=1 packt FFmpeg mit ein – beim AppImage ein statischer Build,
beim Windows-ZIP ffmpeg.exe/ffprobe.exe.
Der Windows-Build ist ein MinGW-Cross-Build im fedora:43-Container:
Fedora liefert Qt 6 fertig für MinGW (mingw64-qt6-qtbase), eine
Windows-Maschine ist nicht nötig. Statt windeployqt – das selbst eine .exe
ist – löst das Skript die Importtabelle rekursiv gegen den Sysroot auf.
Entwicklung
./check.sh # baut und prüft dieselben Tore wie die CI
In VS Code ist .vscode/ eingerichtet: Ctrl+Shift+B baut nach build/,
F5 debuggt aus build-debug/ unter CodeLLDB, und die Paket-Tasks rufen die
Skripte oben auf. IntelliSense zieht die Qt-Header aus compile_commands.json.
Die CI (.forgejo/workflows/) baut bei jedem Push auf
main und konvertiert dabei wirklich – ein Test, der nur übersetzt, würde
falsche FFmpeg-Argumente nicht bemerken. Ein Tag vX.Y.Z stößt Release,
Debian-Registry und Windows-ZIP an.
Die geplante Selbst-Aktualisierung steht in PLAN_AUTOUPDATE.md.
Verteilen
- Linux: AppImage via
linuxdeploymit dem Qt-Plugin, oder schlicht paketieren undffmpegals Abhängigkeit deklarieren.packaging/ngenMediaConvert.desktopnach~/.local/share/applications/kopieren, damit der Eintrag im Menü und unter „Öffnen mit“ erscheint. - Windows:
scripts/build-windows-local.shliefert ein fertiges ZIP samt aller DLLs und dem Plattform-Plugin.ffmpeg.exe/ffprobe.exedaneben legen (oder im Programm nachladen lassen).
Lizenzhinweis
Die Anwendung ruft FFmpeg lediglich als externes Programm auf und enthält
keinen FFmpeg-Code. Wer FFmpeg mit ausliefert, muss dessen Lizenz beachten:
Standard-Builds sind LGPL, Builds mit --enable-gpl (z. B. mit x264/x265)
stehen unter der GPL.