
    )i$                        d dl mZ d dlZd dlZd dlZd dlZd dlmZmZm	Z	m
Z
 d dlZd dlZd dlmZmZmZmZmZ d dlmZ d dlmZ d dl d dlmZ d d	lmZ dd
Z e         ej<                  dd      Z ej@                  d      	 	 	 	 	 	 	 	 	 ddede!de"de	e!   de
e"e"f   de
e"e"f   de"de"de#de	e!   de$de!fd       Z%y)    )PathN)DictListOptionalTuple)	ImageClipAudioFileClipVideoFileClipCompositeVideoClipconcatenate_videoclips)	ColorClip)AudioArrayClip)*)load_dotenv)celeryc                    	 t         j                  j                  |      st        d|       t         j                  j                  |      st        d|       t	        |d      t	        |d      d}t        d       t        j                  |  |      }|j                  dk(  rN|r@t	        |d      5 }|j                  |j                         d	d	d	       t        d
|        |S t        d       yt        d|j                   d|j                          y	# 1 sw Y   KxY w# t        $ r}t        d|        Y d	}~y	d	}~ww xY w)a  
    Sends video and audio to your Flask Wav2Lip API.
    Downloads the generated output video to output_path (if provided).

    Args:
        api_url (str): Base URL of the running Flask API (e.g. "http://127.0.0.1:5001")
        video_path (str): Path to input face video file.
        audio_path (str): Path to input audio file.
        output_path (str, optional): Path to save returned lip-synced video.

    Returns:
        str: Local path to saved output video or None if failed.
    zVideo file not found: zAudio file not found: rb)videoaudioz&[INFO] Sending request to Flask API...)files   wbNz"[DONE] Lip-synced video saved to: z9[DONE] Lip-synced video received (no save path provided).Successz[ERROR] API returned status z: z[ERROR] API call failed: )ospathexistsFileNotFoundErroropenprintrequestspoststatus_codewritecontenttext	Exception)api_url
video_path
audio_pathoutput_pathr   responsefes           6C:\xampp\htdocs\eduruby\Video_generation\Video_sync.pygenerate_lip_sync_via_apir/      s.   ww~~j)#&<ZL$IJJww~~j)#&<ZL$IJJ *d+*d+

 	67==G9U;3&+t,GGH,,- -:;-HI""QR 01E1E0FbXY -,  )!-.s<   B3D' 5DD' )D' 5%D' D$ D' '	E0EEPOPPLER_PATHzVideo_generation.video_sync)namedataavatar_pathdpipoppler_path
resolutionavatar_sizeavatar_marginfpsrender_segments_to_disktmp_dirtitle_slide_durationreturnc                    t        j                  dd      }|	r0t        |	      t        | d         z  }|j	                  dd       d}nt        t        j                               }d}| j                  d      }| j                  d      }t        |dd	
      5 }t        j                  |      }ddd       t        d| d    d      }|j                  j	                  dd       g g }}	 t        d       t        |t        |      ||      }|st        d      t        dt        |       d       t!              }t#        |t$              st'        d      t        |      j)                         st+        d|z         |\  }}|\  }}t        |      }t-        d|dz         D ]  }||dz
     }|dk(  rPd}|
}t/        j0                  t3        ||z        dft.        j4                        } t7        | |      }!t        d       n|j                  |dz
        }"|"rIt        |"      j)                         r0t9        |"      }!t        d| dt        |"      j:                          nSd}|
}t/        j0                  t3        ||z        dft.        j4                        } t7        | |      }!t        d| d       |j=                  |!       |!j>                  }tA        t        |            jC                  |      }#|#jD                  |#jF                  z  ||z  kD  r|#jI                  |      n|#jI                  |      }#|#jD                  |#jF                  }%}$||$z
  d z  ||%z
  d z  }'}&tK        ||fd!"      jC                  |      }(tM        |(|#jO                  |&|'f      g      jQ                  |!      })|dk(  r"|)jC                  |      jS                  |      }*nt        |d#| d$z        }+tU        ||"|+%      },|,rt        d&|        nt        d'| d(       |,r|+n|}-tW        |-||)      }.tY        ||f      }/|/jZ                  d*k(  r|/d+   }/|/j]                  d,      d-z  }/tA        |/d.      jC                  |      jI                  |/      }0|.j_                  |0      }.||z
  |z
  ||z
  |z
  }2}1|.jO                  |1|2f      }.tM        |)|.g||f0      jC                  |      jS                  |      }*|d1z  }3|3j	                  dd       t        |3d2|d3d$z        }4t        d4|4        |*ja                  |4d5d6|d7tc        d8t        jd                         xs d      9       |j=                  |4       |*jg                           t        d:       ti        |D 5cg c]  }5tk        |5       c}5d;<      }6t        d=|        |6ja                  t        |      d5d6|tc        d8t        jd                         xs d      >       |6jg                          t        d?|       t        |      |r4|j)                         r#	 tm        jn                  |       t        d@|       S S S # 1 sw Y   xY wc c}5w # tp        $ r}7t        dA|7       Y d}7~7S d}7~7ww xY w# |rV|j)                         rE	 tm        jn                  |       t        d@|       w # tp        $ r}7t        dA|7       Y d}7~7w d}7~7ww xY ww w xY w)BzO
    Generate final video with slides + audio mapping + lip-synced avatar.
    LIPSYNC_API_URLz'https://eduruby.in/lip-sync/api/lipsyncidT)parentsexist_okpdf_pathaudio_mapping_filerzutf-8)encodingNz./public/Video/z_final_video.mp4z([STEP] Converting PDF pages to images...)r4   r5   z'No images produced from PDF conversion.z[INFO] Produced z pagesz<audio_map must be a dict mapping page numbers to audio pathszAvatar video not found:    iD  )dtype)r9   z![INFO] Page 1: silent title slidez[INFO] Page u   : mapped audio found → z[WARN] Page z$: no audio mapping, inserted silence)width)height   )   rL   rL   )sizecolorlip_avatar_page_z.mp4)r'   r(   r)   r*   z$[INFO] Lip-sync successful for page z [WARN] Lip-sync failed for page z, using original avatar)durationr7      ).r   float32g     o@)ismask)newsize)rM   segmentspage_03dz"[INFO] Rendering segment to disk: libx264aacF   )codecaudio_codecr9   verbosethreadsz [STEP] Concatenating segments...compose)methodz[STEP] Writing final video: )r[   r\   r9   r^   z[DONE] Final video:z [CLEANUP] Removed temporary dir:z [WARN] Failed to remove tmp dir:)9r   getenvr   strmkdirtempfilemkdtempgetr   jsonloadparentr   pdf_to_imagesRuntimeErrorlenload_audio_map
