Frontend überarbeitet, Settings angepasst,
This commit is contained in:
parent
cd5204fa12
commit
8193af6a15
8 changed files with 131 additions and 49 deletions
|
|
@ -3,7 +3,12 @@ log_level: DEBUG
|
||||||
log_rotation: time
|
log_rotation: time
|
||||||
path_file: "media_path.yaml"
|
path_file: "media_path.yaml"
|
||||||
server_ip: "0.0.0.0"
|
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
|
task_max: 1
|
||||||
autostart: true
|
autostart: true
|
||||||
subtitle:
|
subtitle:
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,9 @@ class Process:
|
||||||
self.process_line_extract(obj, line_decoded)
|
self.process_line_extract(obj, line_decoded)
|
||||||
#logging.info(line_decoded)
|
#logging.info(line_decoded)
|
||||||
|
|
||||||
self.time_remaining = obj.format_time(obj.time_remaining())
|
|
||||||
self.loading = (self.frames / obj.source_frames_total) * 100
|
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:
|
if self.line_empty > 30:
|
||||||
break
|
break
|
||||||
|
|
@ -49,7 +48,7 @@ class Process:
|
||||||
self.line_empty = 0
|
self.line_empty = 0
|
||||||
|
|
||||||
if i == 100 or i == 200 or i == 300 or i == 400 or i == 500:
|
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)
|
self.save_stat_value(obj)
|
||||||
elif i == 101 or i == 501:
|
elif i == 101 or i == 501:
|
||||||
i = 0
|
i = 0
|
||||||
|
|
@ -66,17 +65,14 @@ class Process:
|
||||||
|
|
||||||
# Quantizer
|
# Quantizer
|
||||||
q = re.findall(r"q=\s*(\d+).\d+", line)
|
q = re.findall(r"q=\s*(\d+).\d+", line)
|
||||||
#logging.info(f"q: {q}")
|
|
||||||
self.quantizer = int(q[0]) if q else 0
|
self.quantizer = int(q[0]) if q else 0
|
||||||
|
|
||||||
# Bitrate
|
# Bitrate
|
||||||
bitrate = re.findall(r"bitrate=\s*(\d+)", line)
|
bitrate = re.findall(r"bitrate=\s*(\d+)", line)
|
||||||
#logging.info(f"bitrate: {bitrate}")
|
|
||||||
self.bitrate[0] = int(bitrate[0]) if bitrate else 0
|
self.bitrate[0] = int(bitrate[0]) if bitrate else 0
|
||||||
|
|
||||||
# Speed
|
# Speed
|
||||||
speed = re.findall(r"speed=\s*(\d+\.\d+)", line)
|
speed = re.findall(r"speed=\s*(\d+\.\d+)", line)
|
||||||
#logging.info(f"speed: {speed}")
|
|
||||||
self.speed = float(speed[0]) if speed else 0.0
|
self.speed = float(speed[0]) if speed else 0.0
|
||||||
|
|
||||||
# File Size
|
# File Size
|
||||||
|
|
@ -88,7 +84,6 @@ class Process:
|
||||||
# Time
|
# Time
|
||||||
media_time = re.findall(r"time=\s*(\d+:\d+:\d+)", line)
|
media_time = re.findall(r"time=\s*(\d+:\d+:\d+)", line)
|
||||||
time_v = media_time[0] if media_time else "00:00:00"
|
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):
|
if self.time < obj.time_in_sec(time_v):
|
||||||
self.time = obj.time_in_sec(time_v)
|
self.time = obj.time_in_sec(time_v)
|
||||||
obj.process_time = self.time
|
obj.process_time = self.time
|
||||||
|
|
@ -112,15 +107,15 @@ class Process:
|
||||||
if self.speed:
|
if self.speed:
|
||||||
obj.stat_speed = [obj.stat_speed[0] + self.speed, obj.stat_speed[1] + 1]
|
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": {
|
return {"data_flow": {
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"frames": self.frames,
|
"frames": self.frames,
|
||||||
"fps": self.fps,
|
"fps": self.fps,
|
||||||
"quantizer": self.quantizer,
|
"quantizer": self.quantizer,
|
||||||
"size": self.size,
|
"size": self.size,
|
||||||
"time": self.time,
|
"time": obj.format_time(self.time, "Tage", "Std", "Min", None),
|
||||||
"time_remaining": self.time_remaining,
|
"time_remaining": obj.format_time(obj.time_remaining(), None, "Std", "Min", None),
|
||||||
"loading": self.loading,
|
"loading": self.loading,
|
||||||
"bitrate": self.bitrate,
|
"bitrate": self.bitrate,
|
||||||
"speed": self.speed
|
"speed": self.speed
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ class Media:
|
||||||
self.id = Media._id_counter
|
self.id = Media._id_counter
|
||||||
# source
|
# source
|
||||||
self.source_file: str = path
|
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_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_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")))
|
self.source_size: list = self.size_convert("B", None, "storage", int(streams_format[0].get("size")))
|
||||||
|
|
@ -83,6 +84,7 @@ class Media:
|
||||||
return {
|
return {
|
||||||
"source_file_name": self.source_file_name,
|
"source_file_name": self.source_file_name,
|
||||||
"source_file": self.source_file,
|
"source_file": self.source_file,
|
||||||
|
"source_path": self.source_path,
|
||||||
"source_duration": self.source_duration,
|
"source_duration": self.source_duration,
|
||||||
"source_size": self.source_size,
|
"source_size": self.source_size,
|
||||||
"source_frame_rate": self.source_frame_rate,
|
"source_frame_rate": self.source_frame_rate,
|
||||||
|
|
@ -147,30 +149,34 @@ class Media:
|
||||||
return self.process_time_remaining
|
return self.process_time_remaining
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def format_time(seconds):
|
def format_time(seconds:int, str_day, str_hour, str_min, str_s):
|
||||||
days = round(seconds // (24 * 3600))
|
days = round(seconds // (24 * 3600))
|
||||||
seconds %= (24 * 3600)
|
seconds %= (24 * 3600)
|
||||||
if days:
|
if days and str_day is not None:
|
||||||
d = (f"{days} Tag"
|
d = (f"{days} {str_day}")
|
||||||
f"")
|
|
||||||
else:
|
else:
|
||||||
d = ""
|
d = ""
|
||||||
|
|
||||||
hours = round(seconds // 3600)
|
hours = round(seconds // 3600)
|
||||||
seconds %= 3600
|
seconds %= 3600
|
||||||
if hours:
|
if hours and str_hour is not None:
|
||||||
h = f"{hours} Stunden"
|
h = f"{hours} {str_hour}"
|
||||||
else:
|
else:
|
||||||
h = ""
|
h = ""
|
||||||
|
|
||||||
minutes = math.ceil(seconds // 60)
|
minutes = math.ceil(seconds // 60)
|
||||||
seconds %= 60
|
seconds %= 60
|
||||||
if minutes:
|
if minutes and str_min is not None:
|
||||||
m = f"{minutes} Minuten"
|
m = f"{minutes} {str_min}"
|
||||||
else:
|
else:
|
||||||
m = ""
|
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
|
# Data convert
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
||||||
|
|
@ -78,8 +78,8 @@ class Server:
|
||||||
var_convert_active = value
|
var_convert_active = value
|
||||||
|
|
||||||
async def server_websocket(self):
|
async def server_websocket(self):
|
||||||
server = await websockets.serve(self.handle_client, self.yaml['server_ip'], 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['server_port']}")
|
logging.info(f"Websocket Server läuft auf IP: {self.yaml['server_ip']} Port: {self.yaml['websocket_port']}")
|
||||||
await server.wait_closed()
|
await server.wait_closed()
|
||||||
|
|
||||||
# WebServer --------------------------------------------------------------------------------------------------------
|
# WebServer --------------------------------------------------------------------------------------------------------
|
||||||
|
|
@ -97,9 +97,10 @@ class Server:
|
||||||
if "debug" in query:
|
if "debug" in query:
|
||||||
logging.info("Debug-Modus aktiv beim Seitenaufruf")
|
logging.info("Debug-Modus aktiv beim Seitenaufruf")
|
||||||
|
|
||||||
ip = self.yaml.get("server_ip", "localhost")
|
url = self.yaml["extern_websocket_url"]
|
||||||
port = self.yaml.get("server_port", 8000)
|
port = self.yaml["websocket_port"]
|
||||||
return web.json_response({"server_ip": ip, "server_port": port})
|
websocket_https = self.yaml["websocket_https"]
|
||||||
|
return web.json_response({"extern_websocket_url": url, "websocket_port": port, "websocket_https": websocket_https})
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def handle_stat(request):
|
async def handle_stat(request):
|
||||||
|
|
@ -118,9 +119,9 @@ class Server:
|
||||||
app.router.add_static("/client/", path="./client", name="client")
|
app.router.add_static("/client/", path="./client", name="client")
|
||||||
runner = web.AppRunner(app)
|
runner = web.AppRunner(app)
|
||||||
await runner.setup()
|
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()
|
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 -----------------------------------------------------------------------------------------------------
|
# Start Server -----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
<header>
|
<header>
|
||||||
<h1>Video Konvertierung</h1>
|
<h1>Video Konvertierung</h1>
|
||||||
<nav>
|
<nav>
|
||||||
<button onclick="toggleStatHidden()">Statistiken</button>
|
<img src="/client/icons/stat-100.png" onclick="openPopup()" alt="Statisiken" width="50" style="cursor: pointer;">
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
@ -28,10 +28,16 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- === Statistikbereich === -->
|
<!-- === Statistikbereich === -->
|
||||||
<section id="stat" hidden=True>
|
<div id="popup" class="popup">
|
||||||
<h2>Allgemeine Statistiken</h2>
|
<div class="popup-content">
|
||||||
<p>Hier könnten Diagramme, Durchschnittswerte etc. angezeigt werden.</p>
|
<div class="flex-row">
|
||||||
</section>
|
<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_conversion.js"></script>
|
||||||
<script src="/client/media_stat.js"></script>
|
<script src="/client/media_stat.js"></script>
|
||||||
|
|
|
||||||
|
|
@ -149,3 +149,54 @@ nav button:hover {
|
||||||
#statistics h2 {
|
#statistics h2 {
|
||||||
margin-top: 0;
|
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
36
client/media_conversion.js
Normal file → Executable file
|
|
@ -16,13 +16,21 @@ async function getMediaStat() {
|
||||||
|
|
||||||
getServerConfig()
|
getServerConfig()
|
||||||
.then(data => {
|
.then(data => {
|
||||||
const websocketIp = data.server_ip;
|
const externWebsocketUrl = data.extern_websocket_url;
|
||||||
const websocketPort = data.server_port;
|
const websocketPort = data.websocket_port;
|
||||||
const ws = new WebSocket(`ws://${websocketIp}:${websocketPort}`);
|
const websocketHttps = data.websocket_https
|
||||||
|
|
||||||
|
if (websocketHttps === 1){
|
||||||
|
connect = "wss"
|
||||||
|
} else {
|
||||||
|
connect = "ws"
|
||||||
|
}
|
||||||
|
|
||||||
|
const ws = new WebSocket(`${connect}://${externWebsocketUrl}:${websocketPort}`);
|
||||||
|
|
||||||
ws.onopen = function() {
|
ws.onopen = function() {
|
||||||
console.log("WebSocket ist geöffnet");
|
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) {
|
ws.onmessage = function(messageEvent) {
|
||||||
|
|
@ -64,20 +72,21 @@ function createVideoElement(packet){
|
||||||
card.id = key
|
card.id = key
|
||||||
|
|
||||||
card.innerHTML = `
|
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-container">
|
||||||
<div class="progress-bar"></div>
|
<div class="progress-bar"></div>
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
<br/>
|
||||||
<div class="video-card-values">
|
<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="Anzahl der verarbeiteten 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="Dateigröß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="Verarbeitungsgeschwindigkeit in Frames/Sekunde" 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="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="Bitrate" class="video-card-values-items"><b>Bitrate:</b> <span class="bitrate">0</span> <span class="bitrate_unit"></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="Speed" class="video-card-values-items"><b>Speed:</b> <span class="speed">0</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="Zeit" class="video-card-values-items"><b>Zeit:</b> <span class="time_remaining">0</span></div>
|
<div title="Verbleibende Zeit" class="video-card-values-items"><b>Verbleibend:</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="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>
|
||||||
<div class="tooltip">
|
<div class="tooltip">
|
||||||
Quelle: ${video.key}<br>
|
Quelle: ${video.key}<br>
|
||||||
|
|
@ -103,6 +112,7 @@ function updateVideoElement(packet){
|
||||||
container.querySelector(".bitrate_unit").textContent = video.bitrate[1] || 0;
|
container.querySelector(".bitrate_unit").textContent = video.bitrate[1] || 0;
|
||||||
container.querySelector(".speed").textContent = video.speed || 0;
|
container.querySelector(".speed").textContent = video.speed || 0;
|
||||||
container.querySelector(".time_remaining").textContent = video.time_remaining || 0;
|
container.querySelector(".time_remaining").textContent = video.time_remaining || 0;
|
||||||
|
container.querySelector(".time").textContent = video.time || 0;
|
||||||
|
|
||||||
let progressBar = container.querySelector(".progress-bar");
|
let progressBar = container.querySelector(".progress-bar");
|
||||||
let progress = video.loading; // Annahme: `loading` kommt als Zahl von 0 bis 100
|
let progress = video.loading; // Annahme: `loading` kommt als Zahl von 0 bis 100
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,14 @@ async function toggleStatHidden() {
|
||||||
section_stat.hidden = !section_stat.hidden
|
section_stat.hidden = !section_stat.hidden
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openPopup() {
|
||||||
|
document.getElementById("popup").style.display = "block";
|
||||||
|
}
|
||||||
|
|
||||||
|
function closePopup() {
|
||||||
|
document.getElementById("popup").style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
getMediaStat()
|
getMediaStat()
|
||||||
.then(data => {
|
.then(data => {
|
||||||
console.log("Antwort von /api/stats:", data); // Debug-Ausgabe
|
console.log("Antwort von /api/stats:", data); // Debug-Ausgabe
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue