Spaces:
Sleeping
Sleeping
Update app.py
Browse filesadição de legendas .ass
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 |
+
|