Show video transition and generation progress in separate views

This commit is contained in:
Mikei386
2026-09-29 13:46:05 +02:00
parent e851b2f3ea
commit 0ec51bcf6d
5 changed files with 78 additions and 21 deletions
+8 -4
View File
@@ -17,12 +17,12 @@ class Video:
def __init__(self,root,profiles,runtime,scheduler,stop_owned):
self.root=Path(root);self.profiles=profiles;self.runtime=runtime;self.scheduler=scheduler;self.stop_owned=stop_owned
self.lock=threading.RLock();self.mode='llm';self.state='idle';self.error=None;self.process=None;self.profile=None;self.job=None;self.thread=None;self.gpu=None
self.closing=False;self.selected=None
self.switch_phase=None;self.switch_started_at=None;self.target_mode=None;self.closing=False;self.selected=None
if (self.root/'selection.json').exists():self.selected=json.loads((self.root/'selection.json').read_text()).get('profile_id')
def status(self):
with self.lock:
if self.process and self.process.poll() is not None and self.state=='ready':self.state='failed';self.error='Video-Worker beendet; RAM-OOM oder Laufzeitfehler möglich.'
return dict(mode=self.mode,state=self.state,error=self.error,profile_name=self.profile['name'] if self.profile else None,profile_id=self.selected,loaded_profile_id=self.profile['id'] if self.profile else None,gpu=self.gpu,job=dict(self.job) if self.job else None,runtime=self.runtime.status(),memory_policy='Disk-Streaming auf RTX 5080; beide GPUs exklusiv reserviert. Gewichte werden bedarfsgerecht geladen.')
return dict(target_mode=self.target_mode,switch_phase=self.switch_phase,switch_started_at=self.switch_started_at,mode=self.mode,state=self.state,error=self.error,profile_name=self.profile['name'] if self.profile else None,profile_id=self.selected,loaded_profile_id=self.profile['id'] if self.profile else None,gpu=self.gpu,job=dict(self.job) if self.job else None,runtime=self.runtime.status(),memory_policy='Disk-Streaming auf RTX 5080; beide GPUs exklusiv reserviert. Gewichte werden bedarfsgerecht geladen.')
def blockers(self,p):
if not video_recipe(p.get('model') or {}):return ['Für diese Videovariante ist kein Worker angebunden.']
errors=[]
@@ -53,12 +53,13 @@ class Video:
if errors:raise ValueError(' '.join(errors))
# Close admission before stopping any process. Queued leases recheck this flag.
with self.scheduler.cv:self.scheduler.gpu_mode='switching';self.scheduler.cv.notify_all()
self.state='switching';self.error=None
self.state='switching';self.error=None;self.target_mode=mode;self.switch_started_at=time.time();self.switch_phase='Laufende Deck-Aufträge beenden'
self.thread=threading.Thread(target=self._switch,args=(mode,profile),daemon=True);self.thread.start()
return self.status()
def _switch(self,mode,profile):
try:
self.stop_owned();self.stop_process()
with self.lock:self.switch_phase='Auf Freigabe des GPU-Speichers warten'
deadline=time.monotonic()+60
with self.scheduler.cv:
while self.scheduler.active or self.scheduler.transition:
@@ -66,7 +67,9 @@ class Video:
self.scheduler.cv.wait(.2)
self.scheduler.key=None
if self.closing:raise ValueError('Deck wird beendet.')
if mode=='video':self.load(profile)
if mode=='video':
with self.lock:self.switch_phase='GPUs prüfen und Videoprofil vorbereiten'
self.load(profile)
if self.closing:raise ValueError('Deck wird beendet.')
with self.lock:self.mode=mode;self.state='ready' if mode=='video' else 'idle'
with self.scheduler.cv:self.scheduler.gpu_mode=mode;self.scheduler.cv.notify_all()
@@ -133,6 +136,7 @@ class Video:
p=subprocess.Popen([str(python),str(Path(__file__).with_name('video_worker.py'))],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.DEVNULL,bufsize=0,start_new_session=True,env=env)
with self.lock:self.process=p;self.gpu=gpu['uuid']
if self.closing:self.stop_process();raise ValueError('Deck wird beendet.')
with self.lock:self.switch_phase='Video-Worker laden und Komponenten prüfen'
p.stdin.write((json.dumps(config)+'\n').encode());p.stdin.flush();result=self.read(p,180)
if result.get('state')!='ready':raise ValueError(result.get('error','Video-Profil nicht bereit.'))
with self.lock:self.profile=profile