# -*- 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 import openai # --- Configurações (Substitua os placeholders) --- VIDEO_URL = "https://www.youtube.com/watch?v=1htKBjuUWec" # Substitua pela URL do vídeo do YouTube OUTPUT_DIR = "./audio_analysis_output" # Diretório para salvar o áudio AUDIO_FILENAME = "downloaded_audio" TRANSCRIPT_FILENAME = "transcript.txt" AUDIO_PATH = os.path.join(OUTPUT_DIR, AUDIO_FILENAME) TRANSCRIPT_PATH = os.path.join(OUTPUT_DIR, TRANSCRIPT_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', 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best', '-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 def extract_text_from_audio(audio_path, output_txt_path=None) -> str: """ Usa a API Whisper da OpenAI para transcrever o áudio em texto com quebras de linha naturais, removendo timestamps e IDs. Salva em arquivo .txt se o caminho for fornecido. """ try: openai.api_key = os.getenv("OPENAI_API_KEY") print(f"Iniciando transcrição (formato SRT simplificado): {audio_path}") with open(audio_path, "rb") as audio_file: srt_result = openai.Audio.transcribe( model="whisper-1", file=audio_file, response_format="srt" ) # Remove linhas com números e timestamps lines = srt_result.splitlines() only_text = [line.strip() for line in lines if not re.match(r"^\d+$", line) and "-->" not in line] formatted_text = "\n".join(only_text) # Salva em .txt se desejado if output_txt_path: with open(output_txt_path, "w", encoding="utf-8") as f: f.write(formatted_text) print(f"Transcrição salva em: {output_txt_path}") return formatted_text except Exception as e: print(f"Erro ao transcrever áudio: {e}") return "" # --- 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_audio(VIDEO_URL, AUDIO_PATH): print(f"Vídeo salvo em: {AUDIO_PATH}") video_downloaded_or_exists = True else: print("Falha no download do vídeo. Pulando etapas dependentes.") elif os.path.exists(AUDIO_PATH): print(f"URL não fornecida, mas vídeo encontrado em {AUDIO_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.") if False: # Etapa 2: Extrair frames if video_downloaded_or_exists: extract_text_from_audio(AUDIO_PATH + '.mp3', TRANSCRIPT_PATH) else: print("Pulando extração de frames pois o vídeo não está disponível.")