From 5bf1fafddf40a965425a7c4d23e027d4a26d4c7f Mon Sep 17 00:00:00 2001 From: Patrick Gniza Date: Mon, 18 May 2026 15:54:43 +0200 Subject: [PATCH] =?UTF-8?q?Initiale=20Ver=C3=B6ffentlichung=20von=20Grabbe?= =?UTF-8?q?r-Config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Tkinter-GUI zur Konfiguration analoger DirectShow-Video-Grabber - Unterstützung für PAL/NTSC/SECAM-Umschaltung - Unterstützung für Composite- und S-Video-Eingänge über IAMCrossbar - Automatische Speicherung und Anwendung der Konfiguration - Headless-Startmodus mit automatischer Konfigurationsanwendung - Speicherung der Konfiguration unter ProgramData - Nuitka-kompatible Projektstruktur - Inno-Setup-Installer mit optionalem Autostart - README, MIT-Lizenz und requirements.txt hinzugefügt - Projekt-Icon erstellt --- .gitignore | 21 ++++++++ .vscode/tasks.json | 17 ++++++ LICENSE | 21 ++++++++ README.md | 130 +++++++++++++++++++++++++++++++++++++++++++++ Requirements.txt | 1 + setup.iss | 124 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 314 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 Requirements.txt create mode 100644 setup.iss diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4a59c1d --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +__pycache__/ +*.pyc +*.pyo +*.pyd +*.spec + +build/ +dist/ +*.build/ +*.dist/ + +.venv/ +venv/ + +config.json + +*.exe +*.msi + +.idea/ +.vscode/ \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index bf378a9..b618cbd 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -11,6 +11,7 @@ "--enable-plugin=multiprocessing", "--enable-plugin=anti-bloat", "--enable-plugin=tk-inter", + "--windows-console-mode=disable", "--lto=no", "--msvc=latest", "--output-dir=build", @@ -25,6 +26,22 @@ ], "group": "build", "problemMatcher": [] + }, + { + "label": "Build Grabber Config Setup (Inno Setup)", + "type": "process", + "command": "c:\\Program Files (x86)\\Inno Setup 6\\ISCC.exe", + "args": [ + "setup.iss" + ], + "presentation": { + "reveal": "always", + "echo": false + }, + "group": { + "kind": "build", + "isDefault": true + } } ] } \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..69c6f72 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Patrick Gniza + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..201d2e2 --- /dev/null +++ b/README.md @@ -0,0 +1,130 @@ +# Grabber-Config + +Windows-Tool zur automatischen Konfiguration analoger USB-Video-Grabber über DirectShow. + +Die Anwendung kann automatisch: + +- DirectShow-Videoaufnahmegeräte erkennen +- Den Videostandard setzen (PAL / NTSC / SECAM) +- Den Videoeingang umschalten (Composite / S-Video) +- Die Konfiguration dauerhaft speichern +- Die gespeicherte Konfiguration beim Start automatisch anwenden + +Das Projekt richtet sich insbesondere an analoge USB-Grabber, die ihre Einstellungen nach einem Neustart oder erneutem Verbinden verlieren. + +--- + +## Funktionen + +- Schlanke Tkinter-GUI +- Direkte DirectShow-Ansteuerung (kein FFmpeg notwendig) +- Automatische Geräteerkennung +- Automatische Crossbar-Erkennung +- Speicherung der Konfiguration unter: + +```text +C:\ProgramData\GrabberConfig\config.json +``` + +- Headless-Startmodus +- Geeignet für Nuitka-Standalone-Builds + +--- + +## Unterstützte Hardware + +Getestet mit: + +- Hauppauge Cx23100 Video Capture + +Sollte auch mit vielen anderen DirectShow-kompatiblen Grabbern funktionieren: + +- EasyCAP +- UTV007 +- STK1160 +- weitere analoge USB-Capture-Geräte + +--- + +## Verwendung + +### Erste Einrichtung / Konfiguration + +```powershell +python video_grabber_gui.py /config +``` + +Danach auswählen: + +- Videogerät +- Videostandard +- Videoeingang + +Anschließend die Konfiguration speichern. + +--- + +### Automatischer Startmodus + +```powershell +python video_grabber_gui.py +``` + +Wenn bereits eine Konfiguration vorhanden ist, wird automatisch: + +- der konfigurierte Grabber geöffnet +- der gespeicherte Videostandard gesetzt +- der konfigurierte Eingang umgeschaltet +- das Programm anschließend beendet + +Falls keine Konfiguration vorhanden ist, öffnet sich automatisch die GUI. + +--- + +## EXE mit Nuitka erstellen + +Beispiel: + +```powershell +python -m nuitka ^ + --windows-console-mode=disable ^ + --enable-plugin=tk-inter ^ + --windows-icon-from-ico=icon.ico ^ + video_grabber_gui.py +``` + +--- + +## Abhängigkeiten + +```powershell +pip install comtypes +``` + +Tkinter ist bei normalen Python-Installationen unter Windows bereits enthalten. + +--- + +## Technische Details + +Die Anwendung kommuniziert direkt mit den DirectShow-COM-Interfaces: + +- `IAMAnalogVideoDecoder` +- `IAMCrossbar` + +Dadurch können analoge Videoeinstellungen direkt gesetzt werden, ohne zusätzliche Herstellersoftware. + +--- + +## Hinweise + +Einige Grabber stellen ihre Crossbar als separates DirectShow-Gerät bereit. +Die Anwendung versucht dies automatisch zu erkennen und korrekt zu verwenden. + +Nicht alle Treiber unterstützen sämtliche DirectShow-Interfaces vollständig. + +--- + +## Lizenz + +MIT License diff --git a/Requirements.txt b/Requirements.txt new file mode 100644 index 0000000..fa08ead --- /dev/null +++ b/Requirements.txt @@ -0,0 +1 @@ +comtypes diff --git a/setup.iss b/setup.iss new file mode 100644 index 0000000..eb6a019 --- /dev/null +++ b/setup.iss @@ -0,0 +1,124 @@ +#define MyAppName "Grabber Config" +#define MyAppVersion "1.0.0" +#define MyAppPublisher "Patrick Gniza" +#define MyAppExeName "GrabberConfig.exe" + +[Setup] +AppId={{8B2E6B6B-5E0B-4C7F-BF71-GRABBER-CONFIG}} +AppName={#MyAppName} +AppVersion={#MyAppVersion} +AppVerName={#MyAppName} {#MyAppVersion} +AppPublisher={#MyAppPublisher} +DefaultDirName={autopf}\Grabber Config +DefaultGroupName= +DisableProgramGroupPage=yes +DisableDirPage=no +DisableReadyPage=no +DisableFinishedPage=no +DisableWelcomePage=no +ShowLanguageDialog=no +OutputBaseFilename=GrabberConfigSetup +OutputDir=build +Compression=lzma +SolidCompression=yes +ArchitecturesInstallIn64BitMode=x64compatible +PrivilegesRequired=admin + +LicenseFile=LICENSE +SetupIconFile=GrabberConfig.ico +UninstallDisplayIcon={app}\{#MyAppExeName} + +[Languages] +Name: "german"; MessagesFile: "compiler:Languages\German.isl" + +[Tasks] +Name: "autostart"; \ + Description: "Grabber Config zum Autostart hinzufügen"; \ + GroupDescription: "Zusätzliche Aufgaben:"; \ + Flags: unchecked + +[Files] +Source: "build\GrabberConfig.dist\*"; DestDir: "{app}"; Flags: recursesubdirs createallsubdirs + +[Icons] +Name: "{commonstartup}\Grabber Config"; \ + Filename: "{app}\{#MyAppExeName}"; \ + Tasks: autostart + +[Run] +Filename: "{app}\{#MyAppExeName}"; \ + Parameters: "/config"; \ + Description: "Grabber Config Konfiguration starten"; \ + Flags: nowait postinstall skipifsilent + +[UninstallRun] +Filename: "taskkill"; \ + Parameters: "/F /IM {#MyAppExeName}"; \ + Flags: runhidden waituntilterminated + +[UninstallDelete] +Type: filesandordirs; Name: "{app}" + +[Code] + +procedure InitializeWizard; +begin + if FileExists(WizardDirValue + '\{#MyAppExeName}') then + begin + WizardForm.NextButton.Caption := '&Update'; + + WizardForm.WelcomeLabel1.Caption := + 'Update von Grabber Config'; + + WizardForm.WelcomeLabel2.Caption := + 'Die bestehende Installation wird aktualisiert.'; + end; +end; + +procedure CleanApplicationDirectory(); +var + FindRec: TFindRec; + Path: String; +begin + Path := ExpandConstant('{app}'); + + if FindFirst(Path + '\*', FindRec) then + begin + try + repeat + if (FindRec.Name <> '.') and (FindRec.Name <> '..') then + begin + if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0 then + begin + DelTree(Path + '\' + FindRec.Name, True, True, True); + end + else + begin + DeleteFile(Path + '\' + FindRec.Name); + end; + end; + until not FindNext(FindRec); + finally + FindClose(FindRec); + end; + end; +end; + +procedure CurStepChanged(CurStep: TSetupStep); +var + ResultCode: Integer; +begin + if CurStep = ssInstall then + begin + Exec( + 'taskkill', + '/F /IM {#MyAppExeName}', + '', + SW_HIDE, + ewWaitUntilTerminated, + ResultCode + ); + + CleanApplicationDirectory(); + end; +end;