pcdoido2 commited on
Commit
420ac8e
·
verified ·
1 Parent(s): 743303a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +137 -22
app.py CHANGED
@@ -7,7 +7,7 @@ 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")
11
 
12
  st.markdown("Envie seus vídeos e gere conteúdo com efeitos, zoom, texto, música, filtros e antiflop!")
13
 
@@ -71,16 +71,50 @@ if ativar_borda_personalizada:
71
  cor_borda = st.color_picker("Cor da borda", "#FF0000")
72
  animacao_borda = st.selectbox("Animação da borda", ["Nenhuma", "Borda Pulsante", "Cor Animada", "Neon", "Ondulada"])
73
 
74
- # 🔒 Anti-Flop (Configuração)
75
  st.write("### 🔒 Anti-Flop (Evitar Detecção)")
76
  ativar_antiflop = st.checkbox("Ativar Anti-Flop", value=False)
77
  if ativar_antiflop:
78
- zoom_af = st.slider("Zoom Anti-Flop (%)", 100, 105, 101) / 100
79
- brilho_af = st.slider("Brilho Anti-Flop", -0.1, 0.1, 0.01)
80
- contraste_af = st.slider("Contraste Anti-Flop", 0.9, 1.1, 1.01)
81
- saturacao_af = st.slider("Saturação Anti-Flop", 0.9, 1.1, 1.01)
82
- ruido_af = st.slider("Ruído Visual Anti-Flop (0-20)", 0, 20, 5)
83
- rotacao_af = st.slider("Rotação Anti-Flop (graus)", 0.0, 2.0, 0.5)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  # Botão principal
85
  if st.button("Gerar Vídeo(s)"):
86
  if not cortes:
@@ -97,7 +131,6 @@ if st.button("Gerar Vídeo(s)"):
97
  with open(fundo_path, "wb") as f:
98
  f.write(video_fundo.read())
99
  else:
100
- # Gera fundo preto 720x1280
101
  subprocess.run([
102
  "ffmpeg", "-f", "lavfi", "-i", "color=black:s=720x1280:d=600",
103
  "-c:v", "libx264", "-t", str(duracao_final),
@@ -233,7 +266,7 @@ if st.button("Gerar Vídeo(s)"):
233
  video_editado
234
  ], check=True, stderr=subprocess.PIPE)
235
 
236
- # Acelerar vídeo final
237
  video_acelerado = os.path.join(temp_dir, f"video_acelerado_{n}.mp4")
238
  subprocess.run([
239
  "ffmpeg", "-y", "-i", video_editado, "-an",
@@ -242,9 +275,9 @@ if st.button("Gerar Vídeo(s)"):
242
  video_acelerado
243
  ], check=True, stderr=subprocess.PIPE)
244
 
245
- progresso.progress(90)
246
 
247
- # Tutorial no meio
248
  video_final_raw = video_acelerado
249
  if video_tutorial:
