From f44c6d0af196e048756ff3065e876ee6999e5bce Mon Sep 17 00:00:00 2001 From: data Date: Mon, 3 Mar 2025 19:27:42 +0100 Subject: [PATCH] Test --- app/__pycache__/main.cpython-313.pyc | Bin 9997 -> 0 bytes app/__pycache__/video_class.cpython-313.pyc | Bin 2914 -> 0 bytes app/main.py | 42 ++++++-- app/templates/webs-ui.html | 4 +- app/video_class.py | 45 +++++--- app/webs/favicon.ico | Bin 0 -> 16958 bytes app/webs/mkv.png | Bin 0 -> 1953 bytes app/webs/webs.css | 11 +- app/webs/webs.js | 109 ++++++++++++++++---- 9 files changed, 156 insertions(+), 55 deletions(-) delete mode 100644 app/__pycache__/main.cpython-313.pyc delete mode 100644 app/__pycache__/video_class.cpython-313.pyc create mode 100644 app/webs/favicon.ico create mode 100644 app/webs/mkv.png diff --git a/app/__pycache__/main.cpython-313.pyc b/app/__pycache__/main.cpython-313.pyc deleted file mode 100644 index cdefe65f06851195222129ae2d09b48e1d3238dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9997 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 diff --git a/app/main.py b/app/main.py index ed3fed8..3aa62b2 100755 --- a/app/main.py +++ b/app/main.py @@ -8,17 +8,19 @@ import threading import time from datetime import date +import uvicorn from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect from fastapi.staticfiles import StaticFiles from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates +from starlette.websockets import WebSocketState import app.video_class as vc # Settings language = ["ger", "eng"] subtitle_codec_blacklist = ["hdmv_pgs_subtitle", "dvd_subtitle"] -max_tasks = 2 +max_tasks = 1 # Globale Variablen queue = asyncio.Queue() @@ -27,7 +29,7 @@ video_files = {} active_process = set() active_tasks = set() connected_clients = set() -semaphore = threading.Semaphore(1) +semaphore = threading.Semaphore(max_tasks) date = date.today() if not os.path.exists("./logs"): @@ -105,7 +107,7 @@ def get_ffprobe(select, source_file): # Convert Process ------------------------------------------------------------------------------------------------------ def queue_video(): for key, obj in video_files.items(): - with semaphore: + if obj.finished == 0: obj.task = threading.Thread(target=video_convert, args=(obj,)) obj.task.start() active_tasks.add(obj) @@ -114,6 +116,8 @@ def queue_video(): def video_convert(obj): global active_process + semaphore.acquire() + obj.convert_start = time.time() # Erstelle und setze einen Event-Loop für diesen Thread loop = asyncio.new_event_loop() @@ -123,7 +127,7 @@ def video_convert(obj): "ffmpeg", "-y", "-i", obj.source_file, "-map", "0:0", "-c:v", "libsvtav1", - "-preset", "8", + "-preset", "5", "-crf", "30", "-g", "240", "-pix_fmt", "yuv420p10le", @@ -150,6 +154,7 @@ def video_convert(obj): ]) command.append(obj.output_file) logging.info(f"{command}") + loop.run_until_complete(queue.put(video_list())) # Prozess try: @@ -179,9 +184,11 @@ def video_convert(obj): active_process.discard(obj) active_tasks.discard(obj) obj.convert_end = time.time() + semaphore.release() except Exception as e: obj.finished = 2 + semaphore.release() logging.error(f"Convert Process Failure: {e}") #UviCorn WebServer Teil @@ -194,11 +201,9 @@ def read_output(qu): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) - print(active_process) - while True: if not len(active_process): - time.sleep(30) + time.sleep(5) continue for obj in list(active_process): @@ -213,6 +218,13 @@ def read_output(qu): logging.info(f"Data Packet created: {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("/") 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.start() - # await queue.put(obj_list()) - try: + var_first_sending = 0 while True: + if websocket not in connected_clients: + break + message = await queue.get() # Warten auf neue Nachricht aus der Queue await websocket.send_text(message) + if not var_first_sending: + await queue.put(video_list()) + var_first_sending = 1 + except WebSocketDisconnect: logging.info("WebSocket disconnected") except Exception as e: logging.error(f"WebSocket error: {e}") finally: connected_clients.discard(websocket) - await websocket.close() + if websocket.client_state == WebSocketState.CONNECTED: + await websocket.close() @app.get("/clients") async def get_clients_count(): 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) \ No newline at end of file diff --git a/app/templates/webs-ui.html b/app/templates/webs-ui.html index 0a51bc8..f235964 100644 --- a/app/templates/webs-ui.html +++ b/app/templates/webs-ui.html @@ -8,7 +8,9 @@

