
    o]j02                        d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZmZ d dlm	Z	 d dl
Z
 e	e                                          j        d         Zedz  dz  Zedz  dz  Zedz  d	z  Zedz  d
z  Zedz  dz  Zedz  dz  Zedz  dz  Zedz  dz  ZdZ ej        dej                  ZdZd Zd Zd Zd Zd&dZ d Z!d Z"d Z#d Z$d'd!Z%d" Z&d# Z'd$ Z(e)d%k    r ej*         e(                       dS dS )(    N)datetimetimezone)Path   storyzspoken-narration.txtzpromotion-report.jsonscriptzproduction-plan.jsonztts-manifest.jsonaudiosegmentszstory-full.wavzstory-full.mp3logztts-verification.jsonz0http://192.168.40.32:7861/voice/ngoc-huyen-cloneu   \b[\wÀ-ỹĐđ]+\b   c                 N    t          j        |                                           S N)hashlibsha256	hexdigest)datas    script/render-tts.pysha256_bytesr      s    >$))+++    c                    t          j                    }|                     d          5 t          fdd          D ]}|                    |           	 d d d            n# 1 swxY w Y   |                                S )Nrbc                  .                          d          S )Ni   )read)handles   r   <lambda>zsha256_file.<locals>.<lambda>"   s    &++o">"> r   r   )r   r   openiterupdater   )pathdigestblockr   s      @r   sha256_filer"      s    ^F	4 !F>>>>DD 	! 	!EMM%    	!! ! ! ! ! ! ! ! ! ! ! ! ! ! ! s   ,A##A'*A'c                     t          j        dddddddddt          |           g
d	d	d	
          }t          j        |j                  S )Nffprobez-verrorz-show_entrieszformat=duration,sizez,stream=index,codec_name,sample_rate,channelsz-ofjsonT)checkcapture_outputtext)
subprocessrunstrr&   loadsstdout)r   results     r   prober0   '   sY    ^tWo"O:E63t99	

 	 	 	F :fm$$$r   c                    t          j        d|                                           }g }g }d}|D ].}|                                }|st          |          |rdndz   }|r5||z   |k    r,|                    d                    |                     g }d}t          |          |k    rt          j        d|          }|D ]}	|	                                }	|	st          |	          |rdndz   }|r5||z   |k    r,|                    d                    |                     g }d}|                    |	           ||z  }|                    |           ||z  }0|r(|                    d                    |                     |S )Nu   (?<=[.!?…])\s+r   r    z(?<=[,;:])\s+)resplitstriplenappendjoin)
	paragraph	max_chars	sentenceschunkscurrentcurrent_lensentenceextraclausesclauses
             r   split_long_paragraphrC   5   s   ,ioo.?.?@@IFGK ! !>>## 	Hg!415 	{U*Y66MM#((7++,,,GKx==9$$h/::G! 
