
    mj$                       d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	 ddl
mZ ddlZddZ e       ZdZd	Zd
ZdZddZdd dZd!dZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d"dZ	 	 	 	 d#	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d$dZedf	 	 	 d%dZedk(  r~ddlZddlZddlZ eej<                        dkD  rej<                  d   nddddgZ ee ej@                         jB                  dd  e	 ejD                               d      Z# e$de#       yy)&u  
Geração de B-roll via IA usando Seedance-1-Pro (ByteDance) no Replicate.

API: https://replicate.com/bytedance/seedance-1-pro
Custo aproximado: US$0.05/segundo @ 1080p, ~US$0.025/segundo @ 720p

Uso típico (substitui Pexels):
    clips = gerar_videos_seedance(
        termos=[{"query": "...", "inicio": 0.0, "fim": 5.0}, ...],
        job_id="abc",
        temp_dir=Path("/tmp/temp"),
        resolution="720p",
    )
    # clips => [{"path": "/tmp/...mp4", "inicio": 0.0, "fim": 5.0}, ...]
    )annotationsN)ThreadPoolExecutoras_completed)Path)Iterablec                 N   t        j                  dd      j                         } | r| S t        d      }|j	                         r	 |j                  d      j                         D ]  }|j                         }|r|j                  d      r'd|vr,|j                  dd      \  }}|j                         dk(  sU|j                         j                  d	      j                  d
      }|t         j                  d<   |c S  	 yy# t        $ r}t        d|        Y d }~yd }~ww xY w)NREPLICATE_API_TOKEN z/opt/mia/.envzutf-8)encoding#=   "'z%[seedance] erro lendo /opt/mia/.env: )osgetenvstripr   exists	read_text
splitlines
startswithsplitenviron	Exceptionprint)tokenv_pathlinekves         9/opt/mia/workspace/video_editor/backend/seedance_utils.py_load_replicate_tokenr#       s   
)))2
.
4
4
6C

O$H	? **G*<GGI 
zz|ts3d?zz#q)1779 55	,2237A89BJJ45H
   	?9!=>>	?s&   A4D :AD ?D 	D$DD$zbytedance/seedance-1-pro         c                X    | xs dj                         j                  d      }|sy| dS )z
    Recebe a query curta vinda do Claude (ex: "person typing on laptop")
    e devolve um prompt rico otimizado para Seedance, vertical 9:16.
    r
   .z, cinematic vertical 9:16 composition, soft natural lighting, shallow depth of field, smooth slow camera movement, ultra-realistic, high detail photographic quality, 4k, professional color grading)r   rstrip)queryqs     r"   _enriquecer_promptr,   A   s?    
 
"$$S)A # K 	L    c                   	 t        j                  | d|      5 }|j                          |j                  j	                  dd       t        |d      5 }|j                  d      D ]  }|s|j                  |        	 ddd       ddd       |j                         xr |j                         j                  dkD  S # 1 sw Y   @xY w# 1 sw Y   DxY w# t        $ r}t        d	|  d
|        Y d}~yd}~ww xY w)z7Baixa um MP4 pra o caminho destino. Retorna True/False.T)streamtimeoutparentsexist_okwbi   )
chunk_sizeNr   z[seedance] erro baixando z: F)requestsgetraise_for_statusparentmkdiropeniter_contentwriter   statst_sizer   r   )urldestinor0   rfchunkr!   s          r"   _baixar_arquivorE   R   s    \\#dG< 	' NN   =gt$ '^^y^A 'E''	' ~~>GLLN$:$:Q$>>	' '	' 	'  )#b45sL   C :CC -C C	6C  C		CCC 	C<!C77C<c                p   | yt        | t              r| S t        | t        t        f      r| rt	        | d         S dD ]8  }t        | |d      }t        |      r
	  |       c S t        |t              s6|c S  	 t        |       }|j                  d      r|S 	 y# t        $ r Y gw xY w# t        $ r Y yw xY w)u   
    O Replicate Python client retorna:
    - str (URL) na maioria dos modelos novos
    - objeto FileOutput (com método .url) em alguns
    - list[str] em modelos multi-output
    Normaliza pra URL única.
    Nr   )r@   http)	
isinstancestrlisttuple_resolver_output_urlgetattrcallabler   r   )outputattrr    ss       r"   rL   rL   b   s     ~&#&4-(V#F1I.. FD$'A;s
 3HK<<H       s$   B:B) 	B&%B&)	B54B5c                   ddl }| j                  d      xs dj                         }|syt        |      }	t	        t
        t        t        t        t        | j                  dd            t        | j                  dd            z
              xs t        t                    }
t        j                         }t        d| d|
 d	| d
|       	 |j                  t        |	|
|||dd      }t!        |      }|st        d| d|       y|| d|ddz  }t#        ||      st        d| d|        yt        j                         |z
  }t        d| d|dd|        t%        |      t        | d         t        | d         ||
t        |d      dS # t        $ r}t        d| d| d|        Y d}~yd}~ww xY w)zk
    Gera UM clip via Seedance, baixa o MP4 e devolve dict do clip.
    Retorna None em caso de falha.
    r   Nr*   r
   fiminicioz[seedance] gerando clip z (zs, z): F)promptduration
