§
    ‚Njþ5  ã                   ó|  — d dl Z d dlZd dlmZmZ d dlmZm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d dlmZ d d	lmZ d d
lmZ d dlZd dlZ ej        ej        ¬¦  «          ej        e¦  «        Zdeee f         fd„Z!d\  Z"Z# G d„ d¦  «        Z$d„ Z%edk    r e j&         e%¦   «         ¦  «         dS dS )é    N)ÚdatetimeÚtimezone)ÚSessionLocalÚengine)ÚProcessingJob)ÚStream)Úsettings)Úpublish_event©ÚSession)Útext)ÚVideoProcessor)ÚlevelÚreturnc                  óh  — 	 t          j        ddgddd¬¦  «        } d| j        v rt                               d¦  «         dS n# t           j        t          f$ r Y nw xY w	 t          j        ddgddd¬¦  «        } d	| j        v rt                               d
¦  «         dS n# t           j        t          f$ r Y nw xY w	 t          j        ddgddd¬¦  «        } d| j        v rt                               d¦  «         dS n# t           j        t          f$ r Y nw xY wt                               d¦  «         dS )z3Check if GPU is available for hardware accelerationÚffmpegz	-encodersTé   )Úcapture_outputr   ÚtimeoutÚ
h264_nvenczNVIDIA NVENC GPU encoder found)Tr   Úh264_qsvz$Intel Quick Sync Video encoder found)Tr   Úh264_amfzAMD AMF encoder found)Tr   z(No GPU encoder found, using CPU encoding©FÚlibx264)Ú
subprocessÚrunÚstdoutÚloggerÚinfoÚTimeoutExpiredÚFileNotFoundError)Úresults    ú/app/app/daemon.pyÚcheck_gpu_availabler$      s©  € ðÝ”Ø�{Ð#ØØØð	
ñ 
ô 
ˆð ˜6œ=Ð(Ð(Ý�KŠKÐ8Ñ9Ô9Ð9Ø%Ð%ð )øõ Ô%Õ'8Ð9ð ð ð ØˆðøøøðÝ”Ø�{Ð#ØØØð	
ñ 
ô 
ˆð ˜œÐ&Ð&Ý�KŠKÐ>Ñ?Ô?Ð?Ø#Ð#ð 'øõ Ô%Õ'8Ð9ð ð ð ØˆðøøøðÝ”Ø�{Ð#ØØØð	
ñ 
ô 
ˆð ˜œÐ&Ð&Ý�KŠKÐ/Ñ0Ô0Ð0Ø#Ð#ð 'øõ Ô%Õ'8Ð9ð ð ð Øˆðøøøõ ‡K‚KÐ:Ñ;Ô;Ð;ØÐs5   ‚=A ÁAÁAÁ=B ÂB8Â7B8Â<=C< Ã<DÄDr   c                   ó„   — e Zd Zd„ Zd„ Zd„ Zd„ Zd„ Zdede	fd„Z
d	edede	fd
„Zd	edede	fd„Zd	edede	fd„Zd„ Zd„ ZdS )ÚStreamDaemonc                 ó   — d| _         d S )NF)Úrunning©Úselfs    r#   Ú__init__zStreamDaemon.__init__L   s   € ØˆŒˆˆó    c              ƒ   ó  K  — t                                d¦  «         d| _        |                      ¦   «         ƒ d {V —† |                      ¦   «         |                      ¦   «         |                      ¦   «         g}t          j        |Ž ƒ d {V —† d S )NzStarting StreamA2026 Daemon...T)	r   r   r(   Úresume_interrupted_jobsÚprocess_jobsÚhealth_checkÚcleanup_old_sessionsÚasyncioÚgather)r*   Útaskss     r#   ÚstartzStreamDaemon.startO   s£   è è € Ý�ŠÐ4Ñ5Ô5Ð5ØˆŒð ×*Ò*Ñ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,Ð,ð ×ÒÑÔØ×ÒÑÔØ×%Ò%Ñ'Ô'ð
ˆõ Œn˜eÐ$Ð$Ð$Ð$Ð$Ð$Ð$Ð$Ð$Ð$r,   c              ƒ   óL   K  — t                                d¦  «         d| _        d S )NzStopping StreamA2026 Daemon...F)r   r   r(   r)   s    r#   ÚstopzStreamDaemon.stop_   s$   è è € Ý�ŠÐ4Ñ5Ô5Ð5ØˆŒˆˆr,   c              ƒ   ó  ‡K  — 	 ddl m} ddl}ddl}t	          ¦   «         }	 |                     t          ¦  «                             t          j        dk    ¦  «         	                    ¦   «         }|D �].Št                               d‰j        › �¦  «         t          j        › d‰j        › �}|j                             |¦  «        rOd„  |j        |¦  «        D ¦   «         }t%          |¦  «        }t                               d|› d	‰j        › �¦  «         n$d}t                               d
‰j        › �¦  «         d‰j        › �}	d|dœ}
|                     |	|                     |
¦  «        ¦  «         ˆfd„}t+          j        |¬¦  «        }|                     ¦   «          �Œ0	 |                     ¦   «          dS # |                     ¦   «          w xY w# t2          $ r(}t                               d|› �¦  «         Y d}~dS d}~ww xY w)z5Check for interrupted processing jobs and resume themr   ©Úredis_clientNÚ
processingz&Found stuck processing job for stream z/hls/c                 ó<   — g | ]}|                      d ¦  «        ¯|‘ŒS )z.ts)Úendswith)Ú.0Úfs     r#   ú
<listcomp>z8StreamDaemon.resume_interrupted_jobs.<locals>.<listcomp>u   s*   € Ð(]Ð(]Ð(]¨qÈ1Ï:Ê:ÐV[ÑK\ÔK\Ð(]¨Ð(]Ð(]Ð(]r,   zFound z existing segments for stream z&No existing segments found for stream zprocessing_state:Úinterrupted)ÚstatusÚlast_successful_segmentc                  ó2  •— 	 t          ¦   «         } |                      t          ‰j        ¦  «        ¦  «         t                               d‰j        › �¦  «         d S # t          $ r0}t                               d‰j        › d|› �¦  «         Y d }~d S d }~ww xY w)Nz(Resumed processing completed for stream z%Resumed processing failed for stream ú: )r   Úprocess_videoÚstrÚidr   r   Ú	ExceptionÚerror)Ú	processorÚeÚstreams     €r#   Úprocess_in_backgroundzCStreamDaemon.resume_interrupted_jobs.<locals>.process_in_background„   s²   ø€ ðcÝ(6Ñ(8Ô(8˜IØ%×3Ò3µC¸¼	±N´NÑCÔCÐCÝ"ŸKšKÐ(^ÐSYÔS\Ð(^Ð(^Ñ_Ô_Ð_Ð_Ð_øÝ(ð cð cð cÝ"ŸLšLÐ)aÐQWÔQZÐ)aÐ)aÐ^_Ð)aÐ)aÑbÔbÐbÐbÐbÐbÐbÐbÐbøøøøðcøøøs   ƒAA Á
BÁ&%BÂB)Útargetz#Failed to resume interrupted jobs: )Úapp.redis_clientr:   ÚjsonÚosr   Úqueryr   ÚfilterrB   Úallr   r   rH   r	   ÚSTORAGE_PATHÚpathÚexistsÚlistdirÚlenÚsetÚdumpsÚ	threadingÚThreadr5   ÚcloserI   rJ   )r*   r:   rQ   rR   ÚdbÚstuck_streamsÚhls_dirÚsegment_filesÚcurrent_segmentsÚ	state_keyÚ
state_datarN   ÚthreadrL   rM   s                 @r#   r.   z$StreamDaemon.resume_interrupted_jobsc   sO  øè è € ð.	DØ5Ð5Ð5Ð5Ð5Ð5ØˆKˆKˆKØˆIˆIˆIå‘”ˆBð%à "§¢­Ñ 0Ô 0× 7Ò 7½¼ÈÒ8UÑ VÔ V× ZÒ ZÑ \Ô \�à+ð #ñ #�FÝ—K’KÐ TÈÌÐ TÐ TÑUÔUÐUõ "*Ô!6ÐHÐH¸V¼YÐHÐH�GØ”w—~’~ gÑ.Ô.ð ZØ(]Ð(]°J°B´J¸wÑ4GÔ4GÐ(]Ñ(]Ô(]˜Ý+.¨}Ñ+=Ô+=Ð(ÝŸšÐ$hÐ-=Ð$hÐ$hÐ]cÔ]fÐ$hÐ$hÑiÔiÐiÐià+,Ð(ÝŸšÐ$XÈVÌYÐ$XÐ$XÑYÔYÐYð !@°F´IÐ ?Ð ?�Ià"/Ø3Cð"ð "�Jð !×$Ò$ Y°·
²
¸:Ñ0FÔ0FÑGÔGÐGðcð cð cð cð cõ 'Ô-Ð5JÐKÑKÔK�FØ—L’L‘N”N�N‘Nð=#ðB —’‘
”
�
�
�
ø�—’‘
”
�
�
øøøøåð 	Dð 	Dð 	DÝ�LŠLÐB¸qÐBÐBÑCÔCÐCÐCÐCÐCÐCÐCÐCøøøøð	Døøøs/   …G ¢E?F8 Æ"G Æ8GÇG Ç
HÇG>Ç>Hc              ƒ   óH  K  — | j         �r	 t          ¦   «         }|                     t          ¦  «                             t          j        dk    ¦  «                             d¦  «                             ¦   «         }|D ]}|                      ||¦  «        ƒ d {V —† Œ| 	                    ¦   «          t          j        d¦  «        ƒ d {V —† nN# t          $ rA}t                               d|› �¦  «         t          j        d¦  «        ƒ d {V —† Y d }~nd }~ww xY w| j         �°d S d S )NÚpendingé   r   zError processing jobs: é
   )r(   r   rS   r   rT   rB   ÚlimitrU   Úprocess_jobr_   r2   ÚsleeprI   r   rJ   )r*   r`   ÚjobsÚjobrL   s        r#   r/   zStreamDaemon.process_jobs•   sY  è è € ØŒlñ 	(ð(Ý!‘^”^�Ø—x’x¥Ñ.Ô.×5Ò5Ý!Ô(¨IÒ5ñô ç’%˜‘(”(Ÿ3š3™5œ5ð ð  ð 4ð 4�CØ×*Ò*¨3°Ñ3Ô3Ð3Ð3Ð3Ð3Ð3Ð3Ð3Ð3à—’‘
”
�
Ý”m AÑ&Ô&Ð&Ð&Ð&Ð&Ð&Ð&Ð&Ð&øÝð (ð (ð (Ý—’Ð:°qÐ:Ð:Ñ;Ô;Ð;Ý”m BÑ'Ô'Ð'Ð'Ð'Ð'Ð'Ð'Ð'Ð'Ð'Ð'Ð'Ð'øøøøð(øøøð Œlñ 	(ð 	(ð 	(ð 	(ð 	(s   ŒB=C
 Ã

DÃ7DÄDrp   r`   c           	   ƒ   óä  K  — t                                d|j        › d|j        › �¦  «         d|_        t          j        t          j        ¦  «        |_	        d|_
        |                     ¦   «          |                     t          ¦  «                             t          j        |j        k    ¦  «                             ¦   «         }|r|j        sGd|_        d|_        t          j        t          j        ¦  «        |_        |                     ¦   «          d S 	 |j        dk    s|j        dk    r|                      |||¦  «        ƒ d {V —† nQ|j        d	k    r|                      |||¦  «        ƒ d {V —† n(|j        d
k    r|                      |||¦  «        ƒ d {V —† d|_        d|_
        t          j        t          j        ¦  «        |_        |                     ¦   «          t/          dt1          |j        ¦  «        t1          |j        ¦  «        |j        dœ¦  «         d S # t2          $ rÇ}t                                d|j        › d|› �¦  «         d|_        t1          |¦  «        |_        t          j        t          j        ¦  «        |_        |                     ¦   «          t/          dt1          |j        ¦  «        t1          |j        ¦  «        t1          |¦  «        dœ¦  «         Y d }~d S d }~ww xY w)NzProcessing job z for stream r;   r   ÚfailedzStream or file not foundÚhlsÚ	transcodeÚdashÚ	thumbnailÚ	completedéd   Újob_completed)Újob_idÚ	stream_idÚjob_typezError processing job rE   Ú
job_failed)rz   r{   rJ   )r   r   rH   r{   rB   r   Únowr   ÚutcÚ
started_atÚprogressÚcommitrS   r   rT   ÚfirstÚ	file_pathÚerror_messageÚcompleted_atr|   Úconvert_to_hlsÚconvert_to_dashÚgenerate_thumbnailr
   rG   rI   rJ   )r*   rp   r`   rM   rL   s        r#   rm   zStreamDaemon.process_job¦   sß  è è € Ý�ŠÐI c¤fÐIÐI¸#¼-ÐIÐIÑJÔJÐJð "ˆŒ
Ý!œ¥h¤lÑ3Ô3ˆŒØˆŒØ
�	Š	‰Œˆà—’�&Ñ!Ô!×(Ò(­¬°c´mÒ)CÑDÔD×JÒJÑLÔLˆØð 	˜VÔ-ð 	Ø!ˆCŒJØ :ˆCÔÝ'œ|­H¬LÑ9Ô9ˆCÔØ�IŠI‰KŒKˆKØˆFð	ØŒ|˜uÒ$Ð$¨¬¸Ò(CÐ(CØ×)Ò)¨&°#°rÑ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ð:Ð:Ø” Ò'Ð'Ø×*Ò*¨6°3¸Ñ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ø” Ò,Ð,Ø×-Ò-¨f°c¸2Ñ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>à$ˆCŒJØˆCŒLÝ'œ|­H¬LÑ9Ô9ˆCÔØ�IŠI‰KŒKˆKõ ˜/Ý˜cœf™+œ+Ý  ¤™^œ^ØœLð,ð ,ñ ô ð ð ð øõ ð 	ð 	ð 	Ý�LŠLÐ>°´Ð>Ð>¸1Ð>Ð>Ñ?Ô?Ð?Ø!ˆCŒJÝ # A¡¤ˆCÔÝ'œ|­H¬LÑ9Ô9ˆCÔØ�IŠI‰KŒKˆKå˜,Ý˜cœf™+œ+Ý  ¤™^œ^Ý˜Q™œð)ð )ñ ô ð ð ð ð ð ð ð øøøøð	øøøs   ÄDH È
K/È(B<K*Ë*K/rM   c              ƒ   ó.  K  — t           j                             t          j        d|j        › �¦  «        }t          j        |d¬¦  «         t           j                             |d¦  «        }t          rt          nd}t          rt           
                    d|› �¦  «         dd|j        d	|d
dddddddd|g}t          r|dk    r|                     g d¢¦  «         t           
                    dd                     |¦  «        › �¦  «         t          j        |t          j        j        t          j        j        dœŽƒ d {V —†}|                     ¦   «         ƒ d {V —†\  }	}
|j        dk    ri||_        d|_        d|_        d|_        d |_        d |_        d |_        |                     ¦   «          t           
                    d|j        › �¦  «         d S |
r|
                     ¦   «         nd}t                               d|› �¦  «         t;          d|› �¦  «        ‚)NÚhls_T©Úexist_okzplaylist.m3u8r   zUsing GPU encoder: r   ú-iú-c:vú-c:aÚaacú-frs   z	-hls_timeÚ2z-hls_playlist_typeÚvodú-yr   )ú-presetÚp6ú-tuneÚllú-rcÚvbrú-b:vÚ5Mz-maxrateÚ10Mz-bufsizeÚ20MzRunning FFmpeg command: Ú ©r   Ústderrr   Úreadyz$HLS conversion completed for stream úUnknown errorzFFmpeg conversion failed: )rR   rW   Újoinr	   ÚFFMPEG_CACHE_PATHrH   ÚmakedirsÚGPU_AVAILABLEÚGPU_ENCODERr   r   r„   Úextendr2   Úcreate_subprocess_execr   ÚPIPEÚcommunicateÚ
returncodeÚhls_pathrB   Úthumbnail_progress_generatedÚthumbnail_progress_totalÚthumbnail_progress_messageÚthumbnail_progress_errorÚthumbnail_progress_updated_atr‚   ÚdecoderJ   rI   ©r*   rM   rp   r`   Ú
output_dirÚoutput_pathÚvideo_encoderÚcmdÚprocessr   r¢   Ú	error_msgs               r#   r‡   zStreamDaemon.convert_to_hlsØ   s;  è è € Ý”W—\’\¥(Ô"<Ð>PÀVÄYÐ>PÐ>PÑQÔQˆ
Ý
Œ�J¨Ð.Ñ.Ô.Ð.å”g—l’l :¨Ñ?Ô?ˆõ (5ÐC�˜¸)ˆÝð 	?Ý�KŠKÐ=¨mÐ=Ð=Ñ>Ô>Ð>ð Ø�&Ô"Ø�MØ�EØ�%Ø˜Ø  %ØØð

ˆõ ð 	{˜]¨lÒ:Ð:Ø�JŠJÐyÐyÐyÑzÔzÐzå�ŠÐ>¨s¯xªx¸©}¬}Ð>Ð>Ñ?Ô?Ð?åÔ6ØÝÔ%Ô*ÝÔ%Ô*ð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ˆð  '×2Ò2Ñ4Ô4Ð4Ð4Ð4Ð4Ð4Ð4‰ˆ�àÔ Ò"Ð"Ø)ˆFŒOØ#ˆFŒMØ23ˆFÔ/Ø./ˆFÔ+Ø04ˆFÔ-Ø.2ˆFÔ+Ø37ˆFÔ0Ø�IŠI‰KŒKˆKÝ�KŠKÐJ¸v¼yÐJÐJÑKÔKÐKÐKÐKà+1ÐF˜Ÿš™œ˜°ˆIÝ�LŠLÐA°iÐAÐAÑBÔBÐBÝÐD¸ÐDÐDÑEÔEÐEr,   c           
   ƒ   óª  K  — t           j                             t          j        d|j        › �¦  «        }t          j        |d¬¦  «         t           j                             |d¦  «        }t          rt          nd}dd|j	        d|d	d
