Update app.py
Browse files
app.py
CHANGED
@@ -302,6 +302,7 @@ 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 |
if musica:
|
306 |
musica_path = os.path.join(temp_dir, "musica_original.mp3")
|
307 |
with open(musica_path, "wb") as f:
|
@@ -325,129 +326,19 @@ if st.button("Gerar Vídeo(s)"):
|
|
325 |
# 🔒 APLICAR ANTI-FLOP NO FINAL
|
326 |
if ativar_antiflop:
|
327 |
st.info(f"🔒 Aplicando Anti-Flop no vídeo {n+1}...")
|
328 |
-
|
329 |
-
|
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 |
-
# 🔒 Garantir resolução 9:16 no Anti-Flop
|
383 |
-
vf_af += ",scale=720:1280:force_original_aspect_ratio=decrease,pad=720:1280:(ow-iw)/2:(oh-ih)/2"
|
384 |
-
if transicoes:
|
385 |
-
effects = [
|
386 |
-
"fade=t=in:st=0:d=0.5",
|
387 |
-
"fade=t=out:st=3:d=0.5",
|
388 |
-
"zoompan=z='min(pzoom+0.0015,1.5)':d=1",
|
389 |
-
"drawbox=x=0:y=0:w=iw:h=ih:[email protected]:t=fill"
|
390 |
-
]
|
391 |
-
vf_af += ",scale=trunc(iw/2)*2:trunc(ih/2)*2"
|
392 |
-
|
393 |
-
af = f"asetrate=44100*{pitch_r},aresample=44100"
|
394 |
-
profile = "baseline" if fingerprint in ["Android", "Xiaomi"] else "main"
|
395 |
-
if fingerprint == "iPhone":
|
396 |
-
profile = "high"
|
397 |
-
level = "4.0" if fingerprint == "Samsung" else "3.1"
|
398 |
-
ar = "44100" if fingerprint in ["iPhone", "Xiaomi"] else "48000"
|
399 |
-
|
400 |
-
subprocess.run([
|
401 |
-
'ffmpeg', '-i', base_video,
|
402 |
-
'-vf', vf_af,
|
403 |
-
'-af', af,
|
404 |
-
'-r', str(fps_af),
|
405 |
-
'-c:v', 'libx264', '-profile:v', profile, '-level', level,
|
406 |
-
'-b:v', bitrate_r, '-ar', ar,
|
407 |
-
'-preset', 'fast', '-tune', 'zerolatency',
|
408 |
-
'-movflags', '+faststart',
|
409 |
-
antiflop_out
|
410 |
-
], check=True)
|
411 |
-
|
412 |
-
# Download Anti-Flop
|
413 |
st.video(antiflop_out)
|
414 |
with open(antiflop_out, "rb") as f:
|
415 |
-
|
416 |
-
st.download_button(f"📥 Baixar vídeo {n+1} Anti-Flop", f, file_name=antiflop_out, disabled=True)
|
417 |
-
else:
|
418 |
-
st.download_button(f"📥 Baixar vídeo {n+1} Anti-Flop", f, file_name=antiflop_out)
|
419 |
else:
|
420 |
-
|
421 |
st.video(final_name)
|
422 |
with open(final_name, "rb") as f:
|
423 |
-
|
424 |
-
st.download_button(f"📥 Baixar vídeo {n+1}", f, file_name=final_name, disabled=True)
|
425 |
-
else:
|
426 |
-
st.download_button(f"📥 Baixar vídeo {n+1}", f, file_name=final_name)
|
427 |
|
428 |
progresso.progress(100)
|
429 |
-
|
430 |
-
# Antes de abrir o try:
|
431 |
-
videos_gerados = []
|
432 |
-
|
433 |
-
# try:
|
434 |
-
try:
|
435 |
-
progresso = st.progress(0)
|
436 |
-
temp_dir = tempfile.mkdtemp()
|
437 |
-
|
438 |
-
# ... [todo o processamento de vídeos aqui dentro]
|
439 |
-
|
440 |
-
for n in range(num_videos_finais):
|
441 |
-
# ... [processamento de cada vídeo]
|
442 |
-
|
443 |
-
# ➡️ Depois de cada vídeo gerado:
|
444 |
-
if ativar_antiflop:
|
445 |
-
videos_gerados.append(antiflop_out)
|
446 |
-
else:
|
447 |
-
videos_gerados.append(final_name)
|
448 |
-
|
449 |
-
progresso.progress(100)
|
450 |
-
st.success("✅ Todos os vídeos foram gerados com sucesso!")
|
451 |
|
452 |
except subprocess.CalledProcessError as e:
|
453 |
st.error(f"❌ Erro ao gerar vídeo:\n\n{e.stderr.decode(errors='ignore')}")
|
@@ -455,7 +346,7 @@ except subprocess.CalledProcessError as e:
|
|
455 |
finally:
|
456 |
shutil.rmtree(temp_dir)
|
457 |
|
458 |
-
# ➡️ Fora do try-finally: Botão Baixar Todos
|
459 |
if videos_gerados:
|
460 |
st.markdown("### 📥 Baixar Todos os Vídeos")
|
461 |
download_links = ""
|
@@ -477,5 +368,4 @@ if videos_gerados:
|
|
477 |
""",
|
478 |
unsafe_allow_html=True
|
479 |
)
|
480 |
-
|
481 |
-
)
|
|
|
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:
|
|
|
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')}")
|
|
|
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 = ""
|
|
|
368 |
""",
|
369 |
unsafe_allow_html=True
|
370 |
)
|
371 |
+
|
|