
    m<j+                     F   d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dlmZ d dl	m
Z
 d dlZd dlZ ee                                          j        Zedz  Zedz  Z e
              e j        d          Z e j        d	d
          Z e j        dd          Z e j        dd          Z e j        dd          Z e e j        dd                    Z e j        dd          ZdefdZd ZdeddfdZdefdZ d Z!d Z"d Z#d Z$d  Z%d! Z&e'd"k    r e&             dS dS )#    N)Path)datetime)Document)load_dotenvinputoutputHF_TOKENAUTOPROTOCOL_WHISPER_MODELzlarge-v3AUTOPROTOCOL_WHISPER_DEVICEcuda!AUTOPROTOCOL_WHISPER_COMPUTE_TYPEfloat16*AUTOPROTOCOL_WHISPER_FALLBACK_COMPUTE_TYPEint8_float16AUTOPROTOCOL_WHISPER_BATCH_SIZE2AUTOPROTOCOL_WHISPER_LANGUAGEdereturnc                  ^    t          j        d          pt          } | st          d          | S )z?Return the HuggingFace token or raise a web-app friendly error.r	   ur   HF_TOKEN fehlt. Bitte in der lokalen .env setzen; ohne Token kann WhisperX keine Sprecher-Diarisierung ausführen.)osgetenvr	   RuntimeError)tokens    autoprotocol.pyrequire_hf_tokenr   &   s=    Ij!!-XE 
 A
 
 	
 L    c                  r    t          j        t          d           t          j        t          d           dS )z7Stellt sicher, dass die Input/Output-Ordner existieren.T)exist_okN)r   makedirs	INPUT_DIR
OUTPUT_DIR r   r   setup_directoriesr$   /   s2    K	D))))K
T******r   labelc                    t           j                                        st          d|  d           dS t           j                                        \  }}||z
  }d}t          d|  d||z  dd||z  dd||z  dd		           dS )
zBPrint a compact VRAM snapshot without failing on CPU-only systems.z	[*] VRAM u   : CUDA nicht verfügbar.Ni   z: used=z.0fz MiB, free=z MiB, total=z MiB)torchr   is_availableprintmem_get_info)r%   freetotalusedmibs        r   log_cuda_memoryr/   5   s    :""$$ 9%999:::*))++KD%4<D
C		BE 	B 	B$*8 	B 	Bs
A	B 	B,1CKA	B 	B 	B    r   devicec           	      t   t          dt           d|  dt           d           	 t          j        t          | t                    t          fS # t
          j        j        $ r | dk    st          t          k    r t          dt           d           t          j
                     t
          j                                         t
          j                                        rt
          j                                         t          d	           t          j        t          | t                    t          fcY S w xY w)
zSLoad the configured WhisperX model; on CUDA OOM retry with lower VRAM compute type.z[*] Lade WhisperX-Modell 'z' auf z mit compute_type=...)compute_typer   uU   [!] CUDA VRAM war für den primären Lauf zu knapp. Versuche erneut mit compute_type=z, ohne Chatterbox zu stoppen.znach OOM cleanup)r)   WHISPER_MODELWHISPER_COMPUTE_TYPEwhisperx
load_modelr'   r   OutOfMemoryErrorWHISPER_FALLBACK_COMPUTE_TYPEgccollectempty_cacher(   ipc_collectr/   )r0   s    r   !load_whisperx_model_with_fallbackr>   C   sg   		C] 	C 	C	C 	C)=	C 	C 	C  E"=&G[\\\^rrr:& E E EV<@TTT*0M* * *	
 	
 	

 	

   :""$$ 	%J""$$$*+++"=&Gdeee  hE  E  	E  	E  	EEs   'A C'D76D7c                  P   t          j         t          j                            t          d                    } d | D             }|st          d           dS t          d           t          |          D ]<\  }}t          j                            |          }t          d|dz    d|            =	 t          t          d	                    dz
  }d
|cxk    rt          |          k     rn n||         S t          d           dS # t          $ r t          d           Y dS w xY w)uM   Listet alle Medien-Dateien im Input-Ordner auf und lässt den Nutzer wählen.z*.*c                 `    g | ]+}|                                                     d           )|,S ))z.mp4z.movz.m4vz.mkvz.aviz.webm.mp3.m4a.aac.ogg.oga.flac.wav)lowerendswith).0fs     r   
<listcomp>z)list_and_select_files.<locals>.<listcomp>]   sN       7799  I  J  J	  r   z>[!] Keine Audio- oder Videodateien im 'input'-Ordner gefunden.Nu,   
--- Verfügbare Dateien im Input-Ordner ---[   z] u;   
Bitte wähle die Nummer der Datei für die Transkription: r   u   [!] Ungültige Auswahl.z[!] Bitte eine Zahl eingeben.)globr   pathjoinr!   r)   	enumeratebasenameintr   len
ValueError)filesmedia_filesi	file_pathfilename	selections         r   list_and_select_filesr]   Z   s]   Ibgll9e4455E   K
  NOOOt	
9:::!+.. ' '97##I..%!a%%%8%%&&&&	\]]^^abb		,,,,C,,,,,,,y))+,,,4   -...tts   3AD 7D D%$D%c           
         t           j                            |           }t           j                            |          \  }}|                                dv r| S t           j                            t          | d          }t          d| d           ddd| dd	d
dd|g
}t          j	        |t          j
        t          j
                   |S )uQ   Extrahiert die Audiospur aus einem Video via ffmpeg für schnellere Verarbeitung.)rG   rA   rB   rC   rD   rE   rF   z_extracted.wavz
[*] Extrahiere Audio aus r2   ffmpegz-yz-iz-vnz-ar16000z-ac1)stdoutstderr)r   rP   rS   splitextrH   rQ   r!   r)   
subprocessrunDEVNULL)
media_pathr[   nameext
audio_pathcommands         r   extract_audiorm   v   s    w
++H  **ID# yy{{OOOiD)@)@)@AAJ	
5
5
5
5666 tZwsT^_GN7:#5j>PQQQQr   c           	      0   ddl m}m} t          dt          j                            |                       t          dt           dt           dt           d           t          }|dk    r/t          j                                        st          d	           d
}t          d           t          |          \  }}t          d| d           t!          j        |           }|                    |t          t                    }t          d|d                     ~t'          j                     t          j                                        r<t          j                                         t          j                                         t          d           t          d           t!          j        |d         |          \  }}	t!          j        |d         ||	||d          }~t'          j                     t          j                                        r<t          j                                         t          j                                         t          d           t          d           t3                      }
 ||
|          } ||           }~t'          j                     t          j                                        r<t          j                                         t          j                                         t          d           t          d            |||          }g }|d         D ]X}|                    dd          }|                    dd                                          }|                    ||d           Y|S ) u   
    Führt WhisperX lokal auf der GPU aus:
    1. Transkription (Schweizerdeutsch -> Hochdeutsch)
    2. Alignment (Zeitsynchronisation)
    3. Diarisierung (Sprechererkennung)
    r   )DiarizationPipelineassign_word_speakersu.   
[*] Starte KI-Transkription (WhisperX) für: uD   [*] AutoProtocol-STT läuft getrennt von Hermes Telegram-STT: model=z, language=z, batch_size=.r   u5   [!] CUDA ist nicht verfügbar; falle auf CPU zurück.cpuzvor WhisperX loadz$[*] WhisperX aktiv mit compute_type=)
batch_sizelanguagez7[*] Transkription abgeschlossen. Festgesetzte Sprache: rt   z nach Transkriptionsmodell unloadu:   [*] Führe Alignment durch (Text-Audio-Synchronisation)...)language_coder0   segmentsF)return_char_alignmentsznach Alignment unloadz.[*] Starte Sprechererkennung (Diarisierung)...)r   r0   znach Diarization unloadu(   [*] Führe Text und Sprecher zusammen...speaker	UNBEKANNTtext )rx   rz   )whisperx.diarizero   rp   r)   r   rP   rS   r4   WHISPER_LANGUAGEWHISPER_BATCH_SIZEWHISPER_DEVICEr'   r   r(   r/   r>   r6   
load_audio
transcriber:   r;   r<   r=   load_align_modelalignr   getstripappend)rk   ro   rp   r0   modelactive_compute_typeaudioresultmodel_ametadatar   diarize_modeldiarize_segmentsformatted_resultsegmentrx   rz   s                    r   run_whisperxr      s    KJJJJJJJ	
ZBG<L<LZ<X<X
Z
Z[[[		,	, 	,+;	, 	,(	, 	, 	,   F
 7 7 9 9EFFF'((( "C6!J!JE	
G1D
G
G
GHHH
++E e0BM]^^F	
XF:DV
X
XYYY 	JLLLz   !
   
   6777 

FGGG 1z@R[abbbGX^F:.5&inoooF 	JLLLz   !
   
   +,,, 

:;;;E''eFCCCM$}Z00JLLLz   !
   
   -... 

4555!!"2F;;F *% D D++i55{{62&&,,..GT B BCCCCr   c                    t          d           t                      }|                    dd           t          j                    }|                    d          }|                    d          }|                    d|            |                    dt          j        	                    |                      |                    d           | D ]V}|                                }|
                    |d	          d
          }d|_        |
                    |d                    Wd| d}	t          j                            t          |	          }
|                    |
           t          d|
 d           |
S )z@Speichert das fertige Transkript als formatiertes Word-Dokument.z
[*] Erstelle Word-Dokument...Sitzungstranskriptr   z%d.%m.%Y %H:%Mz%Y%m%d_%H%MzDatum der Erstellung: zQuelle: z2--------------------------------------------------rx   z: Trz   Transkript_z.docxz*[+] ERFOLG! Transkript gespeichert unter: 
)r)   r   add_headingr   nowstrftimeadd_paragraphr   rP   rS   add_runboldrQ   r"   save)transcription_dataoriginal_filenamedocr   date_strfile_date_strr   prunneroutput_filenameoutput_paths              r   export_to_wordr      sr   	
+,,,
**COO(!,,,
,..C||,--HLL//M9x99:::F!1!12C!D!DFFGGGh% # #gi044455			'&/""""8M888O',,z?;;KHH[	
F{
F
F
FGGGr   c                 ^   t                       t          |           }t          |          }t          d           ddl}ddl} |j                     |j                                         dt          j
        d<   |j                                        r|j                                         |S )z:Diese Funktion wird unsichtbar vom Streamlit-UI aufgerufenz4[*] Zwinge PyTorch, den VRAM komplett freizugeben...r   Nzexpandable_segments:TruePYTORCH_CUDA_ALLOC_CONF)r$   rm   r   r)   r:   r'   r;   r   r<   r   environr(   r=   )rZ   
audio_filer   r:   r'   s        r   process_directr      s    y))J &j11 

@AAAIIILLLBJLLL	J,FBJ() z   !
    r   c                      t                       t                      } | sd S t          |           }t          |          }t	          ||            d S )N)r$   r]   rm   r   r   )selected_filer   r   s      r   mainr     s^    )++M  }--J &j11 %}55555r   __main__)(r   rO   re   r:   pathlibr   r   docxr   dotenvr   r'   r6   __file__resolveparentBASE_DIRr!   r"   r   r	   r4   r   r5   r9   rT   r~   r}   strr   r$   r/   r>   r]   rm   r   r   r   r   __name__r#   r   r   <module>r      sO   				      				                          
 4>>!!##*w	 
 29Z   	6
CC8&AA ry!DiPP  )	*VXf g g S#DcJJKK 29<dCC #    + + +3 4    Ec E E E E.  8  $Q Q Qf  6  26 6 6  zDFFFFF r   