pcdoido2 commited on
Commit
1d9f898
·
verified ·
1 Parent(s): 3e35582

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -66
app.py CHANGED
@@ -6,7 +6,7 @@ import tempfile
6
  import shutil
7
  import time
8
 
9
- st.set_page_config(page_title="TikTok Video Generator - PRO", layout="centered")
10
  st.title("🎥 TikTok Video Generator - PRO + Anti-Flop")
11
 
12
  st.markdown("Envie seus vídeos e gere conteúdo com efeitos, zoom, texto, música, filtros e antiflop!")
@@ -115,6 +115,9 @@ if ativar_antiflop:
115
  # 💾 Download Automático
116
  st.write("### 💾 Download Automático")
117
  download_automatico = st.checkbox("Ativar Download Automático", value=False)
 
 
 
118
  # Botão principal
119
  if st.button("Gerar Vídeo(s)"):
120
  if not cortes:
@@ -302,70 +305,96 @@ if st.button("Gerar Vídeo(s)"):
302
  "-of", "default=noprint_wrappers=1:nokey=1", video_final_raw
303
  ], stdout=subprocess.PIPE)
304
  dur_video_real = float(dur_proc.stdout.decode().strip())
 
305
 
306
- if musica:
307
- musica_path = os.path.join(temp_dir, "musica_original.mp3")
308
- with open(musica_path, "wb") as f:
309
- f.write(musica.read())
310
- musica_cortada = os.path.join(temp_dir, f"musica_cortada_{n}.aac")
311
- subprocess.run([
312
- "ffmpeg", "-i", musica_path, "-ss", "0", "-t", str(dur_video_real),
313
- "-vn", "-acodec", "aac", "-y", musica_cortada
314
- ], check=True, stderr=subprocess.PIPE)
315
- final_name = f"video_final_{n}_{int(time.time())}.mp4"
316
- subprocess.run([
317
- "ffmpeg", "-i", video_final_raw, "-i", musica_cortada,
318
- "-map", "0:v:0", "-map", "1:a:0",
319
- "-c:v", "copy", "-c:a", "aac",
320
- "-shortest", final_name
321
- ], check=True, stderr=subprocess.PIPE)
322
- else:
323
- final_name = f"video_final_{n}_{int(time.time())}.mp4"
324
- shutil.copy(video_final_raw, final_name)
325
-
326
- # 🔒 APLICAR ANTI-FLOP NO FINAL
327
- if ativar_antiflop:
328
- st.info(f"🔒 Aplicando Anti-Flop no vídeo {n+1}...")
329
- # ... [todo o bloco do Anti-Flop aqui, como te enviei antes] ...
330
- videos_gerados.append(antiflop_out)
331
- st.video(antiflop_out)
332
- with open(antiflop_out, "rb") as f:
333
- st.download_button(f"📥 Baixar vídeo {n+1} Anti-Flop", f, file_name=antiflop_out)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
  else:
335
- videos_gerados.append(final_name)
336
- st.video(final_name)
337
- with open(final_name, "rb") as f:
338
- st.download_button(f"📥 Baixar vídeo {n+1}", f, file_name=final_name)
339
-
340
- progresso.progress(100)
341
- st.success(" Todos os vídeos foram gerados com sucesso!")
342
-
343
- except subprocess.CalledProcessError as e:
344
- st.error(f"❌ Erro ao gerar vídeo:\n\n{e.stderr.decode(errors='ignore')}")
345
-
346
- finally:
347
- shutil.rmtree(temp_dir)
348
-
349
- # ➡️ Fora do try-finally: Botão "Baixar Todos os Vídeos"
350
- if videos_gerados:
351
- st.markdown("### 📥 Baixar Todos os Vídeos")
352
- download_links = ""
353
- for v in videos_gerados:
354
- download_links += f"<a href='{v}' download='{v}'></a>\n"
355
-
356
- st.markdown(
357
- f"""
358
- <button onclick="baixarTodos()">📥 Baixar Todos</button>
359
- <script>
360
- function baixarTodos() {{
361
- const links = Array.from(document.querySelectorAll('a[download]'));
362
- for (let l of links) {{
363
- l.click();
364
- }}
365
- }}
366
- </script>
367
- {download_links}
368
- """,
369
- unsafe_allow_html=True
370
- )
371
-
 
 
 
 
 
 
 
 
 
 
6
  import shutil
