Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import os | |
| import subprocess | |
| import requests | |
| import time | |
| # 1. Recuperar Segredos | |
| IG_USER_ID = os.environ.get("IG_USER_ID") | |
| ACCESS_TOKEN = os.environ.get("IG_ACCESS_TOKEN") | |
| def processar_e_publicar(video_webm_path): | |
| if not video_webm_path: | |
| return "Erro: Nenhum vídeo recebido." | |
| # --- ETAPA A: CONVERSÃO (WebM -> MP4) --- | |
| print("Iniciando conversão...") | |
| output_filename = "video_final.mp4" | |
| output_path = os.path.abspath(output_filename) | |
| # Comando FFmpeg otimizado para Instagram | |
| command = [ | |
| "ffmpeg", "-y", | |
| "-i", video_webm_path, | |
| "-c:v", "libx264", "-preset", "fast", "-crf", "23", # Video H.264 | |
| "-c:a", "aac", "-b:a", "128k", # Audio AAC | |
| "-pix_fmt", "yuv420p", # Garante compatibilidade mobile | |
| "-movflags", "+faststart", | |
| output_path | |
| ] | |
| subprocess.run(command, check=True) | |
| # --- ETAPA B: GERAR URL PÚBLICA --- | |
| # O Gradio serve arquivos estáticos na rota /file/ | |
| # Precisamos descobrir a URL base do Space dinamicamente ou montar manualmente | |
| # Truque para pegar a URL do Space atual | |
| # Se seu usuario é "Joao" e o space é "Bot", a url é https://joao-bot.hf.space | |
| space_host = os.environ.get("SPACE_HOST") # O HF fornece isso auto em alguns casos | |
| if not space_host: | |
| # Fallback: Tenta construir baseado no user/space se estiver nas envs, | |
| # senão, retornaremos o caminho para debug. | |
| # Mas para simplificar, vamos assumir que o script roda e gera o arquivo local. | |
| # O Gradio retorna o caminho, o cliente (App Builder) vai precisar da URL completa. | |
| pass | |
| # A URL pública do arquivo no Gradio segue este padrão: | |
| # https://{USER}-{SPACE_NAME}.hf.space/file={CAMINHO_ABSOLUTO} | |
| # Vamos deixar o Gradio retornar o arquivo processado, e o próprio Gradio gera o link de download. | |
| # PORÉM, para o Instagram, precisamos passar a URL texto. | |
| # Vamos construir a URL pública manualmente para enviar ao Instagram | |
| # ATENÇÃO: Substitua isso se o HF mudar a estrutura, mas o padrão atual é esse. | |
| # Para automação total, vamos usar uma variável que você preenche ou pegamos do sistema | |
| base_url = f"https://{os.environ.get('SPACE_AUTHOR_NAME')}-{os.environ.get('SPACE_REPO_NAME')}.hf.space" | |
| video_public_url = f"{base_url}/file={output_path}" | |
| print(f"URL Gerada para o Instagram: {video_public_url}") | |
| # --- ETAPA C: PUBLICAR NO INSTAGRAM --- | |
| print("Enviando para o Instagram...") | |
| # 1. Criar Container | |
| url_create = f"https://graph.facebook.com/v19.0/{IG_USER_ID}/media" | |
| payload = { | |
| "media_type": "REELS", | |
| "video_url": video_public_url, | |
| "caption": "Vídeo postado via App Builder 🚀 #AI #Automation", | |
| "access_token": ACCESS_TOKEN | |
| } | |
| req = requests.post(url_create, data=payload) | |
| if req.status_code != 200: | |
| return f"Erro Instagram (Container): {req.text}" | |
| container_id = req.json()['id'] | |
| # 2. Esperar processamento (Polling) | |
| status = "IN_PROGRESS" | |
| while status == "IN_PROGRESS": | |
| time.sleep(5) | |
| status_url = f"https://graph.facebook.com/v19.0/{container_id}?fields=status_code&access_token={ACCESS_TOKEN}" | |
| status_resp = requests.get(status_url).json() | |
| status = status_resp.get('status_code', 'ERROR') | |
| print(f"Status: {status}") | |
| if status == 'ERROR': | |
| return "Erro: Instagram falhou ao processar o vídeo." | |
| # 3. Publicar | |
| url_publish = f"https://graph.facebook.com/v19.0/{IG_USER_ID}/media_publish" | |
| pub_payload = { | |
| "creation_id": container_id, | |
| "access_token": ACCESS_TOKEN | |
| } | |
| final_req = requests.post(url_publish, data=pub_payload) | |
| if final_req.status_code == 200: | |
| return f"SUCESSO! Vídeo publicado. ID: {final_req.json()['id']}" | |
| else: | |
| return f"Erro Instagram (Publish): {final_req.text}" | |
| # Interface (API) | |
| demo = gr.Interface( | |
| fn=processar_e_publicar, | |
| inputs=gr.Video(label="Upload WebM"), # Recebe o vídeo | |
| outputs="text" # Retorna a mensagem de sucesso/erro | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() |