% 
% FG':qq; ${U2Y>>MM#((7"3"3444 G"#Kv&&&u$
% NN8$$$5 KK )chhw''(((Mr     `	  c                    d t          j        d|           D             }g }|D ]N}t          |          k    r|                    |           +|                    t          |                     Og }g }d}|D ]}	t          |	          |rdndz   }
|r5||
z   k    r,|                    d                    |                     g }d}|                    |	           ||
z  }||k    r,|                    d                    |                     g }d}|rd                    |          }|rSt          |          dk     r@t          |d                   dz   t          |          z   k    r|dxx         d|z   z  cc<   n|                    |           t          fd|D                       rt          d	          |S )
Nc                 ^    g | ]*}|                                 |                                 +S  )r5   ).0items     r   
<listcomp>zchunk_text.<locals>.<listcomp>Y   s-    VVV4V$**,,VVVr   z\n\s*\nr      z

i  c              3   >   K   | ]}t          |          k    V  d S r   )r6   )rI   chunkr:   s     r   	<genexpr>zchunk_text.<locals>.<genexpr>v   s.      
6
6e3u::	!
6
6
6
6
6
6r   z/Chunker exceeded max_chars after tail balancing)	r3   r4   r6   r7   extendrC   r8   anyRuntimeError)r)   	min_charsr:   
paragraphsunitsr9   r<   r=   sizeunitr@   tails     `         r   
chunk_textrZ   X   s   VV28J+E+EVVVJE E E	y>>Y&&LL####LL-iCCDDDDFGD  D		'0QQq1 	te|i//MM&++g..///GDt9MM&++g..///GD  {{7## 	 c$ii#oo#fRj//A*=D		*IY*V*V2JJJ&4-'JJJJMM$

6
6
6
6v
6
6
666 NLMMMMr   c                     t           t          t          fD ](} |                                 st	          d|            )t          j        t                              d                    }|                    d          dus|                    d          dk    rt	          d          t           	                                }t          |          }|                    d	          |k    rt	          d
          t          |                    dd                    }d|cxk    rdk    sn t	          d          |t          z  }d|cxk    rdk    sn t	          d          t          j        t                              d                    }|                    d          dk    s|                    d          |k    rt	          d          |                    d          ||fS )NzRequired authority missing: utf-8encodingverifiedTstatuspassedz+Story is not promoted; TTS spend is blockedspoken_sha256z*Story hash differs from promoted authoritytotal_wordsr   i 5  i@8  z+Promoted word count is outside target range(   <   zCFixed 231 words/minute duration prediction is outside 40-60 minutesstory_promoted_ready_for_ttscanon_sha256z.Production plan is not unlocked for this canon)STORY	PROMOTIONPLANexistsrS   r&   r-   	read_textget
read_bytesr   intTTS_WORDS_PER_MINUTEdecode)r   	promotionstory_bytes
canon_hashrc   predicted_minutesplans          r   require_promoted_storyrw   {   s   	4( F F{{}} 	FDdDDEEE	F
9...@@AAI}}Z  ,,	h0G0G80S0SHIII""$$Kk**J}}_%%33GHHHimmM15566KK((((5((((HIII#&::"((((b((((`aaa:dnngn6677Dxx;;;txx?W?W[e?e?eKLLLg&&	:==r   c                 ~   t          |           }|st          d          g }t          |d          D ]\  }}|                    ||t	          |                    d                    t          t                              |                    t          t          d|ddz                      t                              dd           ddt          t                              t                              ||d	         t          d
ddd|t          j        t"          j                                                  d	S )NzChunker produced no TTS workr   r\   zsegment-04dz.wavpending)indexr)   text_sha256wordsoutputr`   rc   
doc_truyen1.0true)stylespeeddenoise)	versionr`   sourcesource_canon_sha256source_wordsendpointrequestr<   
created_at)rZ   rS   	enumerater7   r   encoder6   WORD_REfindallr,   SEGMENTSrelative_toPROJECTrh   ENDPOINTr   nowr   utc	isoformat)r)   rr   rt   r<   rowsr{   rO   s          r   build_manifestr      s:   F ;9:::D!&!,,  u'W(=(=>>//008&@&@&@&@&@@MMgVVWW
 
 	 	 	 	 e''0011)!-0)EfMMl8<00::<<
 
 
r   c                 p   t                                           rWt          j        t                               d                    }|                    d          |k    rt          d          |S t          | ||          }t                               t          j	        |dd          dz   d           |S )	Nr\   r]   r   z3Existing TTS manifest belongs to another canon hashFrL   ensure_asciiindent
)
MANIFESTrk   r&   r-   rl   rm   rS   r   
write_textdumps)r)   rr   rt   manifests       r   load_or_create_manifestr      s     :h00'0BBCC<<-..*<<TUUUdIz::H
8%JJJTQ\cdddOr   c                 8   t           | d         z  }|                                r|                                j        dk     rdS 	 t	          |          }|                    dg           }t          |d         d                   }t          |          dk    o$|d                             d	          d
k    o|dk    }|rJ|| d<   |                                j        | d<   t          |	                                          | d<   d| d<   |S # t          $ r Y dS w xY w)Nr~   i   Fstreamsformatdurationr   r   
codec_name	pcm_s16leduration_secondsbytesfile_sha256	completedr`   )r   rk   statst_sizer0   rm   floatr6   r   rn   	Exception)rowr   r   r   r   valids         r   verify_existing_segmentr      s$   S]"D;;== DIIKK/$66uT{{((9b))h
344LLA 
|,,;1 	
  	(&.C"#99;;.CL!-doo.?.?!@!@C'CM   uus   CD 
DD   Tc           	      v   t           | d         z  }|j                            dd           d }t          d|dz             D ]\}	 t	          j        t          | d         dddd	d
          }|                                 |j        	                    d          st          d          |                    d          }|                    |j                   |                    |           t          |           st          d          || d<    d S # t          $ r}	t!          |	          }||k     rdnd| d<   || d<   t"                              t'          j        |dd          dz   d           ||k     r|rt+          j        d|z             Y d }	~	Vd }	~	ww xY wt          d| d          d|           )Nr~   Tparentsexist_okr   r)   r   r   r   )r)   r   r   r   i  )r   timeouts   RIFFz#TTS response is not a RIFF/WAV filez	.wav.partz(Rendered WAV failed ffprobe verificationattemptsretryingfailedr`   r%   FrL   r   r   r\   r]   zSegment r{   z	 failed: )r   parentmkdirrangerequestspostr   raise_for_statuscontent