7
  import time
8
 
9
+ st.set_page_config(page_title="TikTok Video Generator - PRO + Anti-Flop", layout="centered")
10
  st.title("🎥 TikTok Video Generator - PRO + Anti-Flop")
11
 
12
  st.markdown("Envie seus vídeos e gere conteúdo com efeitos, zoom, texto, música, filtros e antiflop!")
 
115
  # 💾 Download Automático
116
  st.write("### 💾 Download Automático")
117
  download_automatico = st.checkbox("Ativar Download Automático", value=False)
118
+ # Lista para armazenar os vídeos gerados
119
+ videos_gerados = []
120
+
121
  # Botão principal
122
  if st.button("Gerar Vídeo(s)"):
123
  if not cortes:
 
305
  "-of", "default=noprint_wrappers=1:nokey=1", video_final_raw
306
  ], stdout=subprocess.PIPE)
307
  dur_video_real = float(dur_proc.stdout.decode().strip())
308
+ progresso.progress(35 + n * 5)
309
 
310
+ # Filtros no vídeo principal (zoom, espelho, borda, etc.)
311
+ filtros_main = ["scale=720:1280:force_original_aspect_ratio=decrease"]
312
+ if zoom != 1.0:
313
+ filtros_main.append(f"scale=iw*{zoom}:ih*{zoom}")
314
+ filtros_main.append(f"setpts=PTS/{velocidade_cortes}")
315
+ if ativar_espelhar:
316
+ filtros_main.append("hflip")
317
+ if remover_borda and tamanho_borda > 0:
318
+ filtros_main.append(f"crop=in_w-{tamanho_borda*2}:in_h-{tamanho_borda*2}")
319
+ if ativar_filtro_cor:
320
+ filtros_main.append("eq=contrast=1.1:saturation=1.2")
321
+ if ativar_borda_personalizada:
322
+ cor_ffmpeg = f"0x{cor_borda.lstrip('#')}FF"
323
+ anim_map = {
324
+ "Nenhuma": "",
325
+ "Borda Pulsante": "enable='lt(mod(t,1),0.5)'",
326
+ "Cor Animada": "enable='lt(mod(t,1),0.5)'",
327
+ "Neon": "enable='lt(mod(t,0.5),0.25)'",
328
+ "Ondulada": "enable='gt(sin(t*3.14),0)'"
329
+ }
330
+ drawbox = f"drawbox=x=0:y=0:w=iw:h=ih:color={cor_ffmpeg}:t=5"
331
+ if anim_map[animacao_borda]:
332
+ drawbox += f":{anim_map[animacao_borda]}"
333
+ filtros_main.append(drawbox)
334
+
335
+ # Fundo com filtros
336
+ filtro_complex = f"[0:v]scale=720:1280:force_original_aspect_ratio=increase,crop=720:1280"
337
+ if ativar_blur_fundo:
338
+ filtro_complex += f",boxblur={blur_strength}:1"
339
+ if ativar_sepia:
340
+ filtro_complex += ",colorchannelmixer=.393:.769:.189:0:.349:.686:.168:0:.272:.534:.131"
341
+ if ativar_granulado:
342
+ filtro_complex += ",noise=alls=20:allf=t+u"
343
+ if ativar_pb:
344
+ filtro_complex += ",hue=s=0.3"
345
+ if ativar_vignette:
346
+ filtro_complex += ",vignette"
347
+ filtro_complex += "[blur];[1:v]" + ",".join(filtros_main) + "[zoomed];[blur][zoomed]overlay=(W-w)/2:(H-h)/2[base]"
348
+
349
+ if ativar_texto and texto_personalizado.strip():
350
+ y_pos = "100" if posicao_texto == "Topo" else "(h-text_h)/2" if posicao_texto == "Centro" else "h-text_h-100"
351
+ enable = f":enable='lt(t\\,{segundos_texto})'" if duracao_texto == "Apenas primeiros segundos" else ""
352
+ texto_clean = texto_personalizado.replace(":", "\\:").replace("'", "\\'")
353
+ filtro_complex += f";[base]drawtext=text='{texto_clean}':fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf:fontcolor={cor_texto}:fontsize={tamanho_texto}:shadowcolor={cor_sombra}:shadowx=3:shadowy=3:x=(w-text_w)/2:y={y_pos}{enable}[final]"
354
  else:
