patocolher commited on
Commit
0590980
Β·
verified Β·
1 Parent(s): b3ba734

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +19 -30
app.py CHANGED
@@ -37,22 +37,15 @@ def contar_frames(path):
37
  # Logo β€” preparaΓ§Γ£o, posiΓ§Γ£o e preview ao vivo
38
  # ══════════════════════════════════════════════════════════════════
39
 
40
- def preparar_logo(logo_path, vid_w, tamanho_pct, opacidade_pct):
41
  """
42
- Abre o logo, redimensiona para tamanho_pct% da largura do vΓ­deo
43
- e escala o canal alpha por opacidade_pct (100 = totalmente opaco,
44
- 0 = invisΓ­vel). Mesmo tratamento simples que o radar-virumania usa.
45
- A eliminaΓ§Γ£o do halo verde Γ© feita na composiΓ§Γ£o FFmpeg (em RGBA).
46
  """
47
  img = Image.open(logo_path).convert("RGBA")
48
 
49
- # Redimensiona proporcionalmente Γ  largura alvo
50
- alvo_w = max(1, int(vid_w * tamanho_pct / 100))
51
- ratio = alvo_w / img.width
52
- alvo_h = max(1, int(img.height * ratio))
53
- img = img.resize((alvo_w, alvo_h), Image.LANCZOS)
54
-
55
- # Escala o canal alpha pela opacidade escolhida
56
  if opacidade_pct < 100:
57
  r, g, b, a = img.split()
58
  fator = opacidade_pct / 100.0
@@ -61,7 +54,7 @@ def preparar_logo(logo_path, vid_w, tamanho_pct, opacidade_pct):
61
 
62
  temp_path = "/tmp/logo_overlay.png"
63
  img.save(temp_path, "PNG")
64
- return temp_path, alvo_w, alvo_h
65
 
66
 
67
  def calcular_posicao_logo(posicao, margem=20, offset_x=0, offset_y=0):
@@ -251,11 +244,11 @@ def reencode_video(
251
 
252
  # ── Prepara a logo (Pillow) ─────────────────────────────────
253
  logo_tmp = None
 
254
  if tem_logo:
255
  try:
256
- logo_tmp, _, _ = preparar_logo(
257
- logo_file, vid_w, logo_tamanho, logo_opacidade
258
- )
259
  except Exception as e:
260
  yield None, f"❌ Erro ao processar logo: {e}"
261
  return
@@ -288,29 +281,25 @@ def reencode_video(
288
  if tem_logo:
289
  cmd += ["-i", logo_tmp]
290
 
291
- # ── filter_complex (overlay em RGBA β†’ yuv420p no fim) ───────
292
  if tem_logo:
293
  overlay_pos = calcular_posicao_logo(
294
  logo_posicao, logo_margem, logo_offset_x, logo_offset_y
295
  )
296
- # CorreΓ§Γ£o do halo verde:
297
- # BASE e LOGO sΓ£o convertidos para RGBA antes do overlay, entΓ£o
298
- # a composiΓ§Γ£o acontece em RGB puro (sem YUV 4:2:0 introduzir
299
- # sangramento de chroma nas bordas). SΓ³ no fim convertemos para
300
- # yuv420p para o encoder. Sem premultiply β€” straight alpha puro.
301
  if vf_parts:
302
  fc = (
303
- f"[0:v]{','.join(vf_parts)},format=rgba[base];"
304
- f"[1:v]format=rgba[logo];"
305
- f"[base][logo]overlay={overlay_pos}[composed];"
306
- f"[composed]format=yuv420p[vout]"
307
  )
308
  else:
309
  fc = (
310
- f"[0:v]format=rgba[base];"
311
- f"[1:v]format=rgba[logo];"
312
- f"[base][logo]overlay={overlay_pos}[composed];"
313
- f"[composed]format=yuv420p[vout]"
314
  )
315
  cmd += ["-filter_complex", fc, "-map", "[vout]"]
316
  if has_audio:
 
37
  # Logo β€” preparaΓ§Γ£o, posiΓ§Γ£o e preview ao vivo
38
  # ══════════════════════════════════════════════════════════════════
39
 
40
+ def preparar_logo(logo_path, opacidade_pct):
41
  """
42
+ SOMENTE aplica a opacidade (escala o canal alpha) via Pillow.
43
+ O redimensionamento Γ© feito pelo prΓ³prio FFmpeg com scale filter β€”
44
+ exatamente como o LegendadorBrasileiroWhisperX faz. Assim evitamos
45
+ re-saves desnecessΓ‘rios da PNG e preservamos as bordas originais.
46
  """
47
  img = Image.open(logo_path).convert("RGBA")
48
 
 
 
 
 
 
 
 
49
  if opacidade_pct < 100:
50
  r, g, b, a = img.split()
51
  fator = opacidade_pct / 100.0
 
54
 
55
  temp_path = "/tmp/logo_overlay.png"
56
  img.save(temp_path, "PNG")
57
+ return temp_path
58
 
59
 
60
  def calcular_posicao_logo(posicao, margem=20, offset_x=0, offset_y=0):
 
244
 
245
  # ── Prepara a logo (Pillow) ─────────────────────────────────
246
  logo_tmp = None
247
+ logo_width_px = 0
248
  if tem_logo:
249
  try:
250
+ logo_tmp = preparar_logo(logo_file, logo_opacidade)
251
+ logo_width_px = max(1, int(vid_w * logo_tamanho / 100))
 
252
  except Exception as e:
253
  yield None, f"❌ Erro ao processar logo: {e}"
254
  return
 
281
  if tem_logo:
282
  cmd += ["-i", logo_tmp]
283
 
284
+ # ── filter_complex (IDÊNTICO ao LegendadorBrasileiroWhisperX) ───
285
  if tem_logo:
286
  overlay_pos = calcular_posicao_logo(
287
  logo_posicao, logo_margem, logo_offset_x, logo_offset_y
288
  )
289
+ # Regra de ouro: NÃO forçar nenhum format= na cadeia. O overlay
290
+ # do FFmpeg jΓ‘ lida com alpha PNG corretamente. ConversΓ΅es
291
+ # explΓ­citas yuv420p↔rgba causam mismatch de matriz de cor
292
+ # (BT.601/BT.709) e introduzem halo verde nas bordas.
 
293
  if vf_parts:
294
  fc = (
295
+ f"[0:v]{','.join(vf_parts)}[base];"
296
+ f"[1:v]scale={logo_width_px}:-1[logo];"
297
+ f"[base][logo]overlay={overlay_pos}[vout]"
 
298
  )
299
  else:
300
  fc = (
301
+ f"[1:v]scale={logo_width_px}:-1[logo];"
302
+ f"[0:v][logo]overlay={overlay_pos}[vout]"
 
 
303
  )
304
  cmd += ["-filter_complex", fc, "-map", "[vout]"]
305
  if has_audio: