Test
This commit is contained in:
parent
7ea9407d41
commit
f44c6d0af1
9 changed files with 156 additions and 55 deletions
Binary file not shown.
Binary file not shown.
40
app/main.py
40
app/main.py
|
|
@ -8,17 +8,19 @@ import threading
|
||||||
import time
|
import time
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
|
import uvicorn
|
||||||
from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
|
from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from fastapi.responses import HTMLResponse
|
from fastapi.responses import HTMLResponse
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
|
from starlette.websockets import WebSocketState
|
||||||
|
|
||||||
import app.video_class as vc
|
import app.video_class as vc
|
||||||
|
|
||||||
# Settings
|
# Settings
|
||||||
language = ["ger", "eng"]
|
language = ["ger", "eng"]
|
||||||
subtitle_codec_blacklist = ["hdmv_pgs_subtitle", "dvd_subtitle"]
|
subtitle_codec_blacklist = ["hdmv_pgs_subtitle", "dvd_subtitle"]
|
||||||
max_tasks = 2
|
max_tasks = 1
|
||||||
|
|
||||||
# Globale Variablen
|
# Globale Variablen
|
||||||
queue = asyncio.Queue()
|
queue = asyncio.Queue()
|
||||||
|
|
@ -27,7 +29,7 @@ video_files = {}
|
||||||
active_process = set()
|
active_process = set()
|
||||||
active_tasks = set()
|
active_tasks = set()
|
||||||
connected_clients = set()
|
connected_clients = set()
|
||||||
semaphore = threading.Semaphore(1)
|
semaphore = threading.Semaphore(max_tasks)
|
||||||
date = date.today()
|
date = date.today()
|
||||||
|
|
||||||
if not os.path.exists("./logs"):
|
if not os.path.exists("./logs"):
|
||||||
|
|
@ -105,7 +107,7 @@ def get_ffprobe(select, source_file):
|
||||||
# Convert Process ------------------------------------------------------------------------------------------------------
|
# Convert Process ------------------------------------------------------------------------------------------------------
|
||||||
def queue_video():
|
def queue_video():
|
||||||
for key, obj in video_files.items():
|
for key, obj in video_files.items():
|
||||||
with semaphore:
|
if obj.finished == 0:
|
||||||
obj.task = threading.Thread(target=video_convert, args=(obj,))
|
obj.task = threading.Thread(target=video_convert, args=(obj,))
|
||||||
obj.task.start()
|
obj.task.start()
|
||||||
active_tasks.add(obj)
|
active_tasks.add(obj)
|
||||||
|
|
@ -114,6 +116,8 @@ def queue_video():
|
||||||
def video_convert(obj):
|
def video_convert(obj):
|
||||||
global active_process
|
global active_process
|
||||||
|
|
||||||
|
semaphore.acquire()
|
||||||
|
|
||||||
obj.convert_start = time.time()
|
obj.convert_start = time.time()
|
||||||
# Erstelle und setze einen Event-Loop für diesen Thread
|
# Erstelle und setze einen Event-Loop für diesen Thread
|
||||||
loop = asyncio.new_event_loop()
|
loop = asyncio.new_event_loop()
|
||||||
|
|
@ -123,7 +127,7 @@ def video_convert(obj):
|
||||||
"ffmpeg", "-y", "-i", obj.source_file,
|
"ffmpeg", "-y", "-i", obj.source_file,
|
||||||
"-map", "0:0",
|
"-map", "0:0",
|
||||||
"-c:v", "libsvtav1",
|
"-c:v", "libsvtav1",
|
||||||
"-preset", "8",
|
"-preset", "5",
|
||||||
"-crf", "30",
|
"-crf", "30",
|
||||||
"-g", "240",
|
"-g", "240",
|
||||||
"-pix_fmt", "yuv420p10le",
|
"-pix_fmt", "yuv420p10le",
|
||||||
|
|
@ -150,6 +154,7 @@ def video_convert(obj):
|
||||||
])
|
])
|
||||||
command.append(obj.output_file)
|
command.append(obj.output_file)
|
||||||
logging.info(f"{command}")
|
logging.info(f"{command}")
|
||||||
|
loop.run_until_complete(queue.put(video_list()))
|
||||||
|
|
||||||
# Prozess
|
# Prozess
|
||||||
try:
|
try:
|
||||||
|
|
@ -179,9 +184,11 @@ def video_convert(obj):
|
||||||
active_process.discard(obj)
|
active_process.discard(obj)
|
||||||
active_tasks.discard(obj)
|
active_tasks.discard(obj)
|
||||||
obj.convert_end = time.time()
|
obj.convert_end = time.time()
|
||||||
|
semaphore.release()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
obj.finished = 2
|
obj.finished = 2
|
||||||
|
semaphore.release()
|
||||||
logging.error(f"Convert Process Failure: {e}")
|
logging.error(f"Convert Process Failure: {e}")
|
||||||
|
|
||||||
#UviCorn WebServer Teil
|
#UviCorn WebServer Teil
|
||||||
|
|
@ -194,11 +201,9 @@ def read_output(qu):
|
||||||
loop = asyncio.new_event_loop()
|
loop = asyncio.new_event_loop()
|
||||||
asyncio.set_event_loop(loop)
|
asyncio.set_event_loop(loop)
|
||||||
|
|
||||||
print(active_process)
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if not len(active_process):
|
if not len(active_process):
|
||||||
time.sleep(30)
|
time.sleep(5)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for obj in list(active_process):
|
for obj in list(active_process):
|
||||||
|
|
@ -213,6 +218,13 @@ def read_output(qu):
|
||||||
logging.info(f"Data Packet created: {obj.to_dict()}")
|
logging.info(f"Data Packet created: {obj.to_dict()}")
|
||||||
loop.run_until_complete(qu.put(obj.to_dict()))
|
loop.run_until_complete(qu.put(obj.to_dict()))
|
||||||
|
|
||||||
|
def video_list():
|
||||||
|
vlist = []
|
||||||
|
for video in video_files.values():
|
||||||
|
vlist.append(video.get_vars())
|
||||||
|
|
||||||
|
return json.dumps({"video_list": vlist})
|
||||||
|
|
||||||
|
|
||||||
@app.post("/")
|
@app.post("/")
|
||||||
async def receive_video_file(data: dict):
|
async def receive_video_file(data: dict):
|
||||||
|
|
@ -242,20 +254,30 @@ async def websocket_v(websocket: WebSocket):
|
||||||
read_output_task = threading.Thread(target=read_output, args=(queue,))
|
read_output_task = threading.Thread(target=read_output, args=(queue,))
|
||||||
read_output_task.start()
|
read_output_task.start()
|
||||||
|
|
||||||
# await queue.put(obj_list())
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
var_first_sending = 0
|
||||||
while True:
|
while True:
|
||||||
|
if websocket not in connected_clients:
|
||||||
|
break
|
||||||
|
|
||||||
message = await queue.get() # Warten auf neue Nachricht aus der Queue
|
message = await queue.get() # Warten auf neue Nachricht aus der Queue
|
||||||
await websocket.send_text(message)
|
await websocket.send_text(message)
|
||||||
|
if not var_first_sending:
|
||||||
|
await queue.put(video_list())
|
||||||
|
var_first_sending = 1
|
||||||
|
|
||||||
except WebSocketDisconnect:
|
except WebSocketDisconnect:
|
||||||
logging.info("WebSocket disconnected")
|
logging.info("WebSocket disconnected")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"WebSocket error: {e}")
|
logging.error(f"WebSocket error: {e}")
|
||||||
finally:
|
finally:
|
||||||
connected_clients.discard(websocket)
|
connected_clients.discard(websocket)
|
||||||
|
if websocket.client_state == WebSocketState.CONNECTED:
|
||||||
await websocket.close()
|
await websocket.close()
|
||||||
|
|
||||||
@app.get("/clients")
|
@app.get("/clients")
|
||||||
async def get_clients_count():
|
async def get_clients_count():
|
||||||
return {"active_clients": len(connected_clients), "active_processes": len(active_process), "active_tasks": len(active_tasks)}
|
return {"active_clients": len(connected_clients), "active_processes": len(active_process), "active_tasks": len(active_tasks)}
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
uvicorn.run("app.main:app", host="127.0.0.1", port=8000, reload=False)
|
||||||
|
|
@ -8,7 +8,9 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Video-Konvertierung Fortschritt</h1>
|
<h1>Video-Konvertierung Fortschritt</h1>
|
||||||
<div id="videos"></div>
|
<div id="videos"></div><br />
|
||||||
|
<div id="video_list" class="video"><div class="video-header"><h1>Warteliste</h1></div></div><br />
|
||||||
|
<div id="video_finished" class="video"><div class="video-header"><h1>Fertig</h1></div></div>
|
||||||
<script src="/webs/webs.js"></script>
|
<script src="/webs/webs.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,16 @@ from collections import deque
|
||||||
class Video:
|
class Video:
|
||||||
def __init__(self, path, video_streams, video_format, audio_streams, subtitle_streams):
|
def __init__(self, path, video_streams, video_format, audio_streams, subtitle_streams):
|
||||||
self.id = id(self)
|
self.id = id(self)
|
||||||
|
|
||||||
|
#Source
|
||||||
self.source_file = path
|
self.source_file = path
|
||||||
self.file_name = os.path.basename(self.source_file)
|
self.file_name = os.path.basename(self.source_file)
|
||||||
self.duration = self.time_in_sec(video_streams[0]["tags"].get("DURATION" or "duration", "00:00:00"))
|
self.duration = self.time_in_sec(video_streams[0]["tags"].get("DURATION" or "duration", "00:00:00"))
|
||||||
self.frame_rate = self.frame_rate(video_streams)
|
self.frame_rate = self.frame_rate(video_streams)
|
||||||
self.frames_max = self.frame_rate * self.duration
|
self.frames_max = self.frame_rate * self.duration
|
||||||
|
self.source_file_size = video_format.get("size", 0)
|
||||||
|
|
||||||
|
# Target
|
||||||
self.output_file = f"{path.rsplit(".", 1)[0]}.webm"
|
self.output_file = f"{path.rsplit(".", 1)[0]}.webm"
|
||||||
self.convert_start = 0
|
self.convert_start = 0
|
||||||
self.convert_end = 0
|
self.convert_end = 0
|
||||||
|
|
@ -30,15 +34,14 @@ class Video:
|
||||||
self.format = [video_format]
|
self.format = [video_format]
|
||||||
|
|
||||||
# Datenpaket
|
# Datenpaket
|
||||||
self.frame = 0
|
self.frame: int = 0
|
||||||
self.fps = 0
|
self.fps: int = 0
|
||||||
self.q = 0
|
self.q: int = 0
|
||||||
self.size = 0
|
self.size: int = 0
|
||||||
self.time = 0
|
self.time: int = 0
|
||||||
self.bitrate = 0
|
self.bitrate: int = 0
|
||||||
self.speed = 0
|
self.speed: int = 0
|
||||||
self.loading = 0
|
self.loading: int = 0
|
||||||
self.count_empty_data = 0
|
|
||||||
|
|
||||||
# Process
|
# Process
|
||||||
self.task = None
|
self.task = None
|
||||||
|
|
@ -109,7 +112,16 @@ class Video:
|
||||||
return json.dumps({"data_flow":data_packet})
|
return json.dumps({"data_flow":data_packet})
|
||||||
|
|
||||||
def get_vars(self):
|
def get_vars(self):
|
||||||
return json.dumps({"obj_list":vars(self)})
|
obj_vars = {
|
||||||
|
"id": self.id,
|
||||||
|
"file_name": self.file_name,
|
||||||
|
"duration": self.format_time(self.duration),
|
||||||
|
"source_file_size": self.convert_kb_mb(self.source_file_size),
|
||||||
|
"finished": self.finished
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj_vars
|
||||||
|
|
||||||
def extract_convert_data(self, line_decoded):
|
def extract_convert_data(self, line_decoded):
|
||||||
frame = re.findall(r"frame=\s*(\d+)", line_decoded)
|
frame = re.findall(r"frame=\s*(\d+)", line_decoded)
|
||||||
|
|
@ -178,23 +190,22 @@ class Video:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def format_time(seconds):
|
def format_time(seconds):
|
||||||
# Berechne die Anzahl der Tage, Stunden, Minuten und Sekunden
|
days = round(seconds // (24 * 3600))
|
||||||
days = round(seconds // (24 * 3600)) # 1 Tag = 24 Stunden * 3600 Sekunden
|
seconds %= (24 * 3600)
|
||||||
seconds %= (24 * 3600) # Restliche Sekunden nach Tagen
|
|
||||||
if days:
|
if days:
|
||||||
d = f"{days} Tage"
|
d = f"{days} Tage"
|
||||||
else:
|
else:
|
||||||
d = ""
|
d = ""
|
||||||
|
|
||||||
hours = round(seconds // 3600) # 1 Stunde = 3600 Sekunden
|
hours = round(seconds // 3600)
|
||||||
seconds %= 3600 # Restliche Sekunden nach Stunden
|
seconds %= 3600
|
||||||
if hours:
|
if hours:
|
||||||
h = f"{hours} Std"
|
h = f"{hours} Std"
|
||||||
else:
|
else:
|
||||||
h = ""
|
h = ""
|
||||||
|
|
||||||
minutes = math.ceil(seconds // 60) # 1 Minute = 60 Sekunden
|
minutes = math.ceil(seconds // 60)
|
||||||
seconds %= 60 # Restliche Sekunden nach Minuten
|
seconds %= 60
|
||||||
if minutes:
|
if minutes:
|
||||||
m = f"{minutes} Min"
|
m = f"{minutes} Min"
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
BIN
app/webs/favicon.ico
Normal file
BIN
app/webs/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
app/webs/mkv.png
Normal file
BIN
app/webs/mkv.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
|
|
@ -56,16 +56,10 @@ h1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
.table_video_info{
|
.table_video_info{
|
||||||
border: None;
|
border: 1px solid black;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
th, td {
|
|
||||||
width: 16%; /* Jede Zelle nimmt 33% der Breite der Tabelle ein */
|
|
||||||
padding: 16px;
|
|
||||||
text-align: left; /* Optional: Text ausrichten */
|
|
||||||
}
|
|
||||||
|
|
||||||
.icons {
|
.icons {
|
||||||
width: 25px;
|
width: 25px;
|
||||||
float: right;
|
float: right;
|
||||||
|
|
@ -73,7 +67,8 @@ th, td {
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
vertical-align: middle;
|
vertical-align: top;
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loader {
|
.loader {
|
||||||
|
|
|
||||||
109
app/webs/webs.js
109
app/webs/webs.js
|
|
@ -1,6 +1,8 @@
|
||||||
let ws = new WebSocket("ws://127.0.0.1:8000/ws");
|
let ws = new WebSocket("ws://127.0.0.1:8000/ws");
|
||||||
let videoQueue = {}; // Hier speichern wir alle laufenden Videos
|
let videoQueue = {}; // Hier speichern wir alle laufenden Videos
|
||||||
|
|
||||||
|
console.log("Start Script");
|
||||||
|
|
||||||
ws.onmessage = function(event) {
|
ws.onmessage = function(event) {
|
||||||
try {
|
try {
|
||||||
let packet = JSON.parse(event.data);
|
let packet = JSON.parse(event.data);
|
||||||
|
|
@ -22,8 +24,22 @@ ws.onmessage = function(event) {
|
||||||
} else {
|
} else {
|
||||||
console.error("Fehlende Felder in der Nachricht", message);
|
console.error("Fehlende Felder in der Nachricht", message);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
console.error("Kein data_flow in der empfangenen Nachricht", packet);
|
|
||||||
|
if (packet.video_list !== undefined) {
|
||||||
|
let video_list = packet.video_list;
|
||||||
|
|
||||||
|
createVideoList(video_list);
|
||||||
|
createVideoListFinished(video_list);
|
||||||
|
|
||||||
|
video_list.forEach(list => {
|
||||||
|
if(list.finished === 1) {
|
||||||
|
let container = document.getElementById(list.id); // Holt das Element mit der id
|
||||||
|
if (container) {
|
||||||
|
container.remove(); // Entfernt das Element aus dem DOM
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Fehler beim Parsen der WebSocket-Nachricht:", e, event.data);
|
console.error("Fehler beim Parsen der WebSocket-Nachricht:", e, event.data);
|
||||||
|
|
@ -34,12 +50,66 @@ ws.onerror = function(event) {
|
||||||
console.error("WebSocket Fehler:", event);
|
console.error("WebSocket Fehler:", event);
|
||||||
};
|
};
|
||||||
|
|
||||||
function sekundenInStundenMinuten(sekunden) {
|
function createVideoList(video) {
|
||||||
const stunden = Math.floor(sekunden / 3600); // 1 Stunde = 3600 Sekunden
|
let container = document.createElement("div");
|
||||||
const minuten = Math.floor((sekunden % 3600) / 60); // Restsekunden in Minuten umrechnen
|
container.className = "video_list";
|
||||||
const verbleibendeSekunden = sekunden % 60; // Übrige Sekunden
|
container.id = "remaining"
|
||||||
|
|
||||||
return `${stunden} Stunden, ${minuten} Minuten, ${verbleibendeSekunden} Sekunden`;
|
let html = ``;
|
||||||
|
|
||||||
|
video.forEach(list => {
|
||||||
|
if(list.finished === 0) {
|
||||||
|
html += `<tr>
|
||||||
|
<td width="5%" align="right"><img src="/webs/mkv.png" width="20px"></td>
|
||||||
|
<td width="65%" align="left"><span>${list.file_name}</span></td>
|
||||||
|
<td width="15%" align="right"><span>${list.duration}</span></td>
|
||||||
|
<td width="15%" align="right"><span>${list.source_file_size}</span></td>
|
||||||
|
</tr>`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
container.innerHTML = `
|
||||||
|
<div class="video-info">
|
||||||
|
<div>
|
||||||
|
<table class="table_video_wait" id="remaining_list" border="0" width="100%">
|
||||||
|
${html}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
document.getElementById("video_list").appendChild(container);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createVideoListFinished(video) {
|
||||||
|
let container = document.createElement("div");
|
||||||
|
container.className = "video_list";
|
||||||
|
container.id = "finished"
|
||||||
|
|
||||||
|
let html = ``;
|
||||||
|
|
||||||
|
video.forEach(list => {
|
||||||
|
if(list.finished === 1) {
|
||||||
|
html += `<tr>
|
||||||
|
<td width="5%" align="right"><img src="/webs/mkv.png" width="20px"></td>
|
||||||
|
<td width="65%" align="left"><span>${list.file_name}</span></td>
|
||||||
|
<td width="15%" align="right"><span>${list.duration}</span></td>
|
||||||
|
<td width="15%" align="right"><span>${list.source_file_size}</span></td>
|
||||||
|
</tr>`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
container.innerHTML = `
|
||||||
|
<div class="video-info">
|
||||||
|
<div>
|
||||||
|
<table class="table_video_wait" id="remaining_list" border="0" width="100%">
|
||||||
|
${html}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
document.getElementById("video_finished").appendChild(container);
|
||||||
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createVideoElement(id, source, target, path) {
|
function createVideoElement(id, source, target, path) {
|
||||||
|
|
@ -54,21 +124,21 @@ function createVideoElement(id, source, target, path) {
|
||||||
</div>
|
</div>
|
||||||
<div class="video-info">
|
<div class="video-info">
|
||||||
<div><span class="path">${path}</span></div>
|
<div><span class="path">${path}</span></div>
|
||||||
<table class="table_video_info">
|
<table border="0" width="100%" style="border-spacing: 20px;">
|
||||||
<tr>
|
<tr>
|
||||||
<th><img src="/webs/animation-32.png" class="icons"></th><th class="label"><div title="Anzahl Frames"><span class="frame">0</span> Anz</div></th>
|
<td><img src="/webs/animation-32.png" class="icons"></td><td class="label"><div title="Anzahl Frames"><span class="frame">0</span> Anz</div></td>
|
||||||
<th><img src="/webs/fps-32.png" class="icons"></th><th class="label"><div title="Frames / Sekunde"><span class="fps">0</span> fps</div></th>
|
<td><img src="/webs/fps-32.png" class="icons"></td><td class="label"><div title="Frames / Sekunde"><span class="fps">0</span> fps</div></td>
|
||||||
<th><img src="/webs/q-24.png" class="icons"></th><th class="label"><div title="Quantizer"><span class="q">0 </span> Q</div></th>
|
<td><img src="/webs/q-24.png" class="icons"></td><td class="label"><div title="Quantizer"><span class="q">0 </span> Q</div></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th><img src="/webs/ssd-30.png" class="icons"></th><th class="label"><div title="Dateigröße"><span class="size">0 </span> MB</div></th>
|
<td><img src="/webs/ssd-30.png" class="icons"></td><td class="label"><div title="Dateigröße"><span class="size">0 </span> MB</div></td>
|
||||||
<th><img src="/webs/bitrate-30.png" class="icons"></th><th class="label"><div title="Bitrate"><span class="bitrate">0 </span> Mb/s</div></th>
|
<td><img src="/webs/bitrate-30.png" class="icons"></td><td class="label"><div title="Bitrate"><span class="bitrate">0 </span> Mb/s</div></td>
|
||||||
<th><img src="/webs/speed-32.png" class="icons"></th><th class="label"><div title="Speed"><span class="speed">0</span> x</div></th>
|
<td><img src="/webs/speed-32.png" class="icons"></td><td class="label"><div title="Speed"><span class="speed">0</span> x</div></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th><img src="/webs/timer-50.png" class="icons"></th><th class="label" colspan="2"><div title="Verbleibend"><span class="time_remaining">0 </span></div></th>
|
<td valign="top"><img src="/webs/timer-50.png" class="icons"></td><td class="label"><div title="Verbleibend"><span class="time_remaining">0 </span></div></td>
|
||||||
<th></th><th></th>
|
<td></td><td></td>
|
||||||
<th></th><th><div class="loader"><span class="finished"></span></div></th>
|
<td></td><td align="right"><div class="loader"><span class="finished"></span></div></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -94,14 +164,15 @@ function updateVideoElement(id, data) {
|
||||||
let progress = data.loading; // Annahme: `loading` kommt als Zahl von 0 bis 100
|
let progress = data.loading; // Annahme: `loading` kommt als Zahl von 0 bis 100
|
||||||
progressBar.style.width = progress + "%"
|
progressBar.style.width = progress + "%"
|
||||||
|
|
||||||
if (data.finished == 0) {
|
if (data.finished == 3) {
|
||||||
progressBar.style.background = "linear-gradient(90deg, #4caf50, #00c853)";
|
progressBar.style.background = "linear-gradient(90deg, #4caf50, #00c853)";
|
||||||
container.querySelector(".finished").textContent = "Läuft";
|
container.querySelector(".finished").textContent = "Läuft";
|
||||||
} else if(data.finished == 1) {
|
} else if(data.finished == 1) {
|
||||||
progressBar.style.background = "#4caf50";
|
progressBar.style.background = "#4caf50";
|
||||||
container.querySelector(".finished").textContent = "Fertig";
|
container.querySelector(".finished").textContent = "Fertig";
|
||||||
} else {
|
} else if(data.finished == 2) {
|
||||||
progressBar.style.background = "#ff0000";
|
progressBar.style.background = "#ff0000";
|
||||||
container.querySelector(".finished").textContent = "Fehler";
|
container.querySelector(".finished").textContent = "Fehler";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
console.log("End Script");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue