Fehler Time gefixt. Code aufgeräumt, Java Script Datenpaket angepasst
This commit is contained in:
parent
beebd25f69
commit
7ea9407d41
3 changed files with 72 additions and 43 deletions
66
app/main.py
66
app/main.py
|
|
@ -15,6 +15,18 @@ from fastapi.templating import Jinja2Templates
|
||||||
|
|
||||||
import app.video_class as vc
|
import app.video_class as vc
|
||||||
|
|
||||||
|
# Settings
|
||||||
|
language = ["ger", "eng"]
|
||||||
|
subtitle_codec_blacklist = ["hdmv_pgs_subtitle", "dvd_subtitle"]
|
||||||
|
max_tasks = 2
|
||||||
|
|
||||||
|
# Globale Variablen
|
||||||
|
queue = asyncio.Queue()
|
||||||
|
read_output_task = None
|
||||||
|
video_files = {}
|
||||||
|
active_process = set()
|
||||||
|
active_tasks = set()
|
||||||
|
connected_clients = set()
|
||||||
semaphore = threading.Semaphore(1)
|
semaphore = threading.Semaphore(1)
|
||||||
date = date.today()
|
date = date.today()
|
||||||
|
|
||||||
|
|
@ -34,18 +46,12 @@ app = FastAPI()
|
||||||
app.mount("/webs", StaticFiles(directory="app/webs"), name="webs")
|
app.mount("/webs", StaticFiles(directory="app/webs"), name="webs")
|
||||||
templates = Jinja2Templates(directory="app/templates")
|
templates = Jinja2Templates(directory="app/templates")
|
||||||
|
|
||||||
queue = asyncio.Queue()
|
def obj_list():
|
||||||
read_output_task = None
|
list_json = []
|
||||||
|
for obj_video in video_files.values():
|
||||||
|
list_json.append(obj_video.get_vars())
|
||||||
|
|
||||||
# Settings
|
return json.dumps({"list_video":list_json})
|
||||||
language = ["ger", "eng"]
|
|
||||||
subtitle_codec_blacklist = ["hdmv_pgs_subtitle", "dvd_subtitle"]
|
|
||||||
max_tasks = 2
|
|
||||||
|
|
||||||
video_files = {}
|
|
||||||
active_process = set()
|
|
||||||
active_tasks = set()
|
|
||||||
connected_clients = set()
|
|
||||||
|
|
||||||
# Media ----------------------------------------------------------------------------------------------------------------
|
# Media ----------------------------------------------------------------------------------------------------------------
|
||||||
def get_video_information(media_path):
|
def get_video_information(media_path):
|
||||||
|
|
@ -117,10 +123,10 @@ 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", "5",
|
"-preset", "8",
|
||||||
"-crf", "24",
|
"-crf", "30",
|
||||||
"-g", "240",
|
"-g", "240",
|
||||||
"-pix_fmt", "yuv420p",
|
"-pix_fmt", "yuv420p10le",
|
||||||
"-svtav1-params", "tune=0:film-grain=8",
|
"-svtav1-params", "tune=0:film-grain=8",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -154,25 +160,21 @@ def video_convert(obj):
|
||||||
)
|
)
|
||||||
|
|
||||||
active_process.add(obj)
|
active_process.add(obj)
|
||||||
logging.info(f"{obj.file_name}")
|
obj.finished = 3
|
||||||
|
|
||||||
print(obj.process.poll())
|
|
||||||
while obj.process.poll() is None:
|
while obj.process.poll() is None:
|
||||||
logging.info(f"{obj.file_name} ... Running")
|
logging.info(f"{obj.file_name} ... Running")
|
||||||
time.sleep(30)
|
time.sleep(10)
|
||||||
print(obj.process.poll())
|
|
||||||
|
|
||||||
if obj.process.poll() == 0:
|
if obj.process.poll() == 0:
|
||||||
obj.finished = 1
|
obj.finished = 1
|
||||||
logging.info(f"Process Finished({obj.process.returncode}): {obj.file_name}")
|
logging.info(f"Process Finished({obj.process.returncode}): {obj.file_name}")
|
||||||
json_data = json.dumps(obj.to_dict())
|
loop.run_until_complete(queue.put(obj.to_dict()))
|
||||||
loop.run_until_complete(queue.put(json_data))
|
|
||||||
|
|
||||||
elif obj.process.poll() != 0:
|
elif obj.process.poll() != 0:
|
||||||
obj.finished = 2
|
obj.finished = 2
|
||||||
logging.info(f"Process Failure({obj.process.returncode}): {obj.file_name}")
|
logging.info(f"Process Failure({obj.process.returncode}): {obj.file_name}")
|
||||||
json_data = json.dumps(obj.to_dict())
|
loop.run_until_complete(queue.put(obj.to_dict()))
|
||||||
loop.run_until_complete(queue.put(json_data))
|
|
||||||
|
|
||||||
active_process.discard(obj)
|
active_process.discard(obj)
|
||||||
active_tasks.discard(obj)
|
active_tasks.discard(obj)
|
||||||
|
|
@ -182,10 +184,6 @@ def video_convert(obj):
|
||||||
obj.finished = 2
|
obj.finished = 2
|
||||||
logging.error(f"Convert Process Failure: {e}")
|
logging.error(f"Convert Process Failure: {e}")
|
||||||
|
|
||||||
|
|
||||||
#test = {"files":["/mnt/Storage/11 - Downloads - JDownloader/01 - Fertig/Star Trek: Deep Space Nine - S01E03 - Die Khon-Ma.mkv /mnt/Storage/11 - Downloads - JDownloader/01 - Fertig/Star Trek: Deep Space Nine - S01E04 - Unter Verdacht.mkv"]}
|
|
||||||
#get_video_information(test)
|
|
||||||
|
|
||||||
#UviCorn WebServer Teil
|
#UviCorn WebServer Teil
|
||||||
#----------------------------------------------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
def read_output(qu):
|
def read_output(qu):
|
||||||
|
|
@ -196,25 +194,25 @@ 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):
|
||||||
loop.run_until_complete(asyncio.sleep(30)) # Keine aktiven Prozesse → kurze Pause
|
time.sleep(30)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for obj in list(active_process):
|
for obj in list(active_process):
|
||||||
line_error = obj.process.stderr.read(1024)
|
line_error = obj.process.stderr.read(1024)
|
||||||
if not line_error:
|
|
||||||
continue
|
|
||||||
|
|
||||||
line_error_decoded = line_error.decode()
|
line_error_decoded = line_error.decode()
|
||||||
|
|
||||||
logging.info(f"Datenpaket {obj.file_name}: {line_error_decoded}")
|
logging.info(f"Data ffmpeg: {line_error_decoded}")
|
||||||
obj.extract_convert_data(line_error_decoded)
|
obj.extract_convert_data(line_error_decoded)
|
||||||
|
|
||||||
json_data = json.dumps(obj.to_dict())
|
|
||||||
|
|
||||||
# Verwende den Event-Loop, um die Daten in die asyncio Queue zu legen
|
# Verwende den Event-Loop, um die Daten in die asyncio Queue zu legen
|
||||||
loop.run_until_complete(qu.put(json_data))
|
logging.info(f"Data Packet created: {obj.to_dict()}")
|
||||||
|
loop.run_until_complete(qu.put(obj.to_dict()))
|
||||||
|
|
||||||
|
|
||||||
@app.post("/")
|
@app.post("/")
|
||||||
async def receive_video_file(data: dict):
|
async def receive_video_file(data: dict):
|
||||||
|
|
@ -244,6 +242,8 @@ 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:
|
||||||
while True:
|
while True:
|
||||||
message = await queue.get() # Warten auf neue Nachricht aus der Queue
|
message = await queue.get() # Warten auf neue Nachricht aus der Queue
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
@ -11,7 +12,7 @@ class Video:
|
||||||
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 = int(video_streams[0].get("r_frame_rate", "0/0").split("/")[0])
|
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.output_file = f"{path.rsplit(".", 1)[0]}.webm"
|
self.output_file = f"{path.rsplit(".", 1)[0]}.webm"
|
||||||
|
|
@ -86,7 +87,7 @@ class Video:
|
||||||
self.time_deque.append(self.time)
|
self.time_deque.append(self.time)
|
||||||
self.time_estimated = self.duration - time_estimated
|
self.time_estimated = self.duration - time_estimated
|
||||||
|
|
||||||
return {
|
data_packet = {
|
||||||
"source": os.path.basename(self.source_file),
|
"source": os.path.basename(self.source_file),
|
||||||
"target": os.path.basename(self.output_file),
|
"target": os.path.basename(self.output_file),
|
||||||
"path": os.path.dirname(self.source_file),
|
"path": os.path.dirname(self.source_file),
|
||||||
|
|
@ -105,6 +106,11 @@ class Video:
|
||||||
"time_remaining": self.time_remaining
|
"time_remaining": self.time_remaining
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return json.dumps({"data_flow":data_packet})
|
||||||
|
|
||||||
|
def get_vars(self):
|
||||||
|
return json.dumps({"obj_list":vars(self)})
|
||||||
|
|
||||||
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)
|
||||||
self.frame = int(frame[0]) if frame else 0
|
self.frame = int(frame[0]) if frame else 0
|
||||||
|
|
@ -120,7 +126,7 @@ class Video:
|
||||||
|
|
||||||
time = re.findall(r"time=\s*(\d+:\d+:\d+)", line_decoded)
|
time = re.findall(r"time=\s*(\d+:\d+:\d+)", line_decoded)
|
||||||
time_v = time[0] if time else "00:00:00"
|
time_v = time[0] if time else "00:00:00"
|
||||||
self.time_in_sec(time_v)
|
self.time = self.time_in_sec(time_v)
|
||||||
|
|
||||||
bitrate = re.findall(r"bitrate=\s*(\d+)", line_decoded)
|
bitrate = re.findall(r"bitrate=\s*(\d+)", line_decoded)
|
||||||
self.bitrate = self.convert_kb_mb(bitrate[0]) if bitrate else 0
|
self.bitrate = self.convert_kb_mb(bitrate[0]) if bitrate else 0
|
||||||
|
|
@ -160,6 +166,16 @@ class Video:
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def frame_rate(video_streams):
|
||||||
|
var_frame_rate = video_streams[0].get("r_frame_rate", "0/0").split("/")
|
||||||
|
if int(var_frame_rate[1]) > 0:
|
||||||
|
int_frame_rate = int(var_frame_rate[0]) / int(var_frame_rate[1])
|
||||||
|
else:
|
||||||
|
int_frame_rate = 0
|
||||||
|
|
||||||
|
return int_frame_rate
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def format_time(seconds):
|
def format_time(seconds):
|
||||||
# Berechne die Anzahl der Tage, Stunden, Minuten und Sekunden
|
# Berechne die Anzahl der Tage, Stunden, Minuten und Sekunden
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,28 @@ let videoQueue = {}; // Hier speichern wir alle laufenden Videos
|
||||||
|
|
||||||
ws.onmessage = function(event) {
|
ws.onmessage = function(event) {
|
||||||
try {
|
try {
|
||||||
let message = JSON.parse(event.data);
|
let packet = JSON.parse(event.data);
|
||||||
|
console.log(packet);
|
||||||
|
|
||||||
// Falls das Video noch nicht existiert, erstelle ein neues Element
|
if (packet.data_flow !== undefined) {
|
||||||
if (!videoQueue[message.id]) {
|
let message = packet.data_flow;
|
||||||
videoQueue[message.id] = createVideoElement(message.id, message.source, message.target, message.path);
|
console.log(message);
|
||||||
|
|
||||||
|
// Überprüfen, ob die erwarteten Felder existieren
|
||||||
|
if (message.id && message.source && message.target && message.path) {
|
||||||
|
// Falls das Video noch nicht existiert, erstelle ein neues Element
|
||||||
|
if (!videoQueue[message.id]) {
|
||||||
|
videoQueue[message.id] = createVideoElement(message.id, message.source, message.target, message.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update der UI
|
||||||
|
updateVideoElement(message.id, message);
|
||||||
|
} else {
|
||||||
|
console.error("Fehlende Felder in der Nachricht", message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error("Kein data_flow in der empfangenen Nachricht", packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update der UI
|
|
||||||
updateVideoElement(message.id, message);
|
|
||||||
} 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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue