pcdoido2 commited on
Commit
c6b9f04
·
verified ·
1 Parent(s): 17762c9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -23
app.py CHANGED
@@ -64,6 +64,8 @@ st.write("### Efeitos PRO")
64
  ativar_zoom_dinamico = st.checkbox("Ativar Zoom/Pan Dinâmico (Movimento de câmera)", value=False)
65
  ativar_color_grading = st.checkbox("Aplicar Color Grading Aleatório", value=False)
66
  ativar_transicoes = st.checkbox("Adicionar Transições Cinemáticas", value=False)
 
 
67
 
68
  # Efeitos extras
69
  st.write("### Outros efeitos")
@@ -94,7 +96,6 @@ if st.button("Gerar Vídeo(s)"):
94
  with open(fundo_path, "wb") as f:
95
  f.write(video_fundo.read())
96
  else:
97
- # Gera fundo preto 720x1280 com duração longa
98
  subprocess.run([
99
  "ffmpeg", "-f", "lavfi", "-i", "color=black:s=720x1280:d=600",
100
  "-c:v", "libx264", "-t", str(duracao_final),
@@ -113,7 +114,7 @@ if st.button("Gerar Vídeo(s)"):
113
  "-y", tutorial_mp4
114
  ], check=True, stderr=subprocess.PIPE)
115
 
116
- # Padronizar vídeos de cortes para 1280x720 com múltiplos de 2
117
  cortes_names = []
118
  for idx, corte in enumerate(cortes):
119
  path_in = os.path.join(temp_dir, f"corte_in_{idx}.mp4")
@@ -126,7 +127,8 @@ if st.button("Gerar Vídeo(s)"):
126
  "-c:v", "libx264", "-preset", "ultrafast", "-crf", "30", path_out
127
  ], check=True, stderr=subprocess.PIPE)
128
  cortes_names.append(path_out)
129
- # ✅ Cortar o vídeo de fundo para a duração final
 
130
  fundo_cortado = os.path.join(temp_dir, "fundo_cortado.mp4")
131
  subprocess.run([
132
  "ffmpeg", "-i", fundo_path, "-t", str(duracao_final),
@@ -153,21 +155,33 @@ if st.button("Gerar Vídeo(s)"):
153
  out = os.path.join(temp_dir, f"cut_{random.randint(1000,9999)}.mp4")
154
 
155
  filtros_corte = []
156
- # Aplica zoom dinâmico se ativado
 
157
  if ativar_zoom_dinamico:
158
- # Movimento aleatório para cima/baixo/esquerda/direita
159
- movimentos = [
160
- "crop=in_w-20:in_h-20:0:0,zoompan=z='zoom+0.001':d=125",
161
- "crop=in_w-20:in_h-20:20:0,zoompan=z='zoom+0.0015':d=125",
162
- "crop=in_w-20:in_h-20:0:20,zoompan=z='zoom+0.0015':d=125"
163
- ]
164
- filtros_corte.append(random.choice(movimentos))
165
  else:
166
  filtros_corte.append("scale=trunc(iw/2)*2:trunc(ih/2)*2")
167
 
168
- # Transição: Adiciona fade in/out aleatório
169
  if ativar_transicoes:
170
- filtros_corte.append("fade=t=in:st=0:d=0.5,fade=t=out:st=4.5:d=0.5")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
 
172
  filtro_final = ",".join(filtros_corte)
173
 
@@ -183,8 +197,7 @@ if st.button("Gerar Vídeo(s)"):
183
  break
184
  except:
185
  continue
186
-
187
- # Concatenação dos cortes com ajuste para múltiplos de 2
188
  lista = os.path.join(temp_dir, f"lista_{n}.txt")
189
  with open(lista, "w") as f:
190
  for c in cortes_prontos:
@@ -196,8 +209,10 @@ if st.button("Gerar Vídeo(s)"):
196
  "-vf", "scale=trunc(iw/2)*2:trunc(ih/2)*2",
197
  "-c:v", "libx264", "-preset", "ultrafast", "-crf", "30", video_raw
198
  ], check=True, stderr=subprocess.PIPE)
 
199
  progresso.progress(35 + n * 5)
200
- # Filtros aplicados ao vídeo principal
 
201
  filtros_main = ["scale=720:1280:force_original_aspect_ratio=decrease"]