Video-Konvertierung Fortschritt

-
+

+

Warteliste


+

Fertig

diff --git a/app/video_class.py b/app/video_class.py index 1d73674..2d75223 100644 --- a/app/video_class.py +++ b/app/video_class.py @@ -9,12 +9,16 @@ from collections import deque class Video: def __init__(self, path, video_streams, video_format, audio_streams, subtitle_streams): self.id = id(self) + + #Source self.source_file = path 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.frame_rate = self.frame_rate(video_streams) 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.convert_start = 0 self.convert_end = 0 @@ -30,15 +34,14 @@ class Video: self.format = [video_format] # Datenpaket - self.frame = 0 - self.fps = 0 - self.q = 0 - self.size = 0 - self.time = 0 - self.bitrate = 0 - self.speed = 0 - self.loading = 0 - self.count_empty_data = 0 + self.frame: int = 0 + self.fps: int = 0 + self.q: int = 0 + self.size: int = 0 + self.time: int = 0 + self.bitrate: int = 0 + self.speed: int = 0 + self.loading: int = 0 # Process self.task = None @@ -109,7 +112,16 @@ class Video: return json.dumps({"data_flow":data_packet}) 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): frame = re.findall(r"frame=\s*(\d+)", line_decoded) @@ -178,23 +190,22 @@ class Video: @staticmethod def format_time(seconds): - # Berechne die Anzahl der Tage, Stunden, Minuten und Sekunden - days = round(seconds // (24 * 3600)) # 1 Tag = 24 Stunden * 3600 Sekunden - seconds %= (24 * 3600) # Restliche Sekunden nach Tagen + days = round(seconds // (24 * 3600)) + seconds %= (24 * 3600) if days: d = f"{days} Tage" else: d = "" - hours = round(seconds // 3600) # 1 Stunde = 3600 Sekunden - seconds %= 3600 # Restliche Sekunden nach Stunden + hours = round(seconds // 3600) + seconds %= 3600 if hours: h = f"{hours} Std" else: h = "" - minutes = math.ceil(seconds // 60) # 1 Minute = 60 Sekunden - seconds %= 60 # Restliche Sekunden nach Minuten + minutes = math.ceil(seconds // 60) + seconds %= 60 if minutes: m = f"{minutes} Min" else: diff --git a/app/webs/favicon.ico b/app/webs/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a8550c8031551c8976ad89655ef688790e3af7ee GIT binary patch literal 16958 zcmeHN-ES0C6rXB>`VU|hA1VmpD@d%8E~T}!fdWN7ia@Bb)j~)kw0wj>_y}%|*g^w5 zG=9aJmRKMG;s*vJAwgD1XvJ3_e1NA~c_cjWCj2<(&YU>i&TeP!Tr<1oPV?)zbM866 z^E+p5x9w&fr;NUqE_LYp%g&s7$C>Il&Kv@{oGt?U)kS;uvJBj8qU?km7)cU4$WA0TjqSjA3-jr_4zXC?m{Y0&AN;ejK4@T7b zNynSgjfEG%NV=b>^-bxX1CP5*3ibZ_}jG(-2jtAAb4_I6`NC z)d4rQVgCa(99XVXQ|jsD`g5>yFBpEG&RTeo?ZpJ#Am67S0dMb9wXkB(V~VHOzg_yT zf2MRdb^rvOp8Yw@p>XRc;K#W`K-(U7k7HJKjG%Exr9W3^E%kJA{W*B69SpxuXDvLq zO}#R%?gkF-0M@wtv_Fc~?ezB#eO$@FCH3M`VeM8hO!44mC(uhhZ`h`Iv9|3I*0gnD z)20{V*6`;W)4je0Ao#g;*2M9UdC>Bn;-mEwtZO-o)vf={|39X5Z)m1x)f~V7rY*h9 zsJ8 z-PqCyMpAv~)-|OY?<@yHS4UELrgY=oIxv#zL$|Ie-Ds@_Lsv&qd8TyZ{Yo&B>O;4# zDc#ssfl`L<{3H+CU#0gVN*B_Hu0{J?F#P#JKHe`Te?Be#KEkZ=!Avmxu|YoGFD8FJ zE&e{jtg*A4-is<9-+zEl^9+)Jk8a++b^>++b^>++ zb^`7MVCoV&v8nq5hwgt#pPgb$pP|dO5+}Bnh5SRG5eaQ?dGWt`Hk)ztv*n(B&a=;Y r))AXgb+S%A>%~c)@CdJ0N9u}>X!@mZvAOe+`;<3Fi4)6XGH^Www{?b^ literal 0 HcmV?d00001 diff --git a/app/webs/mkv.png b/app/webs/mkv.png new file mode 100644 index 0000000000000000000000000000000000000000..98a82336edfcb1111f82a95d1830b6d6dc0f9a55 GIT binary patch literal 1953 zcmV;S2VVGzP)2bC6MxA`B&TBi=f3{e|Gw@U;1yXiCb?lGh%g*P7z!ddLkNx#f<1)L7eeR_BlLt3 zy2A)vD+nDc2yH6}t*Z$4RuRmr2zOTzZm%Kyv4(JS4dKR9gr=tm*PbFYt|K(8Bh;@W zTv|t{+d!z@K)A4haBdU9w24r?iBP$TaQ4{*RIj}YdF6qGFec&uMueZAEkeb{d-)S! zQbH2JXbcl!N9o7Z_LWmY6QdA@=aEFn#6$lcN{rKi2uuZz!j!a&o>8e3+`&jxgrMo= zRyqRx!J}Z4cF|)Al|pwo0-fQ1p>yS9p^0(FI6X)rWMaYJONnt#DouJPix4|c7z`zU zCMp6#XV@YU`N|4Jz_Jmv{M&0z!B8iZR zdEY;j7}E(5=Lu;9h}p^Ei%=h)f#f?`o2796-MU-k_cMDl4ue1 zz|&@7w2dQ)ASx_rfklu(d<`t2BIpX4pfl`;_VAGE-{q0JFj~iuL=X{{w6eVtOwbpU zk`kjDeC{BOmQf@T^oAwR6DKSzd%^1~2E^Aj{hLYU5R||gGASac!G|xxxa&p|L2p=! z^#rfa2lKuXaNrxNzfVbw!5SD0e?Vm*!z)4c`@TGZ5=Qedk_dXk5*y>(@{(eV^Zq69 zNX1}Ivm)3S6X6Y%8hi{Vj9WuUBIpfE+#Tfqtmknt%=?zMyMsTqp>cOeL`!$zvq)jw za3YDIH!N|Blm(c5T%52HQVYN>Qms3rgAZhd(KLu8g5I#iEpp<~Qd~KxnPR#FSvE#B z_*7aLR|k+p&>NPxMUn`MKA8Hm1RM@^6XdWo9;ktF|F#KocTj_m=7rH~KR>S9B@Y^z4RO>l|FP4b#sJ{cgBAFhb!)er`EOsYT`@ETtpeRyrf!+(Hr| zz8uQo#J$r>ImmE1RCVnKljS*;L#=g;-qrU7s2my`MbP9ZqH?(D3}~J#i6GrpIwN1* zL=qvk97@d*IMxzTJV7SW6HJ!hp}O~NdRJ#NktbZSo1k%^hCJcA^B2vNB}4BvAG(1g zLTouC8l#M2jO{O=vh&-x-*LfKM8<&gp?8~0t|N&MTMkEVFT?kD zmK70Xl0?xF>3n15hZEry74p;0!WiPK~vSjGp=7UX0BE*)%$)>mH;gukh*doug zZ+`4x9Z?gMF{4YeW)3rliRQhpun$#tt{T;JfDN&t+y895+Y*{A0^*ICXy(D%!Rap1kC1 zECX=PGN3Gft&=4Y=-x{2{S8TkT%l#MWa!=IFR!2?0+$0DBYQ%+?vPDv&NaI4Hh+HE zm2(m5Z2E>AhTd&H7}FgJ0pWL>55#nbLO}T4=6x~UA(u2c+!?phaWlr5Xy+N6bJL8` z?RDkmZu8z8cL%1??$R_*P(+xH`pLkYiw3PO&ycRW%^6{1EEGgv*MTqUF>ft0o5@n9 nk-IQHyW}c35x5*)0ZIG^GoSOVsKZc=00000NkvXXu0mjf%iDRf literal 0 HcmV?d00001 diff --git a/app/webs/webs.css b/app/webs/webs.css index cdcd712..d5b564c 100644 --- a/app/webs/webs.css +++ b/app/webs/webs.css @@ -56,16 +56,10 @@ h1 { } .table_video_info{ - border: None; + border: 1px solid black; width: 100%; } -th, td { - width: 16%; /* Jede Zelle nimmt 33% der Breite der Tabelle ein */ - padding: 16px; - text-align: left; /* Optional: Text ausrichten */ -} - .icons { width: 25px; float: right; @@ -73,7 +67,8 @@ th, td { .label { text-align: left; - vertical-align: middle; + vertical-align: top; + display: inline-block; } .loader { diff --git a/app/webs/webs.js b/app/webs/webs.js index cf030be..e81db52 100644 --- a/app/webs/webs.js +++ b/app/webs/webs.js @@ -1,6 +1,8 @@ let ws = new WebSocket("ws://127.0.0.1:8000/ws"); let videoQueue = {}; // Hier speichern wir alle laufenden Videos +console.log("Start Script"); + ws.onmessage = function(event) { try { let packet = JSON.parse(event.data); @@ -22,8 +24,22 @@ ws.onmessage = function(event) { } else { 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) { console.error("Fehler beim Parsen der WebSocket-Nachricht:", e, event.data); @@ -34,12 +50,66 @@ ws.onerror = function(event) { console.error("WebSocket Fehler:", event); }; -function sekundenInStundenMinuten(sekunden) { - const stunden = Math.floor(sekunden / 3600); // 1 Stunde = 3600 Sekunden - const minuten = Math.floor((sekunden % 3600) / 60); // Restsekunden in Minuten umrechnen - const verbleibendeSekunden = sekunden % 60; // Übrige Sekunden +function createVideoList(video) { + let container = document.createElement("div"); + container.className = "video_list"; + container.id = "remaining" - return `${stunden} Stunden, ${minuten} Minuten, ${verbleibendeSekunden} Sekunden`; + let html = ``; + + video.forEach(list => { + if(list.finished === 0) { + html += ` + + ${list.file_name} + ${list.duration} + ${list.source_file_size} + `; + } + }); + + container.innerHTML = ` +
+
+ + ${html} +
+
+
`; + + 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 += ` + + ${list.file_name} + ${list.duration} + ${list.source_file_size} + `; + } + }); + + container.innerHTML = ` +
+
+ + ${html} +
+
+
`; + + document.getElementById("video_finished").appendChild(container); + return container; } function createVideoElement(id, source, target, path) { @@ -54,21 +124,21 @@ function createVideoElement(id, source, target, path) {
${path}
- +
- - - + + + - - - + + + - - - + + +
0 Anz
0 fps
0 Q
0 Anz
0 fps
0 Q
0 MB
0 Mb/s
0 x
0 MB
0 Mb/s
0 x
0
0
@@ -94,14 +164,15 @@ function updateVideoElement(id, data) { let progress = data.loading; // Annahme: `loading` kommt als Zahl von 0 bis 100 progressBar.style.width = progress + "%" - if (data.finished == 0) { + if (data.finished == 3) { progressBar.style.background = "linear-gradient(90deg, #4caf50, #00c853)"; container.querySelector(".finished").textContent = "Läuft"; } else if(data.finished == 1) { progressBar.style.background = "#4caf50"; container.querySelector(".finished").textContent = "Fertig"; - } else { + } else if(data.finished == 2) { progressBar.style.background = "#ff0000"; container.querySelector(".finished").textContent = "Fehler"; } } +console.log("End Script");