355
+ filtro_complex += ";[base]null[final]"
356
+
357
+ video_editado = os.path.join(temp_dir, f"video_editado_{n}.mp4")
358
+ subprocess.run([
359
+ "ffmpeg", "-i", fundo_cortado, "-i", video_raw,
360
+ "-filter_complex", filtro_complex,
361
+ "-map", "[final]", "-c:v", "libx264", "-preset", "ultrafast", "-crf", str(crf_value),
362
+ video_editado
363
+ ], check=True, stderr=subprocess.PIPE)
364
+
365
+ # Acelerar vídeo final (sem áudio)
366
+ video_acelerado = os.path.join(temp_dir, f"video_acelerado_{n}.mp4")
367
+ subprocess.run([
368
+ "ffmpeg", "-y", "-i", video_editado, "-an",
369
+ "-filter:v", f"setpts=PTS/{velocidade_final}",
370
+ "-c:v", "libx264", "-preset", "ultrafast", "-crf", str(crf_value),
371
+ video_acelerado
372
+ ], check=True, stderr=subprocess.PIPE)
373
+
374
+ progresso.progress(70)
375
+
376
+ # Tutorial no meio (se enviado)
377
+ video_final_raw = video_acelerado
378
+ if video_tutorial:
379
+ dur_proc = subprocess.run([
380
+ "ffprobe", "-v", "error", "-show_entries", "format=duration",
381
+ "-of", "default=noprint_wrappers=1:nokey=1", video_acelerado
382
+ ], stdout=subprocess.PIPE)
383
+ dur_f = float(dur_proc.stdout.decode().strip())
384
+ pt = dur_f / 2 if dur_f < 10 else random.uniform(5, dur_f - 5)
385
+ part1 = os.path.join(temp_dir, f"part1_{n}.mp4")
386
+ part2 = os.path.join(temp_dir, f"part2_{n}.mp4")
387
+ subprocess.run(["ffmpeg", "-i", video_acelerado, "-ss", "0", "-t", str(pt), "-c:v", "libx264", "-preset", "ultrafast", part1], check=True, stderr=subprocess.PIPE)
388
+ subprocess.run(["ffmpeg", "-i", video_acelerado, "-ss", str(pt), "-c:v", "libx264", "-preset", "ultrafast", part2], check=True, stderr=subprocess.PIPE)
389
+ final_txt = os.path.join(temp_dir, f"final_{n}.txt")
390
+ with open(final_txt, "w") as f:
391
+ f.write(f"file '{part1}'\nfile '{tutorial_mp4}'\nfile '{part2}'\n")
392
+ video_final_raw = os.path.join(temp_dir, f"video_final_raw_{n}.mp4")
393
+ subprocess.run(["ffmpeg", "-f", "concat", "-safe", "0", "-i", final_txt, "-c:v", "libx264", "-preset", "ultrafast", "-crf", str(crf_value), video_final_raw], check=True, stderr=subprocess.PIPE)
394
+
395
+ # 🎵 Música final
396
+ dur_proc = subprocess.run([
397
+ "ffprobe", "-v", "error", "-show_entries", "format=duration",
398
+ "-of", "default=noprint_wrappers=1:nokey=1", video_final_raw
399
+ ], stdout=subprocess.PIPE)
400
+ dur_video_real = float(dur_proc.stdout.decode().strip())