202
 
203
  if zoom != 1.0:
@@ -214,24 +229,24 @@ if st.button("Gerar Vídeo(s)"):
214
  if ativar_filtro_cor:
215
  filtros_main.append("eq=contrast=1.1:saturation=1.2")
216
 
217
- # Aplica Color Grading aleatório se ativado
218
  if ativar_color_grading:
219
  opcoes_color = [
220
  "curves=preset=vintage",
221
  "curves=preset=strong_contrast",
222
- "curves=preset=color_negative",
223
- "hue=s=0.5",
224
- "eq=brightness=0.05:saturation=1.5:contrast=1.2"
225
  ]
226
  filtros_main.append(random.choice(opcoes_color))
227
 
228
- # Garantir múltiplos de 2 no final (sempre)
229
  filtros_main.append("scale=trunc(iw/2)*2:trunc(ih/2)*2")
230
  # Montar filter_complex
231
  filtro_complex = (
232
  f"[0:v]scale=720:1280:force_original_aspect_ratio=increase,"
233
  f"crop=720:1280"
234
  )
 
235
  if ativar_blur_fundo:
236
  filtro_complex += f",boxblur={blur_strength}:1"
237
  if ativar_sepia:
@@ -246,7 +261,7 @@ if st.button("Gerar Vídeo(s)"):
246
 
247
  filtro_complex += f"[1:v]{','.join(filtros_main)}[zoomed];"
248
  filtro_complex += "[blur][zoomed]overlay=(W-w)/2:(H-h)/2[base]"
249
-
250
  if ativar_texto and texto_personalizado.strip():
251
  y_pos = "100" if posicao_texto == "Topo" else "(h-text_h)/2" if posicao_texto == "Centro" else "h-text_h-100"
252
  enable = f":enable='lt(t\\,{segundos_texto})'" if duracao_texto == "Apenas primeiros segundos" else ""
@@ -342,7 +357,6 @@ if st.button("Gerar Vídeo(s)"):
342
  ], check=True, stderr=subprocess.PIPE)
343
 
344
  else:
345
- # Se não tiver música, só copia o vídeo final
346
  final_name = f"video_final_{n}_{int(time.time())}.mp4"
347
  shutil.copy(video_final_raw, final_name)
348
 
 
64
  ativar_zoom_dinamico = st.checkbox("Ativar Zoom/Pan Dinâmico (Movimento de câmera)", value=False)
65
  ativar_color_grading = st.checkbox("Aplicar Color Grading Aleatório", value=False)
66
  ativar_transicoes = st.checkbox("Adicionar Transições Cinemáticas", value=False)
67
+ ativar_freeze_frame = st.checkbox("Aplicar Freeze Frame automático", value=False)
68
+ ativar_slow_motion = st.checkbox("Aplicar Slow Motion Inteligente aleatório", value=False)
69
 
70
  # Efeitos extras
71
  st.write("### Outros efeitos")
 
96
  with open(fundo_path, "wb") as f:
97
  f.write(video_fundo.read())
98
  else:
 
99
  subprocess.run([
100
  "ffmpeg", "-f", "lavfi", "-i", "color=black:s=720x1280:d=600",
101
  "-c:v", "libx264", "-t", str(duracao_final),
 
114
  "-y", tutorial_mp4
115
  ], check=True, stderr=subprocess.PIPE)
116
 
117
+ # Padronizar vídeos de cortes
118
  cortes_names = []
119
  for idx, corte in enumerate(cortes):
120
  path_in = os.path.join(temp_dir, f"corte_in_{idx}.mp4")
 
127
  "-c:v", "libx264", "-preset", "ultrafast", "-crf", "30", path_out
128
  ], check=True, stderr=subprocess.PIPE)
129
  cortes_names.append(path_out)
130
+
131
+ # Cortar fundo para a duração final
132
  fundo_cortado = os.path.join(temp_dir, "fundo_cortado.mp4")
