
    <jP,                        d Z ddlZddlZddlZddlmZ ddlZddlmZ ddl	m
Z
mZ ddlmZmZ ddlmZ dZ ej&                  d	d
      Z ee      j,                  dz  Z ee      j,                  dz  Z ee      j,                  dz  ZdZdZdedefdZdedefdZde fdZ!	 	 	 	 	 d!de de de dede"de de de de"de"de#fd Z$y)"u.   Pipeline principal de processamento de vídeo.    N)Path)transcrever_audio)buscar_videosbaixar_video)cortar_segmentosmontar_video_final)obter_musica_para_videozl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PEXELS_API_KEYPEXELS_API_KEY_PLACEHOLDERtempoutputmusicg      @   	segmentosreturnc                    | sg S g }| d   d   | d   d   | d   d   d}| dd D ]P  }|d   |d   z
  t         k  r|d   |d<   |dxx   d|d   z   z  cc<   1|j                  |       |d   |d   |d   d}R |j                  |       t        |      t        kD  r=t        |      t        z  }t	        t              D cg c]  }|t        ||z            }}|S c c}w )	z
    Agrupa segmentos do Whisper em janelas de ~JANELA_SEG segundos.
    Retorna [{"inicio": float, "fim": float, "texto": str}, ...].
    r   iniciofimtexto)r   r   r      N )
