Frontend überarbeitet, Settings angepasst,

This commit is contained in:
Eduard Wisch 2025-04-23 21:35:37 +02:00
parent cd5204fa12
commit 8193af6a15
8 changed files with 131 additions and 49 deletions

View file

@ -3,7 +3,12 @@ log_level: DEBUG
log_rotation: time
path_file: "media_path.yaml"
server_ip: "0.0.0.0"
server_port: 8000
extern_http_url: localhost
webserver_port: 8080
webserver_https: 0
extern_websocket_url: localhost
websocket_port: 8000
websocket_https: 0
task_max: 1
autostart: true
subtitle:

View file

@ -34,10 +34,9 @@ class Process:
self.process_line_extract(obj, line_decoded)
#logging.info(line_decoded)
self.time_remaining = obj.format_time(obj.time_remaining())
self.loading = (self.frames / obj.source_frames_total) * 100
await self.obj_websocket.send_websocket(self.to_dict())
await self.obj_websocket.send_websocket(self.to_dict(obj))
if self.line_empty > 30:
break
@ -49,7 +48,7 @@ class Process:
self.line_empty = 0
if i == 100 or i == 200 or i == 300 or i == 400 or i == 500:
logging.info(self.to_dict())
logging.info(self.to_dict(obj))
self.save_stat_value(obj)
elif i == 101 or i == 501:
i = 0
@ -66,17 +65,14 @@ class Process:
# Quantizer
q = re.findall(r"q=\s*(\d+).\d+", line)
#logging.info(f"q: {q}")
self.quantizer = int(q[0]) if q else 0
# Bitrate
bitrate = re.findall(r"bitrate=\s*(\d+)", line)
#logging.info(f"bitrate: {bitrate}")
self.bitrate[0] = int(bitrate[0]) if bitrate else 0
# Speed
speed = re.findall(r"speed=\s*(\d+\.\d+)", line)
#logging.info(f"speed: {speed}")
self.speed = float(speed[0]) if speed else 0.0
# File Size
@ -88,7 +84,6 @@ class Process:
# Time
media_time = re.findall(r"time=\s*(\d+:\d+:\d+)", line)
time_v = media_time[0] if media_time else "00:00:00"
#logging.info(media_time)
if self.time < obj.time_in_sec(time_v):
self.time = obj.time_in_sec(time_v)
obj.process_time = self.time
@ -112,15 +107,15 @@ class Process:
if self.speed:
obj.stat_speed = [obj.stat_speed[0] + self.speed, obj.stat_speed[1] + 1]
def to_dict(self):
def to_dict(self, obj):
return {"data_flow": {
"id": self.id,
"frames": self.frames,
"fps": self.fps,
"quantizer": self.quantizer,
"size": self.size,
"time": self.time,
"time_remaining": self.time_remaining,
"time": obj.format_time(self.time, "Tage", "Std", "Min", None),
"time_remaining": obj.format_time(obj.time_remaining(), None, "Std", "Min", None),
"loading": self.loading,
"bitrate": self.bitrate,
"speed": self.speed

View file

@ -9,6 +9,7 @@ class Media:
self.id = Media._id_counter
# source
self.source_file: str = path
self.source_path: str = os.path.dirname(path)
self.source_file_name: str = os.path.basename(self.source_file)
self.source_duration: int = self.time_in_sec(streams_video[0]["tags"].get("DURATION" or "duration", "00:00:00"))
self.source_size: list = self.size_convert("B", None, "storage", int(streams_format[0].get("size")))
@ -83,6 +84,7 @@ class Media:
return {
"source_file_name": self.source_file_name,
"source_file": self.source_file,
"source_path": self.source_path,
"source_duration": self.source_duration,
"source_size": self.source_size,
"source_frame_rate": self.source_frame_rate,
@ -147,30 +149,34 @@ class Media:
return self.process_time_remaining
@staticmethod
def format_time(seconds):
def format_time(seconds:int, str_day, str_hour, str_min, str_s):
days = round(seconds // (24 * 3600))
seconds %= (24 * 3600)
if days:
d = (f"{days} Tag"
f"")
if days and str_day is not None:
d = (f"{days} {str_day}")
else:
d = ""
hours = round(seconds // 3600)
seconds %= 3600
if hours:
h = f"{hours} Stunden"
if hours and str_hour is not None:
h = f"{hours} {str_hour}"
else:
h = ""
minutes = math.ceil(seconds // 60)
seconds %= 60
if minutes:
m = f"{minutes} Minuten"
if minutes and str_min is not None:
m = f"{minutes} {str_min}"
else:
m = ""
return f"{d} {h} {m}"
if seconds and str_s is not None:
s = f"{seconds} {str_s}"
else:
s = ""
return f"{d} {h} {m} {s}"
# Data convert
@staticmethod

View file

@ -78,8 +78,8 @@ class Server:
var_convert_active = value
async def server_websocket(self):
server = await websockets.serve(self.handle_client, self.yaml['server_ip'], self.yaml['server_port'])
logging.info(f"Websocket Server läuft auf IP: {self.yaml['server_ip']} Port: {self.yaml['server_port']}")
server = await websockets.serve(self.handle_client, self.yaml['server_ip'], self.yaml['websocket_port'])
logging.info(f"Websocket Server läuft auf IP: {self.yaml['server_ip']} Port: {self.yaml['websocket_port']}")
await server.wait_closed()
# WebServer --------------------------------------------------------------------------------------------------------
@ -97,9 +97,10 @@ class Server:
if "debug" in query:
logging.info("Debug-Modus aktiv beim Seitenaufruf")
ip = self.yaml.get("server_ip", "localhost")
port = self.yaml.get("server_port", 8000)
return web.json_response({"server_ip": ip, "server_port": port})
url = self.yaml["extern_websocket_url"]
port = self.yaml["websocket_port"]
websocket_https = self.yaml["websocket_https"]
return web.json_response({"extern_websocket_url": url, "websocket_port": port, "websocket_https": websocket_https})
@staticmethod
async def handle_stat(request):
@ -118,9 +119,9 @@ class Server:
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)
site = web.TCPSite(runner, "0.0.0.0", self.yaml["webserver_port"])
await site.start()
logging.info("HTTP Server läuft auf Port 8080")
logging.info(f"HTTP Server läuft auf Port {self.yaml["webserver_port"]}")
# Start Server -----------------------------------------------------------------------------------------------------

View file

@ -11,7 +11,7 @@
<header>
<h1>Video Konvertierung</h1>
<nav>
<button onclick="toggleStatHidden()">Statistiken</button>
<img src="/client/icons/stat-100.png" onclick="openPopup()" alt="Statisiken" width="50" style="cursor: pointer;">
</nav>
</header>
@ -28,10 +28,16 @@
</section>
<!-- === Statistikbereich === -->
<section id="stat" hidden=True>
<h2>Allgemeine Statistiken</h2>
<p>Hier könnten Diagramme, Durchschnittswerte etc. angezeigt werden.</p>
</section>
<div id="popup" class="popup">
<div class="popup-content">
<div class="flex-row">
<h2>Allgemeine Statistiken</h2>
<img src="/client/icons/close-144.png" onclick="closePopup()" alt="Statisiken" width="15" style="cursor: pointer;">
</div>
<p>Hier könnten Diagramme, Durchschnittswerte etc. angezeigt werden.</p>
<section id="stat"></section>
</div>
</div>
<script src="/client/media_conversion.js"></script>
<script src="/client/media_stat.js"></script>

View file

@ -149,3 +149,54 @@ nav button:hover {
#statistics h2 {
margin-top: 0;
}
.conversion_icons {
width: 50px;
height: auto;
}
.conversion_url {
font-size: 0.7rem;
text-align: center;
}
.popup {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0,0,0,0.7);
}
.popup-content {
background-color: #000000;
margin: 15% auto;
padding: 20px;
border: 1px solid #444;
width: 90%;
border-radius: 10px;
color: #eee;
}
.close {
color: #aaa;
float: right;
font-size: 24px;
font-weight: bold;
cursor: pointer;
}
.close:hover {
color: #fff;
}
.flex-row {
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: space-between;
}

36
client/media_conversion.js Normal file → Executable file
View file

@ -16,13 +16,21 @@ async function getMediaStat() {
getServerConfig()
.then(data => {
const websocketIp = data.server_ip;
const websocketPort = data.server_port;
const ws = new WebSocket(`ws://${websocketIp}:${websocketPort}`);
const externWebsocketUrl = data.extern_websocket_url;
const websocketPort = data.websocket_port;
const websocketHttps = data.websocket_https
if (websocketHttps === 1){
connect = "wss"
} else {
connect = "ws"
}
const ws = new WebSocket(`${connect}://${externWebsocketUrl}:${websocketPort}`);
ws.onopen = function() {
console.log("WebSocket ist geöffnet");
ws.send(JSON.stringify({"data_message": "Server Adresse: " + websocketIp + ":" + websocketPort}));
ws.send(JSON.stringify({"data_message": "Server Adresse: " + externWebsocketUrl + ":" + websocketPort}));
};
ws.onmessage = function(messageEvent) {
@ -64,20 +72,21 @@ function createVideoElement(packet){
card.id = key
card.innerHTML = `
<h3 title="${video.source_file_name}" align="center">${video.source_file_name} - ${video.target_file_name}</h3>
<h3 title="${video.source_path}" align="center">${video.source_file_name} - ${video.target_file_name}</h3>
<div class="progress-container">
<div class="progress-bar"></div>
</div>
<br/>
<div class="video-card-values">
<div title="Anzahl Frames" class="video-card-values-items"><b>Frames:</b> <span class="frames">0</span> Anz</div>
<div title="Größe" class="video-card-values-items"><b>Größe:</b> <span class="size">0</span> <span class="size_unit"></span></div>
<div title="FPS" class="video-card-values-items"><b>FPS:</b> <span class="fps">0</span></div>
<div title="Quantizer" class="video-card-values-items"><b>Quanitzer:</b> <span class="quantizer">0</span></div>
<div title="Bitrate" class="video-card-values-items"><b>Bitrate:</b> <span class="bitrate">0</span> <span class="bitrate_unit"></span></div>
<div title="Speed" class="video-card-values-items"><b>Speed:</b> <span class="speed">0</span></div>
<div title="Zeit" class="video-card-values-items"><b>Zeit:</b> <span class="time_remaining">0</span></div>
<div class="video-card-values-items delete-button"><button class="delete-button">Löschen</button></div>
<div title="Anzahl der verarbeiteten Frames" class="video-card-values-items"><b>Frames:</b> <span class="frames">0</span> Anz</div>
<div title="Dateigröße" class="video-card-values-items"><b>Größe:</b> <span class="size">0</span> <span class="size_unit"></span></div>
<div title="Verarbeitungsgeschwindigkeit in Frames/Sekunde" class="video-card-values-items"><b>FPS:</b> <span class="fps">0</span></div>
<div title="Qualitätswert: je niedriger, desto besser, nur bei bestimmten Codecs sichtbar" class="video-card-values-items"><b>Quanitzer:</b> <span class="quantizer">0</span></div>
<div title="Menge an Daten pro Sekunde, die für das Video verwendet wird" class="video-card-values-items"><b>Bitrate:</b> <span class="bitrate">0</span> <span class="bitrate_unit"></span></div>
<div title="Verarbeitungsgeschwindigkeit im Vergleich zur Echtzeit (1.0x = Echtzeit)" class="video-card-values-items"><b>Speed:</b> <span class="speed">0</span></div>
<div title="Verbleibende Zeit" class="video-card-values-items"><b>Verbleibend:</b> <span class="time_remaining">0</span></div>
<div title="Position im Film" class="video-card-values-items"><b>Zeit:</b> <span class="time">0</span></div>
<div class="video-card-values-items delete-button"><img src="/client/icons/muell-128.png" class="conversion_icons"></div>
</div>
<div class="tooltip">
Quelle: ${video.key}<br>
@ -103,6 +112,7 @@ function updateVideoElement(packet){
container.querySelector(".bitrate_unit").textContent = video.bitrate[1] || 0;
container.querySelector(".speed").textContent = video.speed || 0;
container.querySelector(".time_remaining").textContent = video.time_remaining || 0;
container.querySelector(".time").textContent = video.time || 0;
let progressBar = container.querySelector(".progress-bar");
let progress = video.loading; // Annahme: `loading` kommt als Zahl von 0 bis 100

View file

@ -16,6 +16,14 @@ async function toggleStatHidden() {
section_stat.hidden = !section_stat.hidden
}
function openPopup() {
document.getElementById("popup").style.display = "block";
}
function closePopup() {
document.getElementById("popup").style.display = "none";
}
getMediaStat()
.then(data => {
console.log("Antwort von /api/stats:", data); // Debug-Ausgabe