dd|g
}t          r|dk    r| 
                    g d¢¦  «         t          j        |t          j        j        t          j        j        dœŽƒ d {V —†}|                     ¦   «         ƒ d {V —†\  }	}
|j        dk    r||_        |                     ¦   «          d S |
r|
                     ¦   «         nd}t)          d|› �¦  «        ‚)NÚdash_TrŒ   zmanifest.mpdr   r   rŽ   r�   r�   r‘   r’   ru   r   )r–   r—   r˜   r™   rš   r›   rœ   r�   r¡   r   r¤   zFFmpeg DASH conversion failed: )rR   rW   r¥   r	   r¦   rH   r§   r¨   r©   r„   rª   r2   r«   r   r¬   r­   r®   Ú	dash_pathr‚   rµ   rI   r¶   s               r#   rˆ   zStreamDaemon.convert_to_dash  s~  è è € Ý”W—\’\¥(Ô"<Ð>QÀfÄiÐ>QÐ>QÑRÔRˆ
Ý
Œ�J¨Ð.Ñ.Ô.Ð.å”g—l’l :¨~Ñ>Ô>ˆõ (5ÐC�˜¸)ˆð Ø�&Ô"Ø�MØ�EØ�&Øð
ˆõ ð 	U˜]¨lÒ:Ð:Ø�JŠJÐSÐSÐSÑTÔTÐTåÔ6ØÝÔ%Ô*ÝÔ%Ô*ð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ˆð  '×2Ò2Ñ4Ô4Ð4Ð4Ð4Ð4Ð4Ð4‰ˆ�àÔ Ò"Ð"Ø*ˆFÔØ�IŠI‰KŒKˆKˆKˆKà+1ÐF˜Ÿš™œ˜°ˆIÝÐI¸iÐIÐIÑJÔJÐJr,   c           	   ƒ   ó  K  — t          j        t          j        d¬¦  «         t           j                             t          j        d|j        › d�¦  «        }dd|j        ddd	d
d|g	}t          j	        |t          j
        j        t          j
        j        dœŽƒ d {V —†}|                     ¦   «         ƒ d {V —†\  }}|j        dk    r||_        |                     ¦   «          d S |r|                     ¦   «         nd}	t#          d|	› �¦  «        ‚)NTrŒ   Úthumb_z.jpgr   rŽ   z-ssz00:00:01z-vframesÚ1r•   r¡   r   r¤   zThumbnail generation failed: )rR   r§   r	   rV   rW   r¥   rH   r„   r2   r«   r   r¬   r­   r®   Úthumbnail_urlr‚   rµ   rI   )
