Spaces:
Sleeping
Sleeping
# -*- coding: utf-8 -*- | |
""" | |
Script para baixar um vídeo do YouTube, extrair frames, analisar com GPT-4o e contar aves. | |
""" | |
import os | |
import subprocess | |
import cv2 | |
import base64 | |
import time | |
import json | |
import re | |
# --- Configurações (Substitua os placeholders) --- | |
VIDEO_URL = "https://www.youtube.com/watch?v=L1vXCYZAYYM" # Substitua pela URL do vídeo do YouTube | |
RESULTS_FILE = os.path.join(OUTPUT_DIR, "analysis_results.json") | |
OUTPUT_DIR = "./video_analysis_output" # Diretório para salvar o vídeo e os frames | |
AUDIO_FILENAME = "downloaded_audio" | |
VIDEO_PATH = os.path.join(OUTPUT_DIR, AUDIO_FILENAME) | |
# Verifica se a URL foi definida | |
if VIDEO_URL == "URL_DO_SEU_VIDEO_AQUI": | |
print("AVISO: A URL do vídeo não foi definida. Por favor, edite o script e insira a URL desejada.") | |
# exit(1) | |
# --- Funções --- | |
def create_output_directory(): | |
"""Cria o diretório de saída se não existir.""" | |
if not os.path.exists(OUTPUT_DIR): | |
os.makedirs(OUTPUT_DIR) | |
print(f"Diretório criado: {OUTPUT_DIR}") | |
def retirar_sufixo_codec_arquivo(directory) -> None: | |
for filename in os.listdir(directory): | |
# Procura padrão como ".f123" antes da extensão | |
new_filename = re.sub(r'\.f\d{3}(?=\.\w+$)', '', filename) | |
if new_filename != filename: | |
old_path = os.path.join(directory, filename) | |
new_path = os.path.join(directory, new_filename) | |
os.rename(old_path, new_path) | |
print(f"Renomeado: {filename} → {new_filename}") | |
def download_audio(url, output_path): | |
"""Baixa apenas o áudio do YouTube usando yt-dlp.""" | |
print(f"Baixando áudio de {url} para {output_path}...") | |
try: | |
# Comando yt-dlp para baixar o melhor áudio disponível e convertê-lo para mp3 | |
command = [ | |
'yt-dlp', | |
'-f', 'bestaudio', | |
'--extract-audio', | |
'--audio-format', 'mp3', # Pode ser 'mp3', 'm4a', 'wav', etc. | |
'-o', output_path, | |
url | |
] | |
result = subprocess.run(command, check=True, capture_output=True, text=True) | |
retirar_sufixo_codec_arquivo(OUTPUT_DIR) | |
print("Download de áudio concluído com sucesso.") | |
return True | |
except subprocess.CalledProcessError as e: | |
print(f"Erro ao baixar o áudio: {e}") | |
print(f"Saída do erro: {e.stderr}") | |
return False | |
except FileNotFoundError: | |
print("Erro: O comando 'yt-dlp' não foi encontrado. Certifique-se de que ele está instalado e no PATH do sistema.") | |
return False | |
# --- Atualização do Bloco Principal --- | |
# (Adicionar inicialização do cliente OpenAI e o loop de análise) | |
if __name__ == "__main__": | |
create_output_directory() | |
# Etapa 1: Baixar o vídeo | |
video_downloaded_or_exists = False | |
if VIDEO_URL != "URL_DO_SEU_VIDEO_AQUI": | |
if download_video(VIDEO_URL, VIDEO_PATH): | |
print(f"Vídeo salvo em: {VIDEO_PATH}") | |
video_downloaded_or_exists = True | |
else: | |
print("Falha no download do vídeo. Pulando etapas dependentes.") | |
elif os.path.exists(VIDEO_PATH): | |
print(f"URL não fornecida, mas vídeo encontrado em {VIDEO_PATH}. Tentando processar.") | |
video_downloaded_or_exists = True | |
else: | |
print("URL do vídeo não fornecida e vídeo local não encontrado. Pulando download e extração.") | |
# Etapa 2: Extrair frames | |
if video_downloaded_or_exists: | |
extracted_frames = extract_frames(VIDEO_PATH, OUTPUT_DIR, FRAME_INTERVAL_SECONDS) | |
else: | |
print("Pulando extração de frames pois o vídeo não está disponível.") | |
# Etapa 3 e 4: Codificar e Analisar Frames | |
if extracted_frames and openai_client: | |
print(f"\nIniciando análise de {len(extracted_frames)} frames com {GPT_MODEL}...") | |
for frame_path in extracted_frames: | |
print(f"\nProcessando frame: {frame_path}") | |
# Extrai timestamp do nome do arquivo, se possível | |
timestamp_str = "unknown" | |
try: | |
# Exemplo: frame_0000_time_0.00s.png | |
parts = os.path.basename(frame_path).split('_') | |
if len(parts) >= 4 and parts[2] == 'time': | |
timestamp_str = parts[3].replace('s.png','') | |
except Exception: | |
pass # Mantém 'unknown' se o parsing falhar | |
# Codifica o frame | |
base64_image = encode_frame_to_base64(frame_path) | |
if base64_image: | |
# Analisa o frame com GPT-4o | |
# analysis_result = analyze_frame_with_gpt4o(openai_client, base64_image, PROMPT_TEXT) | |
result_entry = { | |
"frame_path": frame_path, | |
"timestamp_approx_sec": timestamp_str, | |
"analysis": f' pulado frame {frame_path}' #analysis_result | |
} | |
analysis_results_list.append(result_entry) | |
# Pausa opcional para evitar rate limiting | |
time.sleep(1) # Pausa de 1 segundo entre as chamadas | |
else: | |
print(f"Falha ao codificar o frame {frame_path}. Pulando análise.") | |
analysis_results_list.append({ | |
"frame_path": frame_path, | |
"timestamp_approx_sec": timestamp_str, | |
"analysis": {"error": "Failed to encode frame to base64."} | |
}) | |
print("\nAnálise de todos os frames concluída.") | |
elif not extracted_frames: | |
print("Nenhum frame foi extraído. Pulando etapa de análise.") | |
elif not openai_client: | |
print("Cliente OpenAI não inicializado (verifique a API Key). Pulando etapa de análise.") | |
# Próxima etapa: Compilar resultados | |
print(f"\nPróxima etapa a ser implementada: Compilação dos resultados ({len(analysis_results_list)} análises) em um relatório.") | |
# ... (código anterior para inicialização, download, extração, análise) ... | |
# Etapa 5: Compilar e Salvar Resultados | |
if analysis_results_list: | |
print(f"\nCompilando {len(analysis_results_list)} resultados da análise...") | |
if save_results_to_json(analysis_results_list, RESULTS_FILE): | |
print("Compilação e salvamento dos resultados concluídos.") | |
else: | |
print("Falha ao salvar os resultados da análise.") | |
else: | |
print("Nenhum resultado de análise para compilar.") | |
print("\n--- Processo de Análise de Vídeo Concluído ---") | |
print(f"Verifique o diretório '{OUTPUT_DIR}' para os frames extraídos (se aplicável).") | |
print(f"Verifique o arquivo '{RESULTS_FILE}' para os resultados da análise (se aplicável).") | |
print("Lembre-se de substituir os placeholders para URL_DO_SEU_VIDEO_AQUI e SUA_CHAVE_API_OPENAI_AQUI no script.") | |