pcdoido2 commited on
Commit
824fdfc
·
verified ·
1 Parent(s): 147915a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +171 -159
app.py CHANGED
@@ -1,164 +1,176 @@
1
  import streamlit as st
2
  import subprocess
3
  import os
 
4
  import random
5
- import tempfile
6
  import shutil
7
- import time
8
-
9
- st.set_page_config(page_title="TikTok Video Generator", 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 e filtros!")
13
-
14
- # Uploads dos vídeos de cortes (principal)
15
- st.markdown("<div style='background-color:#F0F0FF;padding:10px;border-radius:8px'>", unsafe_allow_html=True)
16
- st.subheader("🎬 Envie os vídeos principais (cortes)")
17
- cortes = st.file_uploader("Vídeos de cortes", type=["mp4"], accept_multiple_files=True)
18
- st.markdown("</div>", unsafe_allow_html=True)
19
-
20
- # Upload do vídeo de fundo (opcional)
21
- st.markdown("<div style='background-color:#FFF0F0;padding:10px;border-radius:8px;margin-top:15px;'>", unsafe_allow_html=True)
22
- st.subheader("🌄 Envie o vídeo de fundo (opcional)")
23
- video_fundo = st.file_uploader("Vídeo de Fundo (com blur e efeitos)", type=["mp4", "mov"])
24
- st.markdown("</div>", unsafe_allow_html=True)
25
-
26
- # Uploads adicionais
27
- video_tutorial = st.file_uploader("📎 Tutorial (opcional)", type="mp4")
28
- musica = st.file_uploader("🎵 Música (opcional, MP3)", type=["mp3"])
29
-
30
- # Configurações gerais
31
- num_videos_finais = st.number_input("Quantos vídeos gerar?", 1, 10, 1)
32
- duracao_final = st.number_input("Duração final (s)", 10, 300, 30)
33
- duracao_corte = st.number_input("Duração de cada corte (s)", 1, 30, 5)
34
- zoom = st.slider("Zoom no vídeo principal", 1.0, 2.0, 1.0, 0.1)
35
- blur_strength = st.slider("Blur no fundo", 1, 50, 10)
36
- velocidade_cortes = st.slider("Velocidade dos cortes", 0.5, 2.0, 1.0, 0.1)
37
- velocidade_final = st.slider("Velocidade final", 0.5, 2.0, 1.0, 0.1)
38
- crf_value = st.slider("Qualidade CRF", 18, 30, 23)
39
-
40
- # Texto com emojis
41
- st.write("### Texto no Vídeo")
42
- ativar_texto = st.checkbox("Ativar texto", value=False)
43
- if ativar_texto:
44
- texto_personalizado = st.text_input("Texto (emojis permitidos)", "🔥 Siga para mais!")
45
- posicao_texto = st.selectbox("Posição do texto", ["Topo", "Centro", "Base"])
46
- duracao_texto = st.radio("Duração do texto", ["Vídeo todo", "Apenas primeiros segundos"])
47
- segundos_texto = 5
48
- if duracao_texto == "Apenas primeiros segundos":
49
- segundos_texto = st.slider("Segundos", 1, 30, 5)
50
- cor_texto = st.color_picker("Cor do texto", "#FFFF00")
51
- cor_sombra = st.color_picker("Cor da sombra", "#000000")
52
- tamanho_texto = st.slider("Tamanho da fonte", 20, 100, 60, step=2)
53
-
54
- # Filtros no fundo
55
- st.write("### Filtros no fundo")
56
- ativar_blur_fundo = st.checkbox("Ativar blur no fundo", value=True)
57
- ativar_sepia = st.checkbox("Sépia", False)
58
- ativar_granulado = st.checkbox("Granulado", False)
59
- ativar_pb = st.checkbox("Preto e branco", False)
60
- ativar_vignette = st.checkbox("Vignette", False)
61
-
62
- # Efeitos extras
63
- st.write("### Outros efeitos")
64
- ativar_espelhar = st.checkbox("Espelhar vídeo", True)
65
- ativar_filtro_cor = st.checkbox("Ajuste de cor", True)
66
- remover_borda = st.checkbox("Remover borda do vídeo")
67
- tamanho_borda = st.slider("Tamanho da borda (px)", 0, 200, 0, 5)
68
-
69
- # Borda personalizada
70
- ativar_borda_personalizada = st.checkbox("Borda personalizada", False)
71
- if ativar_borda_personalizada:
72
- cor_borda = st.color_picker("Cor da borda", "#FF0000")
73
- animacao_borda = st.selectbox("Animação da borda", ["Nenhuma", "Borda Pulsante", "Cor Animada", "Neon", "Ondulada"])
74
-
75
- # 💥 Anti-Flop
76
- st.write("### 🔒 Anti-Flop PRO MAX")
77
- ativar_antiflop = st.checkbox("Ativar Anti-Flop", value=False)
78
- if ativar_antiflop:
79
- perfil_fingerprint = st.selectbox("Perfil Fingerprint", ["Android", "iPhone", "Câmera", "CapCut", "Samsung", "Xiaomi", "LG"])
80
- lote_efeitos = st.checkbox("Aplicar efeitos por lote (aleatórios)", value=True)
81
- usar_marca = st.checkbox("Marca d’água fantasma", value=True)
82
- usar_glitch = st.checkbox("Inserir frame preto aleatório", value=True)
83
- res_random = st.checkbox("Resolução aleatória", value=True)
84
- transicoes = st.checkbox("Transições visuais aleatórias", value=True)
85
-
86
- # BOTÃO PRINCIPAL
87
- if st.button("Gerar Vídeo(s)"):
88
- if not cortes:
89
- st.error("❌ Envie os vídeos de cortes.")
90
- else:
91
- with st.spinner("🎬 Processando..."):
92
- progresso = st.progress(0)
93
- temp_dir = tempfile.mkdtemp()
94
-
95
- try:
96
- # (Aqui segue todo o processamento original do video-generator.py...)
97
-
98
- # Após gerar cada vídeo final:
99
- # video_final é o vídeo já pronto (com música)
100
-
101
- for n in range(num_videos_finais):
102
- final_name = f"video_final_{n}_{int(time.time())}.mp4"
103
-
104
- # Aqui você insere o código Anti-Flop, se ativado
105
- if ativar_antiflop:
106
- antiflop_out = os.path.join(temp_dir, f"antiflop_{n}.mp4")
107
- zoom_r = random.uniform(1.00, 1.05) if lote_efeitos else 1.02
108
- brilho_r = random.uniform(-0.05, 0.05) if lote_efeitos else 0.01
109
- contraste_r = random.uniform(0.95, 1.05) if lote_efeitos else 1.01
110
- saturacao_r = random.uniform(0.95, 1.05) if lote_efeitos else 1.01
111
- ruido_r = random.randint(3, 15) if lote_efeitos else 5
112
- rot_r = random.uniform(0.2, 1.5) * 0.01745 if lote_efeitos else 0.5 * 0.01745
113
- pitch_r = random.uniform(1.00, 1.08) if lote_efeitos else 1.01
114
- velocidade_r = random.uniform(1.00, 1.03) if lote_efeitos else 1.01
115
- bitrate_r = f"{random.randint(900, 1500)}k" if lote_efeitos else "1100k"
116
- encoder_name = f"{perfil_fingerprint}Cam_{random.randint(1000,9999)}"
117
-
118
- vf = (
119
- f"scale=iw*{zoom_r}:ih*{zoom_r},"
120
- f"crop=iw/{zoom_r}:ih/{zoom_r},"
121
- f"[email protected]:t=fill,"
122
- f"eq=brightness={brilho_r}:contrast={contraste_r}:saturation={saturacao_r},"
123
- f"noise=alls={ruido_r}:allf=t,"
124
- f"rotate={rot_r}:c=black@0.0"
125
- )
126
- if usar_marca:
127
- vf += f",drawtext=text='{encoder_name}':[email protected]:x=10:y=10:fontsize=24"
128
- if usar_glitch:
129
- vf += ",blackframe=1:0"
130
- if res_random:
131
- w = random.choice([720, 960, 1080])
132
- h = random.choice([1280, 1440, 1920])
133
- vf += f",scale={w}:{h}"
134
- if transicoes:
135
- effects = [
136
- "fade=t=in:st=0:d=0.5",
137
- "fade=t=out:st=3:d=0.5",
138
- "zoompan=z='min(pzoom+0.0015,1.5)':d=1",
139
- "drawbox=x=0:y=0:w=iw:h=ih:[email protected]:t=fill"
140
- ]
141
- vf += "," + random.choice(effects)
142
-
143
- af = f"asetrate=44100*{pitch_r},aresample=44100"
144
- subprocess.run([
145
- "ffmpeg", "-i", final_name,
146
- "-vf", vf, "-af", af,
147
- "-c:v", "libx264", "-preset", "fast", "-b:v", bitrate_r,
148
- "-c:a", "aac", "-movflags", "+faststart",
149
- antiflop_out
150
- ], check=True)
151
- final_name = antiflop_out
152
-
153
- st.video(final_name)
154
- with open(final_name, "rb") as f:
155
- st.download_button(f"📥 Baixar vídeo {n+1}", f, file_name=final_name)
156
-
157
- progresso.progress(100)
158
- st.success("✅ Todos os vídeos foram gerados com sucesso!")
159
-
160
- except subprocess.CalledProcessError as e:
161
- st.error(f"❌ Erro ao gerar vídeo:\n\n{e.stderr.decode(errors='ignore')}")
162
-
163
- finally:
164
- shutil.rmtree(temp_dir)
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
  import subprocess
3
  import os
4
+ import uuid
5
  import random
 
6
  import shutil
7
+
8
+ st.set_page_config(page_title="Anti-Flop PRO MAX", layout="centered")
9
+ st.title("🚀 Anti-Flop PRO MAX – Gerador com Fingerprint Invisível")
10
+
11
+ uploaded_file = st.file_uploader("📤 Envie seu vídeo (MP4)", type=["mp4"])
12
+
13
+ if uploaded_file:
14
+ raw_input_filename = f"raw_{uuid.uuid4().hex}.mp4"
15
+ with open(raw_input_filename, "wb") as f:
16
+ f.write(uploaded_file.read())
17
+
18
+ input_filename = f"cleaned_{uuid.uuid4().hex}.mp4"
19
+ subprocess.run(['ffmpeg', '-i', raw_input_filename, '-map_metadata', '-1', '-c', 'copy', input_filename])
20
+ os.remove(raw_input_filename)
21
+
22
+ st.video(input_filename)
23
+ st.success("🎥 Vídeo carregado e metadados limpos!")
24
+
25
+ st.subheader("🎛️ Ajustes Visuais e Áudio (padrão)")
26
+
27
+ if st.button("🎲 RANDOMIZAR TUDO"):
28
+ st.session_state.zoom_default = random.uniform(1.00, 1.05)
29
+ st.session_state.brilho_default = random.uniform(-0.05, 0.05)
30
+ st.session_state.contraste_default = random.uniform(0.95, 1.05)
31
+ st.session_state.saturacao_default = random.uniform(0.95, 1.05)
32
+ st.session_state.ruido_default = random.randint(3, 15)
33
+ st.session_state.rotacao_default = random.uniform(0.2, 1.5)
34
+ st.session_state.pitch_default = random.uniform(1.00, 1.08)
35
+ st.session_state.fps_val = random.choice([30, 29.97, 25])
36
+ st.session_state.bitrate_default = random.randint(900, 1500)
37
+ st.session_state.velocidade_default = random.uniform(1.00, 1.03)
38
+ st.rerun()
39
+
40
+ zoom_default = st.slider("Zoom (%)", 100, 105, int(st.session_state.get('zoom_default', 1.01) * 100)) / 100
41
+ brilho_default = st.slider("Brilho", -0.1, 0.1, st.session_state.get('brilho_default', 0.01))
42
+ contraste_default = st.slider("Contraste", 0.9, 1.1, st.session_state.get('contraste_default', 1.01))
43
+ saturacao_default = st.slider("Saturação", 0.9, 1.1, st.session_state.get('saturacao_default', 1.01))
44
+ ruido_default = st.slider("Ruído Visual (0-20)", 0, 20, st.session_state.get('ruido_default', 5))
45
+ rotacao_default = st.slider("Rotação (graus)", 0.0, 2.0, st.session_state.get('rotacao_default', 0.5))
46
+ pitch_default = st.slider("Pitch do Áudio (%)", 100, 110, int(st.session_state.get('pitch_default', 1.01) * 100)) / 100
47
+ fps = st.selectbox("FPS Final", [30, 29.97, 25], index=[30, 29.97, 25].index(st.session_state.get('fps_val', 30)))
48
+ bitrate_default = st.slider("Bitrate (kbps)", 800, 2000, st.session_state.get('bitrate_default', 1100))
49
+ velocidade_default = st.slider("Velocidade do Vídeo (%)", 100, 103, int(st.session_state.get('velocidade_default', 1.01) * 100)) / 100
50
+
51
+ st.subheader("🧩 Extras Anti-Detecção")
52
+ usar_marca = st.checkbox("Marca d’água Fantasma com perfil", value=True)
53
+ usar_glitch = st.checkbox("Inserir Frame Preto Aleatório", value=True)
54
+ res_random = st.checkbox("Resolução Aleatória", value=True)
55
+ cortar = st.checkbox("Cortar trecho aleatório do vídeo", value=True)
56
+ embaralhar = st.checkbox("Embaralhar trechos do vídeo", value=True)
57
+
58
+ st.subheader("🎨 Avançado")
59
+ lote_efeitos = st.checkbox("🎨 Aplicar efeitos por lote (aleatórios)", value=True)
60
+ transicoes = st.checkbox("🔄 Transições visuais aleatórias", value=True)
61
+
62
+ st.subheader("🕵️‍♂️ Perfil Fingerprint")
63
+ fingerprint = st.selectbox("Escolha o Perfil", ["Android", "iPhone", "Câmera", "CapCut", "Samsung", "Xiaomi", "LG"])
64
+
65
+ qtd_videos = st.number_input("Quantidade de vídeos únicos:", min_value=1, max_value=10, value=3)
66
+
67
+ if st.button("🎬 Gerar Vídeos Únicos"):
68
+ st.info("Processando vídeos... aguarde!")
69
+ output_files = []
70
+
71
+ if embaralhar:
72
+ temp_dir = f"temp_{uuid.uuid4().hex}"
73
+ os.makedirs(temp_dir, exist_ok=True)
74
+ subprocess.run(['ffmpeg', '-i', input_filename, '-c', 'copy', '-f', 'segment', '-segment_time', '2', f'{temp_dir}/out%03d.mp4'])
75
+ files = os.listdir(temp_dir)
76
+ files.sort()
77
+ random.shuffle(files)
78
+ concat_list = f"{temp_dir}/list.txt"
79
+ with open(concat_list, 'w') as f:
80
+ for file in files:
81
+ f.write(f"file '{os.path.join(temp_dir, file)}'\n")
82
+ shuffled_input = f"shuffled_{uuid.uuid4().hex}.mp4"
83
+ subprocess.run(['ffmpeg', '-f', 'concat', '-safe', '0', '-i', concat_list, '-c', 'copy', shuffled_input])
84
+ shutil.rmtree(temp_dir)
85
+ base_video = shuffled_input if os.path.exists(shuffled_input) else input_filename
86
+ else:
87
+ base_video = input_filename
88
+
89
+ for _ in range(qtd_videos):
90
+ encoder_name = f"{fingerprint}Cam_{random.randint(1000,9999)}"
91
+ final_out = f"{encoder_name}_video_{uuid.uuid4().hex}.mp4"
92
+
93
+ if lote_efeitos:
94
+ zoom_r = random.uniform(1.00, 1.05)
95
+ brilho_r = random.uniform(-0.05, 0.05)
96
+ contraste_r = random.uniform(0.95, 1.05)
97
+ saturacao_r = random.uniform(0.95, 1.05)
98
+ ruido_r = random.randint(3, 15)
99
+ rot_r = random.uniform(0.2, 1.5) * 0.01745
100
+ pitch_r = random.uniform(1.00, 1.08)
101
+ velocidade_r = random.uniform(1.00, 1.03)
102
+ bitrate_r = f"{random.randint(900, 1500)}k"
103
+ else:
104
+ zoom_r = zoom_default
105
+ brilho_r = brilho_default
106
+ contraste_r = contraste_default
107
+ saturacao_r = saturacao_default
108
+ ruido_r = ruido_default
109
+ rot_r = rotacao_default * 0.01745
110
+ pitch_r = pitch_default
111
+ velocidade_r = velocidade_default
112
+ bitrate_r = f"{bitrate_default}k"
113
+
114
+ vf = (
115
+ f"scale=iw*{zoom_r}:ih*{zoom_r},"
116
+ f"crop=iw/{zoom_r}:ih/{zoom_r},"
117
+ f"[email protected]:t=fill,"
118
+ f"eq=brightness={brilho_r}:contrast={contraste_r}:saturation={saturacao_r},"
119
+ f"noise=alls={ruido_r}:allf=t,"
120
+ f"rotate={rot_r}:[email protected]"
121
+ )
122
+
123
+ if usar_marca:
124
+ vf += f",drawtext=text='{encoder_name}':fontcolor=white@0.005:x=10:y=10:fontsize=24"
125
+ if usar_glitch:
126
+ vf += ",blackframe=1:0"
127
+ if res_random:
128
+ w = random.choice([720, 960, 1080])
129
+ h = random.choice([1280, 1440, 1920])
130
+ vf += f",scale={w}:{h}"
131
+ if transicoes:
132
+ effects = [
133
+ "fade=t=in:st=0:d=0.5",
134
+ "fade=t=out:st=3:d=0.5",
135
+ "zoompan=z='min(pzoom+0.0015,1.5)':d=1",
136
+ "drawbox=x=0:y=0:w=iw:h=ih:color=white@0.02:t=fill"
137
+ ]
138
+ vf += "," + random.choice(effects)
139
+
140
+ af = f"asetrate=44100*{pitch_r},aresample=44100"
141
+ profile = "baseline" if fingerprint in ["Android", "Xiaomi"] else "main"
142
+ if fingerprint == "iPhone":
143
+ profile = "high"
144
+ level = "4.0" if fingerprint == "Samsung" else "3.1"
145
+ ar = "44100" if fingerprint in ["iPhone", "Xiaomi"] else "48000"
146
+
147
+ codec_cmd = ['-c:v', 'libx264', '-profile:v', profile, '-level', level]
148
+ audio_cmd = ['-ar', ar]
149
+ filters = ['-vf', vf, '-af', af, '-r', str(fps)]
150
+ speed_filter = ['-filter:v', f"setpts={1/velocidade_r}*PTS"]
151
+ speed_audio = ['-filter:a', f"atempo={velocidade_r}"]
152
+ duration_cmd = ['-ss', str(random.uniform(0, 1))] if cortar else []
153
+
154
+ subprocess.run([
155
+ 'ffmpeg', '-i', base_video, *duration_cmd,
156
+ *filters, *speed_filter, *speed_audio,
157
+ *codec_cmd, '-b:v', bitrate_r,
158
+ *audio_cmd,
159
+ '-preset', 'fast', '-tune', 'zerolatency',
160
+ '-movflags', '+faststart',
161
+ final_out
162
+ ])
163
+
164
+ output_files.append(final_out)
165
+
166
+ if base_video != input_filename and os.path.exists(base_video):
167
+ os.remove(base_video)
168
+ os.remove(input_filename)
169
+
170
+ st.success(f"✅ {qtd_videos} vídeos gerados com fingerprint invisível!")
171
+
172
+ for file in output_files:
173
+ st.video(file)
174
+ with open(file, "rb") as f:
175
+ st.download_button(f"📥 Baixar {file}", data=f, file_name=file, mime="video/mp4")
176
+ os.remove(file)