r*   rM   rp   r`   r¸   rº   r»   r   r¢   r¼   s
             r#   r‰   zStreamDaemon.generate_thumbnail1  s1  è è € Ý
Œ•HÔ)°DÐ9Ñ9Ô9Ð9å”g—l’l¥8Ô#8Ð:RÀ6Ä9Ð:RÐ:RÐ:RÑSÔSˆð Ø�&Ô"Ø�:Ø˜ØØð
ˆõ  Ô6ØÝÔ%Ô*ÝÔ%Ô*ð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ˆð  '×2Ò2Ñ4Ô4Ð4Ð4Ð4Ð4Ð4Ð4‰ˆ�àÔ Ò"Ð"Ø#.ˆFÔ Ø�IŠI‰KŒKˆKˆKˆKà+1ÐF˜Ÿš™œ˜°ˆIÝÐG¸IÐGÐGÑHÔHÐHr,   c              ƒ   óH  K  — | j         �r	 t          ¦   «         }	 |                     t          d¦  «        ¦  «         |                     ¦   «          n# |                     ¦   «          w xY wddlm} |                     ¦   «          t           	                    d¦  «         t          dddi¦  «         nT# t          $ rG}t                               d|› �¦  «         t          dd	t          |¦  «        d
œ¦  «         Y d }~nd }~ww xY wt          j        d¦  «        ƒ d {V —† d S d S )NzSELECT 1r   r9   zHealth check passedr0   rB   ÚhealthyzHealth check failed: Ú	unhealthy)rB   rJ   é   )r(   r   Úexecuter   r_   rP   r:   Úpingr   Údebugr
   rI   rJ   rG   r2   rn   )r*   r`   r:   rL   s       r#   r0   zStreamDaemon.health_checkN  sO  è è € ØŒlñ 	ðXå!‘^”^�ðØ—J’J�t JÑ/Ô/Ñ0Ô0Ð0à—H’H‘J”J�J�Jø�B—H’H‘J”J�J�Jøøøð :Ð9Ð9Ð9Ð9Ð9Ø×!Ò!Ñ#Ô#Ð#å—’Ð2Ñ3Ô3Ð3Ý˜n¨x¸Ð.CÑDÔDÐDÐDøåð Xð Xð XÝ—’Ð8°QÐ8Ð8Ñ9Ô9Ð9Ý˜n¸ÍsÐSTÉvÌvÐ.VÐ.VÑWÔWÐWÐWÐWÐWÐWÐWøøøøðXøøøõ ”- Ñ#Ô#Ð#Ð#Ð#Ð#Ð#Ð#Ð#ØˆEð+	ð 	s.   ŒB2 ›"A ½B2 ÁA(Á(A	B2 Â2
