Webserver hinzugefügt, Javascript angepasst abruf der IP Dynamisch
This commit is contained in:
parent
3c18dd7e18
commit
d5f6178188
7 changed files with 165 additions and 24 deletions
109
README.md
109
README.md
|
|
@ -1,2 +1,109 @@
|
|||
# python.video_converter_v3
|
||||
|
||||
# Video-Konvertierungsprogramm
|
||||
|
||||
Dies ist ein einfaches Video-Konvertierungsprogramm, das eine Weboberfläche zur Verfügung stellt, um Videos in verschiedene Formate zu konvertieren. Das Backend läuft auf Python und verwendet WebSockets, um mit der Benutzeroberfläche zu kommunizieren und den Status von Konvertierungen zu verfolgen.
|
||||
|
||||
## Features
|
||||
|
||||
- **Weboberfläche** zur Anzeige aktueller Konvertierungen, Warteschlangen und Status.
|
||||
- **Echtzeit-Kommunikation** via WebSocket zwischen Frontend und Backend.
|
||||
- **Automatische Konvertierung** bei Dateipfadänderungen (optional, basierend auf den Einstellungen).
|
||||
- **Statistiken** zu konvertierten Videos.
|
||||
- Unterstützung für verschiedene Videoformate und Codecs.
|
||||
|
||||
## Anforderungen
|
||||
|
||||
- Python 3.8+
|
||||
- Abhängigkeiten:
|
||||
- `aiohttp` – Für den HTTP-Server
|
||||
- `websockets` – Für die WebSocket-Kommunikation
|
||||
- Weitere Abhängigkeiten wie z. B. `ffmpeg` für die Video-Konvertierung
|
||||
|
||||
### Installationsanweisungen
|
||||
|
||||
1. **Klonen des Repositories:**
|
||||
|
||||
```bash
|
||||
git clone https://github.com/dein-benutzername/video-konverter.git
|
||||
cd video-konverter
|
||||
```
|
||||
|
||||
2. **Installiere die Abhängigkeiten:**
|
||||
|
||||
Wenn du noch keine virtuelle Umgebung eingerichtet hast, erstelle eine:
|
||||
|
||||
```bash
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate # Auf Windows: venv\Scriptsctivate
|
||||
```
|
||||
|
||||
Dann installiere alle benötigten Abhängigkeiten:
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
3. **Installiere ffmpeg:**
|
||||
|
||||
Für die Video-Konvertierung benötigst du `ffmpeg`. Installiere es je nach deinem Betriebssystem:
|
||||
|
||||
- **Ubuntu/Debian:**
|
||||
```bash
|
||||
sudo apt-get install ffmpeg
|
||||
```
|
||||
- **macOS (via Homebrew):**
|
||||
```bash
|
||||
brew install ffmpeg
|
||||
```
|
||||
- **Windows:**
|
||||
Lade `ffmpeg` von [ffmpeg.org](https://ffmpeg.org/download.html) herunter und stelle sicher, dass es im Systempfad verfügbar ist.
|
||||
|
||||
## Nutzung
|
||||
|
||||
1. **Starte den Server:**
|
||||
|
||||
Der WebSocket-Server und der HTTP-Server laufen auf demselben Event-Loop. Um beide zu starten, führe einfach das Python-Skript aus:
|
||||
|
||||
```bash
|
||||
python server.py
|
||||
```
|
||||
|
||||
Der HTTP-Server ist auf `http://localhost:8080` erreichbar, und die WebSocket-Verbindung läuft unter `ws://localhost:8000`.
|
||||
|
||||
2. **Weboberfläche aufrufen:**
|
||||
|
||||
Öffne deinen Webbrowser und gehe zu `http://localhost:8080`, um die Benutzeroberfläche des Video-Konverters zu sehen. Du kannst Videos hochladen und deren Konvertierungsstatus in Echtzeit verfolgen.
|
||||
|
||||
## Funktionen der Weboberfläche
|
||||
|
||||
- **Aktuelle Konvertierungen**: Zeigt alle laufenden und abgeschlossenen Konvertierungen an.
|
||||
- **Warteschlange**: Zeigt an, welche Videos noch konvertiert werden müssen.
|
||||
- **Start/Pause/Stop**: Ermöglicht es, die Konvertierung zu steuern (je nach Implementierung).
|
||||
- **Statistiken**: Zeigt Informationen zu den konvertierten Videos (z. B. Dateigröße, Format, etc.).
|
||||
|
||||
## Backend
|
||||
|
||||
Das Backend ist für die Verwaltung der Video-Konvertierungen zuständig und kommuniziert über WebSockets mit der Frontend-Weboberfläche.
|
||||
|
||||
### WebSocket-Server
|
||||
|
||||
Der WebSocket-Server wartet auf Verbindungen und sendet Updates zu den Konvertierungen an die Clients. Die Kommunikation erfolgt mit JSON-Nachrichten. Der Server unterstützt folgende Nachrichtenarten:
|
||||
|
||||
- **Datenpfad** (`data_path`): Gibt den Pfad der zu konvertierenden Datei an.
|
||||
- **Befehle** (`data_command`): Für zukünftige Erweiterungen von Steuerbefehlen.
|
||||
|
||||
## Konfiguration
|
||||
|
||||
Die Konfiguration des Programms erfolgt über eine YAML-Datei (z. B. `config.yaml`), die Parameter wie den Serverport, den Pfad zu den Konvertierungswerkzeugen (z. B. `ffmpeg`) und automatische Startoptionen für die Konvertierungen enthält.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **Problem:** Der WebSocket-Server startet nicht.
|
||||
- **Lösung:** Überprüfe, ob der Port (Standard: `8000`) bereits von einer anderen Anwendung verwendet wird.
|
||||
|
||||
- **Problem:** Videos werden nicht konvertiert.
|
||||
- **Lösung:** Stelle sicher, dass `ffmpeg` korrekt installiert und im Systempfad verfügbar ist.
|
||||
|
||||
## Lizenz
|
||||
|
||||
Dieses Projekt ist unter der MIT-Lizenz lizenziert – siehe [LICENSE](LICENSE) für Details.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ if __name__ == "__main__":
|
|||
obj_server = Server()
|
||||
|
||||
try:
|
||||
asyncio.run(obj_server.start())
|
||||
asyncio.run(obj_server.start_server())
|
||||
except asyncio.exceptions.CancelledError:
|
||||
pass
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ log_file: "server.log"
|
|||
log_level: DEBUG
|
||||
log_rotation: time
|
||||
path_file: "media_path.yaml"
|
||||
server_ip: "0.0.0.0"
|
||||
server_ip: "127.0.0.1"
|
||||
server_port: 8000
|
||||
task_max: 1
|
||||
autostart: true
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ class Convert:
|
|||
self.active_tasks = set()
|
||||
self.active_process = set()
|
||||
|
||||
logging.info("Video Convert Start here")
|
||||
|
||||
async def snake_waiting(self):
|
||||
while True:
|
||||
if len(self.active_tasks) < self.yaml["task_max"] and self.obj_path.count_paths(None) > 0:
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ class Settings:
|
|||
yaml.dump(self.yaml, file, default_flow_style=False, indent=4)
|
||||
|
||||
def set_logging(self):
|
||||
print(self.yaml)
|
||||
|
||||
log_level = self.yaml.get("log_level", "INFO")
|
||||
log_file = self.yaml.get("log_file", "app.log")
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
import asyncio
|
||||
|
||||
import websockets
|
||||
import json
|
||||
import logging
|
||||
|
||||
from websockets import InvalidUpgrade, ConnectionClosed, ConnectionClosedError
|
||||
from aiohttp import web
|
||||
|
||||
from app.class_settings import Settings
|
||||
from app.class_file_path import Path
|
||||
|
|
@ -12,8 +15,8 @@ var_convert_active = False
|
|||
|
||||
class Server:
|
||||
def __init__(self):
|
||||
self.websocket_send = 0
|
||||
self.websocket = None
|
||||
self.clients = set()
|
||||
obj_settings = Settings()
|
||||
obj_settings.set_logging()
|
||||
|
||||
|
|
@ -22,25 +25,21 @@ class Server:
|
|||
self.obj_convert = Convert(self, self.yaml, self.obj_path)
|
||||
|
||||
async def send_websocket(self, message):
|
||||
try:
|
||||
await self.websocket.send(json.dumps(message))
|
||||
except websockets.exceptions.ConnectionClosed:
|
||||
if self.websocket_send == 0:
|
||||
logging.warning("No websocket client connected!")
|
||||
self.websocket_send += 1
|
||||
message_json = json.dumps(message)
|
||||
|
||||
if self.websocket_send == 100:
|
||||
self.websocket_send = 0
|
||||
for client in self.clients.copy():
|
||||
try:
|
||||
await client.send(message_json)
|
||||
except websockets.exceptions.ConnectionClosed:
|
||||
self.clients.remove(client)
|
||||
|
||||
async def handle_client(self, websocket):
|
||||
self.websocket = websocket
|
||||
self.clients.add(websocket)
|
||||
global var_convert_active
|
||||
|
||||
print("Server sagt: Client verbunden")
|
||||
try:
|
||||
async for message in websocket:
|
||||
print(f"Server hat Empfangen: {message}")
|
||||
|
||||
data = json.loads(message)
|
||||
|
||||
if data.get("data_path"):
|
||||
|
|
@ -54,13 +53,17 @@ class Server:
|
|||
|
||||
elif data.get("data_command"):
|
||||
pass
|
||||
elif data.get("data_message"):
|
||||
logging.info(f"Server hat Empfangen: {data.get('data_message')}")
|
||||
|
||||
#response = f"Server antwortet: {message.upper()}"
|
||||
#await websocket.send(response)
|
||||
except (ConnectionClosedError, InvalidUpgrade):
|
||||
pass
|
||||
except json.JSONDecodeError as e:
|
||||
logging.error(f"JSON Fehler: {e}")
|
||||
except ConnectionClosed:
|
||||
print("Server sagt: Client getrennt")
|
||||
logging.error("Server sagt: Client getrennt")
|
||||
finally:
|
||||
self.clients.remove(websocket)
|
||||
|
||||
@staticmethod
|
||||
def set_var_convert_active(value: bool):
|
||||
|
|
@ -68,7 +71,37 @@ class Server:
|
|||
|
||||
var_convert_active = value
|
||||
|
||||
async def start(self):
|
||||
async def server_websocket(self):
|
||||
server = await websockets.serve(self.handle_client, self.yaml['server_ip'], self.yaml['server_port'])
|
||||
print(f"Websocket Server läuft auf IP: {self.yaml['server_ip']} Port: {self.yaml['server_port']}")
|
||||
await server.wait_closed()
|
||||
logging.info(f"Websocket Server läuft auf IP: {self.yaml['server_ip']} Port: {self.yaml['server_port']}")
|
||||
await server.wait_closed()
|
||||
|
||||
# WebServer --------------------------------------------------------------------------------------------------------
|
||||
|
||||
@staticmethod
|
||||
async def handle_index(request):
|
||||
return web.FileResponse("./client/index.html")
|
||||
|
||||
async def handle_ip(self, request):
|
||||
ip = self.yaml.get("server_ip", "localhost")
|
||||
port = self.yaml.get("server_port", 8000)
|
||||
return web.json_response({"server_ip": ip, "server_port": port})
|
||||
|
||||
async def server_http(self):
|
||||
app = web.Application()
|
||||
app.router.add_get("/", self.handle_index)
|
||||
app.router.add_get("/api/ip", self.handle_ip)
|
||||
app.router.add_static("/client", path="./client", name="client")
|
||||
runner = web.AppRunner(app)
|
||||
await runner.setup()
|
||||
site = web.TCPSite(runner, "0.0.0.0", 8080)
|
||||
await site.start()
|
||||
logging.info("HTTP Server läuft auf Port 8080")
|
||||
|
||||
# Start Server -----------------------------------------------------------------------------------------------------
|
||||
|
||||
async def start_server(self):
|
||||
await asyncio.gather(
|
||||
self.server_websocket(),
|
||||
self.server_http()
|
||||
)
|
||||
|
|
|
|||
4
requirements.txt
Normal file
4
requirements.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
PyYAML~=6.0.2
|
||||
websockets~=15.0
|
||||
asyncio~=3.4.3
|
||||
aiohttp~=3.11.16
|
||||
Loading…
Reference in a new issue