jcnok commited on
Commit
131c8cf
·
verified ·
1 Parent(s): 73228b4

Update app.py

Browse files

adição de legendas .ass

Files changed (1) hide show
  1. app.py +83 -0
app.py CHANGED
@@ -220,3 +220,86 @@ async def get_duration(file: UploadFile = File(...)):
220
  os.remove(temp_input_path)
221
  print(f"Cleaned up temporary file: {temp_input_path}")
222
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  os.remove(temp_input_path)
221
  print(f"Cleaned up temporary file: {temp_input_path}")
222
 
223
+ # ==============================================================================
224
+ # 4. ENDPOINT PARA ADICIONAR LEGENDAS
225
+ # ==============================================================================
226
+
227
+ @app.post("/add-subtitles/")
228
+ async def add_subtitles(
229
+ video_file: UploadFile = File(...),
230
+ subtitle_file: UploadFile = File(...)
231
+ ):
232
+ """
233
+ Adiciona ('queima') um arquivo de legenda (.ass) a um vídeo.
234
+
235
+ Este endpoint espera o upload de dois arquivos: o vídeo base e o
236
+ arquivo de legenda. Ele usa o filtro 'ass' do FFmpeg para renderizar
237
+ as legendas diretamente no vídeo.
238
+
239
+ Args:
240
+ video_file (UploadFile): O arquivo de vídeo de entrada (ex: .mp4).
241
+ subtitle_file (UploadFile): O arquivo de legenda no formato .ass.
242
+
243
+ Returns:
244
+ FileResponse: O vídeo final com as legendas "queimadas".
245
+ """
246
+ # --- Setup do Ambiente Temporário ---
247
+ unique_id = str(uuid.uuid4())
248
+ temp_processing_dir = os.path.join(TEMP_DIR, unique_id)
249
+ os.makedirs(temp_processing_dir)
250
+
251
+ # Define os caminhos para os arquivos de entrada e saída
252
+ video_input_path = os.path.join(temp_processing_dir, video_file.filename)
253
+ subtitle_input_path = os.path.join(temp_processing_dir, "subtitle.ass") # Nome padronizado
254
+ final_output_path = os.path.join(temp_processing_dir, f"video_with_subtitles.mp4")
255
+
256
+ try:
257
+ # --- ETAPA 1: Salvar os arquivos recebidos no disco ---
258
+ print("--- STEP 1 (Subtitles): Saving uploaded files ---")
259
+ # Salva o vídeo
260
+ with open(video_input_path, "wb") as buffer:
261
+ shutil.copyfileobj(video_file.file, buffer)
262
+ print(f"Video saved to: {video_input_path}")
263
+
264
+ # Salva a legenda
265
+ with open(subtitle_input_path, "wb") as buffer:
266
+ shutil.copyfileobj(subtitle_file.file, buffer)
267
+ print(f"Subtitle saved to: {subtitle_input_path}")
268
+
269
+ # --- ETAPA 2: Construir e Executar o Comando FFmpeg ---
270
+ print("--- STEP 2 (Subtitles): Executing FFmpeg command ---")
271
+
272
+ # O filtro `ass` precisa de um caminho de arquivo. Como o ffmpeg é executado
273
+ # a partir da raiz, precisamos fornecer o caminho completo. Para evitar problemas
274
+ # com espaços ou caracteres especiais, usamos shlex.quote.
275
+ # O filtro do Windows pode precisar de uma sintaxe de escape diferente,
276
+ # mas para o ambiente Linux do Hugging Face, isto é o ideal.
277
+ escaped_subtitle_path = subtitle_input_path.replace("'", "'\\''")
278
+
279
+ command = (
280
+ f"ffmpeg -i {shlex.quote(video_input_path)} "
281
+ f"-vf \"ass='{escaped_subtitle_path}'\" "
282
+ f"-c:v libx264 -preset ultrafast -c:a copy "
283
+ f"{shlex.quote(final_output_path)}"
284
+ )
285
+
286
+ await run_subprocess(command)
287
+
288
+ print(f"--- SUCCESS: Final video with subtitles created at {final_output_path} ---")
289
+
290
+ # --- ETAPA 3: Retornar o arquivo e agendar a limpeza ---
291
+ cleanup_task = BackgroundTask(cleanup_directory, directory_path=temp_processing_dir)
292
+ return FileResponse(
293
+ path=final_output_path,
294
+ filename="video_com_legenda.mp4",
295
+ media_type="video/mp4",
296
+ background=cleanup_task
297
+ )
298
+
299
+ except Exception as e:
300
+ print(f"\n--- AN ERROR OCCURRED in /add-subtitles/ ---")
301
+ print(f"Error Details: {e}")
302
+ print("-------------------------------------------\n")
303
+ cleanup_directory(directory_path=temp_processing_dir)
304
+ raise HTTPException(status_code=500, detail=str(e))
305
+