DÂ<=C>Ã>Dc              ƒ   óš  K  — | j         �r@	 ddlm} ddlm} t          ¦   «         }|                     |¦  «                             |j        t          j	        t          j        ¦  «        k     ¦  «                             ¦   «         }|D ]}|                     |¦  «         Œ|                     ¦   «          |                     ¦   «          t                                dt%          |¦  «        › d�¦  «         n4# t&          $ r'}t                                d|› �¦  «         Y d }~nd }~ww xY wt+          j        d¦  «        ƒ d {V —† | j         �°>d S d S )Nr   )Ú	timedeltar   zCleaned up z expired sessionszError cleaning up sessions: i  )r(   r   rÌ   Úapp.models.sessionr   r   rS   rT   Ú
expires_atr~   r   r   rU   Údeleter‚   r_   r   r   rZ   rI   rJ   r2   rn   )r*   rÌ   ÚSessionModelr`   ÚexpiredÚsessionrL   s          r#   r1   z!StreamDaemon.cleanup_old_sessionsf  s  è è € ØŒlñ 	&ðAØ.Ð.Ð.Ð.Ð.Ð.ØFÐFÐFÐFÐFÐFå!‘^”^�ØŸ(š( <Ñ0Ô0×7Ò7Ø Ô+­h¬l½8¼<Ñ.HÔ.HÒHñô ç’#‘%”%ð ð  'ð 'ð '�GØ—I’I˜gÑ&Ô&Ð&Ð&à—	’	‘”�Ø—’‘
”
�
å—’ÐI­#¨g©,¬,ÐIÐIÐIÑJÔJÐJÐJøåð Að Að AÝ—’Ð?¸AÐ?Ð?Ñ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@øøøøðAøøøõ ”- Ñ%Ô%Ð%Ð%Ð%Ð%Ð%Ð%Ð%ð+ Œlñ 	&ð 	&ð 	&ð 	&ð 	&s   ŒC&C3 Ã3
D$Ã=DÄD$N)Ú__name__Ú
__module__Ú__qualname__r+   r5   r7   r.   r/   r   r   rm   r   r‡   rˆ   r‰   r0   r1   © r,   r#   r&   r&   K   s6  € € € € € ðð ð ð%ð %ð %ð ð ð ð0Dð 0Dð 0Dðd(ð (ð (ð"0 ]ð 0¸ð 0ð 0ð 0ð 0ðd2F¨6ð 2F¸ð 2FÈ7ð 2Fð 2Fð 2Fð 2Fðh#K¨Fð #K¸ð #KÈGð #Kð #Kð #Kð #KðJI¨vð I¸Mð IÈwð Ið Ið Ið Ið:ð ð ð0&ð &ð &ð &ð &r,   r&   c               ƒ   ó²   K  — t          ¦   «         } 	 |                      ¦   «         ƒ d {V —† d S # t          $ r |                      ¦   «         ƒ d {V —† Y d S w xY w)N)r&   r5   ÚKeyboardInterruptr7   )Údaemons    r#   ÚmainrÚ     s~   è è € Ý‰^Œ^€FðØ�lŠl‰nŒnÐÐÐÐÐÐÐÐÐøÝð ð ð Ø�kŠk‰mŒmÐÐÐÐÐÐÐÐÐÐðøøøs   ’. ®$AÁAÚ__main__)'r2   Úloggingr   r   Úapp.databaser   r   Úapp.models.processing_jobr   Úapp.models.streamr   Ú
app.configr	   Úapp.sser
   r   rR   Úsqlalchemy.ormr   Ú
sqlalchemyr   Úapp.services.video_processorr   r]   ÚshutilÚbasicConfigÚ	LOG_LEVELÚ	getLoggerrÓ   r   ÚtupleÚboolrG   r$   r¨   r©   r&   rÚ   r   rÖ   r,   r#   ú<module>rë      s¾  ðØ €€€Ø €€€Ø 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ð 'Ø -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø $Ð $Ð $Ð $Ð $Ð $Ø Ð Ð Ð Ð Ð Ø !Ð !Ð !Ð !Ð !Ð !Ø Ð Ð Ð Ø 	€	€	€	Ø "Ð "Ð "Ð "Ð "Ð "Ø Ð Ð Ð Ð Ð Ø 7Ð 7Ð 7Ð 7Ð 7Ð 7Ø Ð Ð Ð Ø €€€à €Ô ˜(Ô,Ð -Ñ -Ô -Ð -Ø	ˆÔ	˜8Ñ	$Ô	$€ð-˜U 4¨ 9Ô-ð -ð -ð -ð -ðf .Ñ €ˆ{ðq&ð q&ð q&ð q&ð q&ñ q&ô q&ð q&ðh	ð ð ð ˆzÒÐØ€G„K��‘”ÑÔÐÐÐð Ðr,   