133
  subprocess.run([
134
  "ffmpeg", "-i", fundo_path, "-t", str(duracao_final),
 
155
  out = os.path.join(temp_dir, f"cut_{random.randint(1000,9999)}.mp4")
156
 
157
  filtros_corte = []
158
+
159
+ # ✅ Zoom/Pan Dinâmico corrigido
160
  if ativar_zoom_dinamico:
161
+ filtros_corte.append("scale=iw*1.05:ih*1.05,crop=iw-20:ih-20")
 
 
 
 
 
 
162
  else:
163
  filtros_corte.append("scale=trunc(iw/2)*2:trunc(ih/2)*2")
164
 
165
+ # Transições Cinemáticas
166
  if ativar_transicoes:
167
+ filtros_corte.append("fade=t=in:st=0:d=0.3,fade=t=out:st=4.7:d=0.3")
168
+
169
+ # ✅ Slow Motion Inteligente (aleatório)
170
+ aplicar_slow = ativar_slow_motion and random.random() < 0.3
171
+ if aplicar_slow:
172
+ filtros_corte.append("setpts=1.5*PTS")
173
+
174
+ # ✅ Freeze Frame (aleatório, 0.5s no meio)
175
+ aplicar_freeze = ativar_freeze_frame and random.random() < 0.3
176
+ if aplicar_freeze:
177
+ freeze_frame = os.path.join(temp_dir, f"freeze_{random.randint(1000,9999)}.mp4")
178
+ subprocess.run([
179
+ "ffmpeg", "-ss", str(ini + duracao_corte/2), "-i", c,
180
+ "-t", "0.001", "-vf", "scale=1280:720", "-c:v", "libx264",
181
+ "-y", freeze_frame
182
+ ], check=True, stderr=subprocess.PIPE)
183
+ cortes_prontos.append(freeze_frame)
184
+ tempo_total += 0.5
185
 
186
  filtro_final = ",".join(filtros_corte)
187
 
 
197
  break
198
  except:
199
  continue
200
+ # Concatenação dos cortes
 
201
  lista = os.path.join(temp_dir, f"lista_{n}.txt")
202
  with open(lista, "w") as f:
203
  for c in cortes_prontos:
 
209
  "-vf", "scale=trunc(iw/2)*2:trunc(ih/2)*2",
210
  "-c:v", "libx264", "-preset", "ultrafast", "-crf", "30", video_raw
211
  ], check=True, stderr=subprocess.PIPE)
212
+
213
  progresso.progress(35 + n * 5)
214
+
215
+ # Filtros aplicados ao vídeo principal (sobre o vídeo de cortes)
216
  filtros_main = ["scale=720:1280:force_original_aspect_ratio=decrease"]
217
 
218
  if zoom != 1.0:
 
229
  if ativar_filtro_cor:
230
  filtros_main.append("eq=contrast=1.1:saturation=1.2")
231
 
232
+ # Color Grading aleatório
233
  if ativar_color_grading:
234
  opcoes_color = [
235
  "curves=preset=vintage",
236
  "curves=preset=strong_contrast",
237
+ "eq=brightness=0.05:saturation=1.4:contrast=1.3",
238
+ "hue=s=0.6",
239
+ "colorchannelmixer=.5:0:.5:0:.5:0:.5:0:.5:0:.5"
240
  ]
241
  filtros_main.append(random.choice(opcoes_color))
242
 
 
243
  filtros_main.append("scale=trunc(iw/2)*2:trunc(ih/2)*2")
244
  # Montar filter_complex
245
  filtro_complex = (
246
  f"[0:v]scale=720:1280:force_original_aspect_ratio=increase,"
247
  f"crop=720:1280"
248
  )
249
+
250
  if ativar_blur_fundo:
251
  filtro_complex += f",boxblur={blur_strength}:1"
252
  if ativar_sepia:
 
261
 
262
  filtro_complex += f"[1:v]{','.join(filtros_main)}[zoomed];"
263
  filtro_complex += "[blur][zoomed]overlay=(W-w)/2:(H-h)/2[base]"
264
+
265
  if ativar_texto and texto_personalizado.strip():
266
  y_pos = "100" if posicao_texto == "Topo" else "(h-text_h)/2" if posicao_texto == "Centro" else "h-text_h-100"
267
  enable = f":enable='lt(t\\,{segundos_texto})'" if duracao_texto == "Apenas primeiros segundos" else ""
 
357
  ], check=True, stderr=subprocess.PIPE)
358
 
359
  else:
 
360
  final_name = f"video_final_{n}_{int(time.time())}.mp4"
361
  shutil.copy(video_final_raw, final_name)
362