isinstancedict
ValueErrorr   r   rangenpzerosintrR   r   r	   r1   appendrP   r   set_durationwhresizer   r   set_pos	set_audioset_fpsr/   make_avatar_clip_for_durationcreate_circle_mask_arrayndimastypeset_maskwrite_videofilemin	cpu_countcloser   r
   shutilrmtreer&   )8r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r'   tmpdirtmp_createdrC   audio_map_pathr,   audio_map_sourcer*   audio_clips	seg_filespage_images	audio_mapWHawah	num_pagespage_noimg_pathsrrP   
silent_arr
audio_clipr)   slide_img_clipimg_wimg_hx_posy_posbgslide_segmentcomposedsynced_avatar_outsync_successavatar_final_pathavatar_clipmask_arr	mask_clippos_xpos_yseg_dirseg_outpfinalr-   s8                                                           r.   pdf_audio_map_to_videor   I   s   " ii)+TUGgT$Z0TD1h&&()xx
#HXX23N	ncG	499Q< 
5 d4DEFKTD9KK=89#Hc&ksQ]^HII [!1 2&9:"#34	)T*[\\K '')#$>$LMM1B$	Q	A.G"7Q;/H !|/XXs2='91&=RZZP
+JB?
9;&]]7Q;7
$z"2"9"9";!.z!:JL	1J4PZK[K`K`JabcB3H!#3rH}+=q*A!TJ!/
!CJL	1UVWz*!**H 's8}5BB8LN #$$~'7'77AEB %%A%.#**!*4 
 *++^-=-=5EI!+a%iA-=5EAo>KKHUB.^++UEN;<i
# 
 !|(55h?GGL %(3CG9D1Q(Q$R!8#*) 1	   @	JK<WIE\]^)5%; " <%k 4RH===A%'/H$OOI6>ht4!\(+VKV0 
 *229= 2v5q2v7Mu)115%.A-"K01v,x( 
 z)GMM$M6'eGC=$==>G6wi@A$$!A 3!5 %  W%NN /D 	01&'01y!]1y1)
 	,[M:;BLLN/a1 	 	
 	#[1; 6==?=f%8&A +;] 
5	4| 2(  =8!<<=	 6==?=f%8&A =8!<<=	 +;sn   Y*R*Z Y&&A<Z 5!Y+Y#&Z +	Z
4ZZ
['!![['	["[['[""[')N)	   N)i   i  )   r         Tz./public/tmpg      @)&pathlibr   r   rg   rd   r   typingr   r   r   r   r    numpyrr   moviepy.editorr   r	   r
   r   r   moviepy.video.VideoClipr   moviepy.audio.AudioClipr   Video_generation.helpersdotenvr   
celery_appr   r/   ra   r5   taskrb   rt   boolfloatr        r.   <module>r      s1    	    . .    . 2 &  -^ ryy. /0 "&"-#-$(+"%o=
o=o= 
o= 3-	o=
 c3ho= sCxo= o= 
o= "o= c]o=  o= 	o= 1o=r   