250
  dur_proc = subprocess.run([
@@ -262,13 +295,13 @@ if st.button("Gerar Vídeo(s)"):
262
  f.write(f"file '{part1}'\nfile '{tutorial_mp4}'\nfile '{part2}'\n")
263
  video_final_raw = os.path.join(temp_dir, f"video_final_raw_{n}.mp4")
264
  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)
 
265
  # 🎵 Música final
266
  dur_proc = subprocess.run([
267
  "ffprobe", "-v", "error", "-show_entries", "format=duration",
268
  "-of", "default=noprint_wrappers=1:nokey=1", video_final_raw
269
  ], stdout=subprocess.PIPE)
270
  dur_video_real = float(dur_proc.stdout.decode().strip())
271
-
272
  if musica:
273
  musica_path = os.path.join(temp_dir, "musica_original.mp3")
274
  with open(musica_path, "wb") as f:
@@ -291,26 +324,108 @@ if st.button("Gerar Vídeo(s)"):
291
 
292
  # 🔒 APLICAR ANTI-FLOP NO FINAL
293
  if ativar_antiflop:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
  antiflop_out = f"antiflop_{n}_{int(time.time())}.mp4"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
  vf_af = (
296
- f"scale=iw*{zoom_af}:ih*{zoom_af},"
297
- f"crop=iw/{zoom_af}:ih/{zoom_af},"
298
- f"eq=brightness={brilho_af}:contrast={contraste_af}:saturation={saturacao_af},"
299
- f"noise=alls={ruido_af}:allf=t,"
300
- f"rotate={rotacao_af}*PI/180:[email protected]"
301
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
  subprocess.run([
303
- "ffmpeg", "-i", final_name, "-vf", vf_af,
304
- "-c:v", "libx264", "-preset", "fast", "-crf", str(crf_value),
 
 
 
 
 
 
305
  antiflop_out
306
  ], check=True)
 
 
307
  st.video(antiflop_out)
308
  with open(antiflop_out, "rb") as f:
309
- st.download_button(f"📥 Baixar vídeo {n+1} Anti-Flop", f, file_name=antiflop_out)
 
 
 
310
  else:
 
311
  st.video(final_name)
312
  with open(final_name, "rb") as f:
313
- st.download_button(f"📥 Baixar vídeo {n+1}", f, file_name=final_name)
 
 
 
314
 
315
  progresso.progress(100)
316
  st.success("✅ Todos os vídeos foram gerados com sucesso!")
 
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!")
13
 
 
71
  cor_borda = st.color_picker("Cor da borda", "#FF0000")
72
  animacao_borda = st.selectbox("Animação da borda", ["Nenhuma", "Borda Pulsante", "Cor Animada", "Neon", "Ondulada"])
73
 
74
+ # 🔒 Anti-Flop Completo
75
  st.write("### 🔒 Anti-Flop (Evitar Detecção)")
76
  ativar_antiflop = st.checkbox("Ativar Anti-Flop", value=False)
77
  if ativar_antiflop:
78
+ aplicar_random = st.button("🎲 RANDOMIZAR Anti-Flop")
79
+ if 'antiflop_settings' not in st.session_state or aplicar_random:
80
+ st.session_state.antiflop_settings = {
81
+ 'zoom': random.uniform(1.00, 1.05),
82
+ 'brilho': random.uniform(-0.05, 0.05),
83
+ 'contraste': random.uniform(0.95, 1.05),
84
+ 'saturacao': random.uniform(0.95, 1.05),
85
+ 'ruido': random.randint(3, 15),
86
+ 'rotacao': random.uniform(0.2, 1.5),
87
+ 'pitch': random.uniform(1.00, 1.08),
88
+ 'velocidade': random.uniform(1.00, 1.03),
89
+ 'bitrate': random.randint(900, 1500),
90
+ 'fps': random.choice([30, 29.97, 25])
91
+ }
92
+ antiflop = st.session_state.antiflop_settings
93
+ zoom_af = st.slider("Zoom Anti-Flop (%)", 100, 105, int(antiflop['zoom']*100)) / 100
94
+ brilho_af = st.slider("Brilho Anti-Flop", -0.1, 0.1, antiflop['brilho'])
95
+ contraste_af = st.slider("Contraste Anti-Flop", 0.9, 1.1, antiflop['contraste'])
96
+ saturacao_af = st.slider("Saturação Anti-Flop", 0.9, 1.1, antiflop['saturacao'])
97
+ ruido_af = st.slider("Ruído Visual Anti-Flop (0-20)", 0, 20, antiflop['ruido'])
98
+ rotacao_af = st.slider("Rotação Anti-Flop (graus)", 0.0, 2.0, antiflop['rotacao'])
99
+ pitch_af = st.slider("Pitch do Áudio Anti-Flop (%)", 100, 110, int(antiflop['pitch']*100)) / 100
100
+ velocidade_af = st.slider("Velocidade do Vídeo Anti-Flop (%)", 100, 103, int(antiflop['velocidade']*100)) / 100
101
+ bitrate_af = st.slider("Bitrate Anti-Flop (kbps)", 800, 2000, antiflop['bitrate'])
102
+ fps_af = st.selectbox("FPS Final Anti-Flop", [30, 29.97, 25], index=[30, 29.97, 25].index(antiflop['fps']))
103
+ st.subheader("🧩 Extras Anti-Detecção")
104
+ usar_marca = st.checkbox("Marca d’água Fantasma com perfil", value=True)
105
+ usar_glitch = st.checkbox("Inserir Frame Preto Aleatório", value=True)
106
+ res_random = st.checkbox("Resolução Aleatória", value=True)
107
+ cortar = st.checkbox("Cortar trecho aleatório do vídeo", value=True)
108
+ embaralhar = st.checkbox("Embaralhar trechos do vídeo", value=True)
109
+ st.subheader("🎨 Avançado Anti-Flop")
110
+ lote_efeitos = st.checkbox("Aplicar efeitos por lote (aleatórios)", value=True)
111
+ transicoes = st.checkbox("Transições visuais aleatórias", value=True)
112
+ st.subheader("🕵️‍♂️ Perfil Fingerprint")
113
+ fingerprint = st.selectbox("Escolha o Perfil Anti-Flop", ["Android", "iPhone", "Câmera", "CapCut", "Samsung", "Xiaomi", "LG"])
114
+
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:
 
131
  with open(fundo_path, "wb") as f:
132
  f.write(video_fundo.read())
133
  else:
 
134
  subprocess.run([
135
  "ffmpeg", "-f", "lavfi", "-i", "color=black:s=720x1280:d=600",
136
  "-c:v", "libx264", "-t", str(duracao_final),
 
266
  video_editado
267
  ], check=True, stderr=subprocess.PIPE)
268
 
269
+ # Acelerar vídeo final (sem áudio)
270
  video_acelerado = os.path.join(temp_dir, f"video_acelerado_{n}.mp4")
271
  subprocess.run([
272
  "ffmpeg", "-y", "-i", video_editado, "-an",
 
275
  video_acelerado
276
  ], check=True, stderr=subprocess.PIPE)
277
 
278
+ progresso.progress(70)
279
 
280
+ # Tutorial no meio (se enviado)
281
  video_final_raw = video_acelerado
282
  if video_tutorial:
283
  dur_proc = subprocess.run([
 
295
  f.write(f"file '{part1}'\nfile '{tutorial_mp4}'\nfile '{part2}'\n")
296
  video_final_raw = os.path.join(temp_dir, f"video_final_raw_{n}.mp4")
297
  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)
298
+
299
  # 🎵 Música final
300
  dur_proc = subprocess.run([
301
  "ffprobe", "-v", "error", "-show_entries", "format=duration",
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
  if musica:
306
  musica_path = os.path.join(temp_dir, "musica_original.mp3")
307
  with open(musica_path, "wb") as f:
 
324
 
325
  # 🔒 APLICAR ANTI-FLOP NO FINAL
326
  if ativar_antiflop:
327
+ st.info(f"🔒 Aplicando Anti-Flop no vídeo {n+1}...")
328
+ base_video = final_name
329
+ # 🌀 Embaralhar trechos se ativado
330
+ if embaralhar:
331
+ temp_af_dir = f"temp_af_{random.randint(1000,9999)}"
332
+ os.makedirs(temp_af_dir, exist_ok=True)
333
+ subprocess.run(['ffmpeg', '-i', base_video, '-c', 'copy', '-f', 'segment', '-segment_time', '2', f'{temp_af_dir}/out%03d.mp4'])
334
+ files = os.listdir(temp_af_dir)
335
+ files.sort()
336
+ random.shuffle(files)
337
+ concat_list = f"{temp_af_dir}/list.txt"
338
+ with open(concat_list, 'w') as f:
339
+ for file in files:
340
+ f.write(f"file '{os.path.join(temp_af_dir, file)}'\n")
341
+ shuffled_input = f"shuffled_af_{random.randint(1000,9999)}.mp4"
342
+ subprocess.run(['ffmpeg', '-f', 'concat', '-safe', '0', '-i', concat_list, '-c', 'copy', shuffled_input])
343
+ shutil.rmtree(temp_af_dir)
344
+ base_video = shuffled_input if os.path.exists(shuffled_input) else final_name
345
+
346
+ encoder_name = f"{fingerprint}Cam_{random.randint(1000,9999)}"
347
  antiflop_out = f"antiflop_{n}_{int(time.time())}.mp4"
348
+
349
+ # 🎨 Efeitos
350
+ if lote_efeitos:
351
+ zoom_r = random.uniform(1.00, 1.05)
352
+ brilho_r = random.uniform(-0.05, 0.05)
353
+ contraste_r = random.uniform(0.95, 1.05)
354
+ saturacao_r = random.uniform(0.95, 1.05)
355
+ ruido_r = random.randint(3, 15)
356
+ rot_r = random.uniform(0.2, 1.5) * 0.01745
357
+ velocidade_r = random.uniform(1.00, 1.03)
358
+ bitrate_r = f"{random.randint(900, 1500)}k"
359
+ pitch_r = random.uniform(1.00, 1.08)
360
+ else:
361
+ zoom_r = zoom_af
362
+ brilho_r = brilho_af
363
+ contraste_r = contraste_af
364
+ saturacao_r = saturacao_af
365
+ ruido_r = ruido_af
366
+ rot_r = rotacao_af * 0.01745
367
+ velocidade_r = velocidade_af
368
+ bitrate_r = f"{bitrate_af}k"
369
+ pitch_r = pitch_af
370
+
371
  vf_af = (
372
+ f"scale=iw*{zoom_r}:ih*{zoom_r},"
373
+ f"crop=iw/{zoom_r}:ih/{zoom_r},"
374
+ f"eq=brightness={brilho_r}:contrast={contraste_r}:saturation={saturacao_r},"
375
+ f"noise=alls={ruido_r}:allf=t,"
376
+ f"rotate={rot_r}:[email protected]"
377
  )
378
+ if usar_marca:
379
+ vf_af += f",drawtext=text='{encoder_name}':[email protected]:x=10:y=10:fontsize=24"
380
+ if usar_glitch:
381
+ vf_af += ",blackframe=1:0"
382
+ if res_random:
383
+ w = random.choice([720, 960, 1080])
384
+ h = random.choice([1280, 1440, 1920])
385
+ vf_af += f",scale={w}:{h}"
386
+ if transicoes:
387
+ effects = [
388
+ "fade=t=in:st=0:d=0.5",
389
+ "fade=t=out:st=3:d=0.5",
390
+ "zoompan=z='min(pzoom+0.0015,1.5)':d=1",
391
+ "drawbox=x=0:y=0:w=iw:h=ih:[email protected]:t=fill"
392
+ ]
393
+ vf_af += "," + random.choice(effects)
394
+
395
+ af = f"asetrate=44100*{pitch_r},aresample=44100"
396
+ profile = "baseline" if fingerprint in ["Android", "Xiaomi"] else "main"
397
+ if fingerprint == "iPhone":
398
+ profile = "high"
399
+ level = "4.0" if fingerprint == "Samsung" else "3.1"
400
+ ar = "44100" if fingerprint in ["iPhone", "Xiaomi"] else "48000"
401
+
402
  subprocess.run([
403
+ 'ffmpeg', '-i', base_video,
404
+ '-vf', vf_af,
405
+ '-af', af,
406
+ '-r', str(fps_af),
407
+ '-c:v', 'libx264', '-profile:v', profile, '-level', level,
408
+ '-b:v', bitrate_r, '-ar', ar,
409
+ '-preset', 'fast', '-tune', 'zerolatency',
410
+ '-movflags', '+faststart',
411
  antiflop_out
412
  ], check=True)
413
+
414
+ # Download Anti-Flop
415
  st.video(antiflop_out)
416
  with open(antiflop_out, "rb") as f:
417
+ if download_automatico:
418
+ st.download_button(f"📥 Baixar vídeo {n+1} Anti-Flop", f, file_name=antiflop_out, disabled=True)
419
+ else:
420
+ st.download_button(f"📥 Baixar vídeo {n+1} Anti-Flop", f, file_name=antiflop_out)
421
  else:
422
+ # Download normal
423
  st.video(final_name)
424
  with open(final_name, "rb") as f:
425
+ if download_automatico:
426
+ st.download_button(f"📥 Baixar vídeo {n+1}", f, file_name=final_name, disabled=True)
427
+ else:
428
+ st.download_button(f"📥 Baixar vídeo {n+1}", f, file_name=final_name)
429
 
430
  progresso.progress(100)
431
  st.success("✅ Todos os vídeos foram gerados com sucesso!")