startswithrS   with_suffixwrite_bytesreplacer   r   r,   r   r   r&   r   timesleep)
r   r   max_attemptsretry_sleepr   
last_errorattemptresponsetempexcs
             r   render_segmentr      s   S]"DKdT222JL1,-- ) )	)}K)"%	  	 	 	H %%'''#..w77 J"#HIII##K00DX-...LL*3// O"#MNNN%C
OFF 	) 	) 	)SJ*1L*@*@JJhCM%CL
8%PQ R R RUY Ydklll%%+%
1<(((	) E#g,EEEE
F
FFs   CD
FA4FFc                    t           dz  dz  }g }| d         D ]`}t           |d         z                                  }|                    dt          |                              dd          z   dz              a|                    d                    |          dz   d	
           t          j        	                    dd           t          j        ddddddddddt          |          ddt          t                    gd           t          j        ddddddt          t                    ddddt          t                    gd           d S )Nr   ztts-concat.txtr<   r~   zfile ''z'\''r   r\   r]   Tr   ffmpegz-hide_bannerz	-loglevelr%   z-yz-fconcatz-safe0z-iz-ccopy)r'   z-c:a
libmp3lamez-b:a192k)r   resolver7   r,   r   r   r8   
OUTPUT_WAVr   r   r*   r+   
OUTPUT_MP3)r   concat_filelinesr   r   s        r   concatenater      s   H$'77KE! G G#h-'0022XD		 1 1#w ? ??#EFFFF499U++d2WEEED4888N	>;tXwX[]acfgrcscsuy  |B  DG  HR  DS  DS  	T    N	>;tS__V\^jlrtz|  AK  }L  }L  	M     r   c           	      f   t          t                    }|                    dg           }t          |d         d                   }t	          d | d         D                       }t          d | d         D                       ovt          |          dk    oc|d                             d	          d
k    oD|d                             d          dk    o%t          ||z
            dk     od|cxk    odk    nc }i ddd|d|dt	          d | d         D                       dt          | d                   dt          dt          t	          d | d         D                       t          z  d          d|dt          |dz  d          d|dt          ||z
  d          d t          t                              t                              d!t          t                              t                              d"t          t                    d#|d$t          j        t"          j                                                  }t(          j                            d%d%&           t(                              t1          j        |d'd()          d*z   d+,           |st5          d-          |S ).Nr   r   r   c              3   @   K   | ]}t          |d                    V  dS )r   N)r   rI   r   s     r   rP   z!verify_outputs.<locals>.<genexpr>	  s0      XXc5%7!899XXXXXXr   r<   c              3   H   K   | ]}|                     d           dk    V  dS r`   r   Nrm   r   s     r   rP   z!verify_outputs.<locals>.<genexpr>  s3      KKCGGH,KKKKKKr   r   r   r   r   sample_rate48000g?rE   i.  r   r_   r   segments_completedc              3   H   K   | ]}|                     d           dk    V  dS r   r   r   s     r   rP   z!verify_outputs.<locals>.<genexpr>  s3      !a!as#''("3"3{"B!a!a!a!a!a!ar   segments_totaltts_words_per_minutepredicted_duration_minutesc              3   &   K   | ]}|d          V  dS )r}   NrH   r   s     r   rP   z!verify_outputs.<locals>.<genexpr>  s&      /[/[G/[/[/[/[/[/[r   r   r   duration_minutesre   segment_duration_sumduration_delta_seconds   
output_wav
output_mp3
wav_sha256r0   
checked_atTr   FrL   r   r   r\   r]   zFinal TTS verification failed)r0   r   rm   r   sumallr6   absrp   roundr,   r   r   r   r"   r   r   r   r   r   RECEIPTr   r   r   r&   r   rS   )r   rt   	wav_prober   r   segment_durationr_   receipts           r   verify_outputsr     s   j!!ImmIr**GYx(455HXXXhEWXXXXXKK8JKKKKK 	0LLA	0AJNN<((K7	0 AJNN=))W4	0 ++,,s2		0
 x////<//// 1H 	z 	c!a!ahW_N`!a!a!aaa	
 	#hx011 	 4 	%eC/[/[QYHZ/[/[/[,[,[^r,rtu&v&v 	H 	E(R-33 	 0 	!%3C(CQ"G"G 	c*0099:: 	c*0099:: 	k*-- 	  	hl8<00::<<!G$ N555tz'aHHH4OZabbb <:;;;Nr   c            
         	 t                      \  } }}t                              dd           t          | ||          }d|d<   t                              t          j        |dd          dz   d	
           |d         D ]}|                    d          dk    rt          |          r+t          ||           t                              t          j        |dd          dz   d	
           t          t          j        |d         |d         |                    d          dd          d           t          |           t          ||          }d|d<   t          j        t           j                                                  |d<   t'          t(                              t,                              |d<   t'          t.                              t,                              |d<   t                              t          j        |dd          dz   d	
           t          t          j        d|d         |d         dd                     dS # t0          $ r)}t          d| t2          j                   Y d }~dS d }~ww xY w)NTr   runningr`   FrL   r   r   r\   r]   r<   r   r{   r   )segmentr`   r   )r   )flushcompleted_atr   r   r_   )r`   r_   r   r   zTTS blocked: )filer   )rw   r   r   r   r   r   r&   r   rm   r   r   printr   r   r   r   r   r   r   r,   r   r   r   r   r   sysstderr)r)   rr   rt   r   r   r   r   s          r   mainr  +  s   &<&>&>#itd333*4JGG&DJxeANNNQUU`ghhhH% 	[ 	[Cwwx  K//4KC4P4P/3)))
8%PQ R R RUY Ydklll$*WX\_\c\cdv\w\wxx  HM  N  N  N  VZ  [  [  [  [  [H :66(#+<#=#=#G#G#I#I !$Z%;%;G%D%D!E!E!$Z%;%;G%D%D!E!EDJxeANNNQUU`ghhhdjKWZ=Pfm  oA  gB  C  C  RW  X  X  X  	Y  	Y  	Yq   #c###*5555qqqqqs   II 
J"JJ__main__)rD   rE   )r   T)+r   r&   r3   r*   r  r   r   r   pathlibr   r   __file__r   r   r   rh   ri   rj   r   r   r   r   r   r   compileUNICODEr   rp   r   r"   r0   rC   rZ   rw   r   r   r   r   r   r   r  __name__exitrH   r   r   <module>r     s9     				     



  ' ' ' ' ' ' ' '       
$x..
 
 
"
"
*1
-'22g 77	22X 33Wz)w!11
w!11

E/3
3=
"*+RZ
8
8 , , ,  % % %     F       F> > >.  6    .!G !G !G !GH  $# # #L  6 zCHTTVV r   