# -*- 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.")