resolutionaspect_ratiofpscamera_fixed)inputz&[seedance] erro chamando modelo (clip z, 'z'): z[seedance] clip z sem URL no output: 
_seedance_02dz.mp4z [seedance] falha ao baixar clip z de z OK em .1fzs -> r   )pathrT   rS   r*   duracao_geradatempo_geracao_s)	replicater7   r   r,   maxSEEDANCE_DUR_MINminintroundfloatSEEDANCE_DUR_DEFAULTtimer   run
MODEL_SLUGr   rL   rE   rI   )termoidxjob_idtemp_dirrW   rX   rY   rb   r*   rU   duracao_alvot0rO   r!   r@   destdurs                    r"   _gerar_um_clipru      s    YYw%2,,.E&F'E%		%+,uUYYx5K/LLMNfRf* L
 
B	$SEL>ZLE9
UV (( , %  

 v
&C %9&DE
3s)488D3%0T#?@
))+
C	SES	tf
=> D	h(U5\"& a= #  6se3ugT!MNs   F 	F=F88F=720pc                   | D cg c](  }|j                  d      xs dj                         s'|* } }| st        d       g S t        st        d       g S t        t        j
                  d<   t        |      }|j                  dd       t        j                         }t        dt        |        d	| d
|        g }	t        |      5 }
t        |       D ci c]"  \  }}|
j                  t        |||||||      |$ }}}t        |      D ]+  }||   }	 |j                         }|r|	j!                  |       - 	 ddd       |	j%                  d        t        j                         |z
  }t        |	      }t        |       |z
  }t        d| d| d|dd       |	S c c}w c c}}w # t"        $ r}t        d| d|        Y d}~d}~ww xY w# 1 sw Y   xY w)u;  
    Gera N clips em paralelo via Seedance-1-Pro.

    Args:
        termos: lista de {"query": str, "inicio": float, "fim": float}
        job_id: id do job (pra nomear arquivos)
        temp_dir: pasta destino dos MP4s
        resolution: "720p" (mais barato) ou "1080p"
        aspect_ratio: "9:16" pra Reels (default)
        fps: 24 ou 30
        max_workers: paralelismo (default 3 — Replicate aceita bem)

    Returns:
        list[dict] = [{"path", "inicio", "fim", "query", "duracao_gerada", "tempo_geracao_s"}, ...]
        Lista vazia se TODAS falharem.
    r*   r
   u)   [seedance] nenhum termo válido recebido.u;   [seedance] REPLICATE_API_TOKEN não configurado. Abortando.r	   Tr1   u"   [seedance] iniciando geração de z clip(s), workers=z, resolution=)max_workersz[seedance] worker z explodiu: Nc                    | d   S )NrT    )xs    r"   <lambda>z'gerar_videos_seedance.<locals>.<lambda>  s
    !H+ r-   )keyz[seedance] terminou: z OK, z falha(s) em r^   zs total)r7   r   r   REPLICATE_TOKENr   r   r   r:   rj   lenr   	enumeratesubmitru   r   resultappendr   sort)termosro   rp   rW   rX   rY   rx   tt_start
resultadospoolirm   futuresfutrB   r!   totalsucessofalhass                       r"   gerar_videos_seedancer      s   2  BAAEE'N$8b#?#?#AaBFB9:	KL	 )8BJJ$%H~HNN4$N/iikG	.s6{m < Mzl< = J		4 > &f-

 5	 KKq&(L# 
 
  ( 	>CA>JJL%%a(	>>$ OO-O.IIK'!E*oG[7"F	!'%x}U3Kw
WX[ C*
  >*1#[<==>> >sR   (F F 
G'F% G#F+:G%G+	G4G
G
GGG1080pc                8    |dk(  rdnd}t        | |z  |z  d      S )zZ
    Estimativa simples de custo do Replicate.
    1080p ~= $0.05/s, 720p ~= $0.025/s
    r   g?g?   )rg   )	qtd_clips	duracao_srW   preco_ss       r"   estimar_custo_usdr     s)     !G+dGY&0!44r-   __main__r   z$a photographer adjusting camera lensg        g      @)r*   rT   rS      )r   ro   rp   rW   z
RESULTADO:)returnrI   )r*   rI   r   rI   )x   )r@   rI   rA   r   r0   rf   r   bool)r   z
str | None)rm   dictrn   rf   ro   rI   rp   r   rW   rI   rX   rI   rY   rf   r   zdict | None)rv   z9:16   r$   )r   zIterable[dict]ro   rI   rp   r   rW   rI   rX   rI   rY   rf   rx   rf   r   rJ   )r   rf   r   rf   rW   rI   r   rh   )%__doc__
__future__r   r   rj   concurrent.futuresr   r   pathlibr   typingr   r6   r#   r~   rl   rd   SEEDANCE_DUR_MAXri   r,   rE   rL   ru   r   r   __name__systempfileuuidr   argvr   uuid4hex
gettempdiroutr   rz   r-   r"   <module>r      s    # 	  ?   . ()'
    " D@@	@ @ 	@
 @ @ 
@ @N FFF F 	F
 F 
F F 
FR 8L'.5!$5385 z #CHH 1!7] F
  tzz|#)h))+,	C 
, r-   