JANELA_SEGappendlenMAX_JANELASrangeint)r   janelasatualsegstepis         4/opt/mia/workspace/video_editor/backend/processor.py_construir_janelasr$      s
   
 	G |H-il56IT]^_T`ahTijE} XJx(Z7u:E%L'NcCL00NNN5!"8}SZ#g,WEX NN5 7|k!7|k)383EFa73q4x=)FFN Gs   =Ctranscricaoc                    | j                  dg       }t        |      }|sg S t        j                  t              }dj                  d t        |      D              }d| d}	 |j                  j                  ddd	|d
g      }|j                  d   j                  }t        j                  d|t        j                        }|st        d|dd         g S t        j                   |j#                               }	|	j                  dg       }
g }|
D ]  }	 t%        |j                  dd            dz
  }|j                  d      xs dj'                         }|dk  s|t)        |      k\  rY|r|j+                         dk(  ro||   }|j-                  t/        |d         t/        |d         |d        |S # t0        $ r Y w xY w# t0        $ r}t        d|        g cY d}~S d}~ww xY w)u   
    Para cada janela de ~7s da transcrição, gera uma query visual em inglês via Claude.
    Retorna lista alinhada: [{"inicio": float, "fim": float, "query": str}, ...].
    r   )api_key
c           	   3   t   K   | ]0  \  }}|d z    d|d   dd|d   dd|d   j                           2 yw)	r   z. [r   z.1fzs - r   zs] r   N)strip).0r"   js      r#   	<genexpr>z&analisar_para_broll.<locals>.<genexpr>G   sR      Aq Q3%s1X;s#4%~S79I9I9K8LMs   68u%  Você está ajudando a editar um Reel para Instagram. Para cada trecho de fala numerado abaixo, sugira UMA query de busca em inglês (3-5 palavras visuais concretas) para encontrar um vídeo no Pexels que ILUSTRE visualmente o conceito específico falado naquele trecho.

Regras:
- Sempre em inglês
- 3 a 5 palavras concretas e visuais (ex: "person typing laptop", "city skyline sunset", "team meeting office")
- NÃO repita a mesma query
- Se o trecho for muito genérico/conectivo (sem conceito visual claro), retorne "skip" como query

Trechos:
u   

Retorne APENAS um JSON válido neste formato (sem texto antes ou depois):
{
  "brolls": [
    {"n": 1, "query": "person typing laptop"},
    {"n": 2, "query": "skip"},
    ...
  ]
}zclaude-haiku-4-5i  user)rolecontent)model
max_tokensmessagesr   z\{.*\}z[claude] Resposta sem JSON: N   brollsnr   query skipr   r   )r   r   r7   z'[claude] Erro ao analisar para b-roll: )getr$   	anthropic	AnthropicANTHROPIC_KEYjoin	enumerater3   creater0   textresearchDOTALLprintjsonloadsgroupr   r*   r   lowerr   float	Exception)r%   r   r   clientbloco_janelaspromptresprA   matchdataitemsoutitidxr7   r,   es                    r#   analisar_para_brollrW   :   s   
 R0I +G	  7F II g& M
	  	F(#%%$%&9: & 

 ||A##		)T29950ds=>Izz%++-(2&  	B"&&a.)A-.B5577cS\1 7CL

#AhK0 5?" 	  
    7s;<	sb   $A4G <G AF7*G +F7 G 2F73G 7	G G GG 	G)G$G)$G)c                  &   t         j                         syt        t         j                  d            t        t         j                  d            z   t        t         j                  d            z   } | syddl}t        |j                  |             S )uQ   Retorna o caminho de uma música aleatória do diretório music/, ou '' se vazio.r8   *.mp3z*.m4az*.aacr   N)	MUSIC_DIRexistslistglobrandomstrchoice)musicasr^   s     r#   escolher_musicarb      sk    9>>'*+d9>>'3J.KKdS\SaSabiSjNkkGv}}W%&&    job_id
video_pathmodousar_musicaestilo_legendatamanho_legendamusica_path_diretousar_legenda
usar_brollvolume_musicac                    	  || ddd       |dk(  r'|r%t        dt        |       d       t        |||       }|	xs |
}dg d}|r@ || d	d
d       t        d| d       t        |      }t        dt        |d                 nt        d        || dd
d       g }|
r$ || ddd       t	        |      }t        d|D cg c]  }|d   |d   |d   f c}         || ddd       t        |      D ]  \  }}|j                  dd      }|st        |d      }d}|d d D ]K  }t        t        |  d!|d"d#z        }t        |d$   |      }|s.|j                  ||d   |d   d%       d&} n d'|d(z    d)t        |       d*| |rdnd+z   } || dt        d|d,z  z   d-      |        t        d.t        |              nt        d/        || ddd0        || d1d2d3       t        t        |  d4z        }d}|r&|r5t        |      j                         r|} || d1d-d5       t        d6|        n || d1d-d7       	 t!        |j                  d8d      |       xs d}|rt        d:|        ng }t$        j                         rnt$        j'                         D ]3  }|j)                         s|j+                  |j-                  d;             5 |j+                  t$        j-                  d;             |r,d<d l}t        |j1                  |            }t        d=|        |	r|nd} t3        ||||| | |||>	       t        |      j                         st5        d?       || d@dAdB|       y c c}w # t"        $ r}t        d9|        d}Y d }~2d }~ww xY w# t"        $ rF}t        dC|  d*|        d<d l}!|!j9                           || dDd<dEt        |              Y d }~y d }~ww xY w)Fu+  
    Pipeline completo (toggles independentes):
    1. Corta segmentos (modo live)
    2. Transcrição Whisper (sempre, pra alimentar B-roll/legenda quando ativos)
    3. Análise Claude para b-roll (se usar_broll)
    4. Download b-roll Pexels (se usar_broll)
    5. Montagem final com FFmpeg (legenda/música/B-roll condicionais)

    Args extras:
        usar_legenda: se False, pula queima de legenda no vídeo final.
        usar_broll:   se False, pula análise/download Pexels.
        usar_musica:  já existia. Se False, output sem música.
    fila   u   Preparando vídeo...livez[proc] Cortando z segmentos...r8   )r   r   transcrevendo   u   Transcrevendo áudio com IA...z[proc] Transcrevendo z...u$   [proc] Transcrição OK. Segmentos: r   u3   [proc] Transcrição pulada (legenda + b-roll off).
preparandou(   Preparando vídeo (sem transcrição)...
analisando   u*   Analisando conteúdo para buscar B-roll...z[proc] B-rolls alinhados: r   r   r7   baixando_broll-   u   Buscando vídeos de apoio...   )
quantidadeFN_broll_02dz.mp4url)pathr   r   TzB-roll r   /z: z (sem resultado)   <   z[proc] B-rolls baixados: z([proc] B-roll pulado (usar_broll=False).zPulando B-roll...montandoA   u   Montando vídeo final...z
_final.mp4zAplicando trilha selecionada...u(   [proc] Música escolhida pelo usuário: u%   Buscando trilha sonora automática...r   z[proc] ccMixter falhou: u'   [proc] Música automática (ccMixter): rY   r   u!   [proc] Música local (fallback): )	video_principalclips_brollr%   musica_pathrh   rd   output_pathri   rm   u.   Arquivo de saída não foi gerado pelo FFmpeg.	concluidod   u   Pronto! Seu Reel está pronto.z[proc] ERRO no job errozErro no processamento: )rE   r   _cortar_segmentosr   rW   r?   r:   r   r_   TEMP_DIRr   r   min
OUTPUT_DIRr   r[   r	   rK   rZ   iterdiris_dirextendr]   r^   r`   r   RuntimeError	traceback	print_exc)"rd   re   rf   r   rg   rh   callback_statusri   rj   rk   rl   rm   precisa_transcricaor%   r   termostr"   termor7   videosbaixadovdestok
status_msgr   r   rV   musicas_locaissubr^   estilo_efetivor   s"                                     r#   processar_videor      su   6tO+AB6>i$S^$4MBC*:y&IJ +8j "4FOR9YZ)*S9:+J7K8[=U9V8WXYGIFL"6`a FL"6bc(5F.]c/dXY8ah'
0S/d.efgF$4b:XY%f- [5		'2.&u; 
AxVHGAc7$*GGHD%ah5B#**$(&+Ho#(<, 
 #'
  'qse1S[ME7CWrZlm
(8#b1q5j":MzZ%[( -c+.>-?@A<>FL"6IJ 	
B0JK*&'<<= !d+=&>&E&E&G0
B8YZ@NO
B8_`%"9+//'SU:VX^"_"eceK CK=QR &(N '')#,#4#4#6 IC"zz| . 5 5chhw6G HI '--innW.EF%%&)&--*G&H A+OP ,8R&###)#+'
	
 K '')OPPS2RT_`e 0e\ ! %4QC89"$K%L  O#F82aS12-DSVH+MNN	Osd   B?N M1
A;N C0N  M6 #AN 2B>N 1N 6	N?NN NN 	O,&<O''O,)medioNTT   )%__doc__rF   osrB   pathlibr   r;   whisper_utilsr   pexels_utilsr   r   ffmpeg_utilsr   r   r   music_utilsr	   r=   getenv
PEXELS_KEY__file__parentr   r   rZ   r   r   r\   r$   dictrW   r_   rb   boolr   r    rc   r#   <module>r      sR   4  	 	   + 4 R /~RYY')EF
>  6)(^""X-
N!!G+	 
$ 4 <IT Id IX' '& #"OOOOOO OO 	OO
 OO OO OO OO OO OO OOrc   