
    \j.              
          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d9dZd Z d Z!d Z"d Z#d:dZ$d  Z%d! Z&e'd"k    r e             \  Z(Z)Z*e+                    d#d#$            e"e(e)e*          Z,d%e,d&<   e-                     ej.        e,d'd()          d*z   d+,           e,d-         D ]Z/e/0                    d&          d.k    r e#e/          r' e$e/           e-                     ej.        e,d'd()          d*z   d+,            e1 ej.        e/d/         e/d&         e/0                    d0          d1d'2          d#3            e%e,            e&e,e*          Z2d.e,d&<    ej3        ej4                  5                                e,d4<    e6e7                    e                    e,d5<    e6e7                    e                    e,d6<   e-                     ej.        e,d'd()          d*z   d+,            e1 ej.        d.e2d7         e2d0         d8d'2                     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À-ỹĐđ]+\bc                 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   prober.   &   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_paragraphrA   4   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}|rw|rMt          d                    |                    dk     r'|dxx         dd                    |          z   z  cc<   n(|                    d                    |                     |S )Nc                 ^    g | ]*}|                                 |                                 +S  )r3   ).0items     r   
<listcomp>zchunk_text.<locals>.<listcomp>X   s-    VVV4V$**,,VVVr   z\n\s*\nr      z

i  )r1   r2   r4   r5   extendrA   r6   )r'   	min_charsr8   
paragraphsunitsr7   r:   r;   sizeunitr>   s              r   
chunk_textrR   W   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 0 	0c&++g..//#552JJJ&6;;w#7#777JJJJMM&++g..///Mr   c                  d   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
          d|                    d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 authorityi 5  total_wordsr   i@8  z+Promoted word count is outside target rangestory_promoted_ready_for_ttscanon_sha256z.Production plan is not unlocked for this canon)STORY	PROMOTIONPLANexistsRuntimeErrorr$   r+   	read_textget
read_bytesr   decode)r   	promotionstory_bytes
canon_hashplans        r   require_promoted_storyrk   w   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IMM-33<<<<u<<<<HIII: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   rT   zsegment-04dz.wavpending)indexr'   text_sha256wordsoutputrX   r[   
doc_truyen1.0true)stylespeeddenoise)	versionrX   sourcesource_canon_sha256source_wordsendpointrequestr:   
created_at)rR   rb   	enumerater5   r   encoder4   WORD_REfindallr*   SEGMENTSrelative_toPROJECTr^   ENDPOINTr   nowr   utc	isoformat)r'   rg   ri   r:   rowsro   chunks          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 )	NrT   rU   r{   z3Existing TTS manifest belongs to another canon hashFrJ   ensure_asciiindent
)
MANIFESTra   r$   r+   rc   rd   rb   r   
write_textdumps)r'   rg   ri   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)Nrr   i   Fstreamsformatdurationr   r   
codec_name	pcm_s16leduration_secondsbytesfile_sha256	completedrX   )r   ra   statst_sizer.   rd   floatr4   r   re   	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   c           	      |   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        t*          dd          dz   d           ||k     rt-          j        d|z             Y d }~Yd }~ww xY wt          d| d          d|           )Nrr   Tparentsexist_okr   r'   rs   rt   ru   )r'   rv   rw   rx   i  )r   timeouts   RIFFz#TTS response is not a RIFF/WAV filez	.wav.partz(Rendered WAV failed ffprobe verificationattemptsretryingfailedrX   r#   FrJ   r   r   rT   rU   zSegment ro   z	 failed: )r   parentmkdirrangerequestspostr   raise_for_statuscontent
startswithrb   with_suffixwrite_bytesreplacer   r   r*   r   r   r$   r   r   timesleep)r   max_attemptsr   
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 A7F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:   rr   zfile ''z'\''r   rT   rU   Tr   ffmpegz-hide_bannerz	-loglevelr#   z-yz-fconcatz-safe0z-iz-ccopy)r%   z-c:a
libmp3lamez-b:a192k)r   resolver5   r*   r   r   r6   
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                    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 }d||t	          d | d         D                       t          | d                   |t          |dz  d          |t          ||z
  d          t          t          
                    t                              t          t          
                    t                              t          t                    |t          j        t           j                                                  d}t&          j                            dd           t&                              t/          j        |dd          dz   d           |st3          d          |S )Nr   r   r   c              3   @   K   | ]}t          |d                    V  dS )r   N)r   rG   r   s     r   	<genexpr>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 rX   r   Nrd   r   s     r   r   z!verify_outputs.<locals>.<genexpr>  s3      KKCGGH,KKKKKKr   r   r   r   r   sample_rate48000g?rC   i.  c              3   H   K   | ]}|                     d           dk    V  dS r   r   r   s     r   r   z!verify_outputs.<locals>.<genexpr>  s3      !a!as#''("3"3{"B!a!a!a!a!a!ar   <   r      )ry   rW   r{   segments_completedsegments_totalr   duration_minutessegment_duration_sumduration_delta_seconds
output_wav
output_mp3
wav_sha256r.   
checked_atTr   FrJ   r   r   rT   rU   zFinal TTS verification failed)r.   r   rd   r   sumallr4   absroundr*   r   r   r   r    r   r   r   r   r   RECEIPTr   r   r   r$   r   rb   )r   ri   	wav_prober   r   segment_durationrW   receipts           r   verify_outputsr      sF   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////<////  )!!a!ahW_N`!a!a!aaahx011$!(R-33 0"'3C(CQ"G"G*0099::*0099::!*--l8<00::<< G  N555tz'aHHH4OZabbb <:;;;Nr   __main__Tr   runningrX   FrJ   r   r   rT   rU   r:   r   ro   r   )segmentrX   r   )r   )flushcompleted_atr   r   rW   )rX   rW   r   )rB   rC   )r   )8r   r$   r1   r(   sysr   r   r   pathlibr   r   __file__r   r   r   r^   r_   r`   r   r   r   r   r   r   compileUNICODEr   r   r    r.   rA   rR   rk   r   r   r   r   r   r   __name__r'   rg   ri   r   r   r   r   r   rd   printr   r   r   r   r*   r   rF   r   r   <module>r      s     				     



  ' ' ' ' ' ' ' '       
$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   @> > >&  6    .!G !G !G !GH  $! ! !H z"8"8":":D)ZNN4$N///&&tY
CCH"HX

8%JJJTQ\cddd! W W778++0G0G0L0L+sJDJxeANNNQUU`ghhhjdjS\S]X[X_X_`rXsXstt  DI  J  J  J  RV  	W  	W  	W  	W  	WKnXz22G$HX+x|HL99CCEEH^ S!7!7!@!@AAH\ S!7!7!@!@AAH\

8%JJJTQ\cddd	E*$*9Lbij|b}~~  NS  T  T  T  U  U  U  U  U' r   