Código em python:
import os
import csv
import json
import random
from datetime import datetime, timedelta
import google.generativeai as genai
from moviepy import VideoFileClip
# Configuração da API do Google (Gemini)
GOOGLE_API_KEY = “SUA CHAVE AQUI”
genai.configure(api_key=GOOGLE_API_KEY)
# Configuração para transcrição literal
stt_config = {
“temperature”: 0.0,
“top_p”: 0.95,
“top_k”: 40,
“max_output_tokens”: 1024,
“response_mime_type”: “text/plain”,
}
# Configuração para geração de conteúdo JSON (Metricool/SEO)
seo_config = {
“temperature”: 0.7,
“top_p”: 0.95,
“top_k”: 40,
“max_output_tokens”: 2048,
“response_mime_type”: “application/json”,
}
model_stt = genai.GenerativeModel(model_name=”gemini-2.0-flash”, generation_config=stt_config)
model_seo = genai.GenerativeModel(model_name=”gemini-2.0-flash”, generation_config=seo_config)
def transcrever_video(caminho_video):
“””Extrai áudio e transcreve o conteúdo falado.”””
audio_temp = “temp_audio.wav”
try:
video = VideoFileClip(caminho_video)
if video.audio is None: return “[Sem áudio]”
video.audio.write_audiofile(audio_temp, fps=16000, nbytes=2, codec=’pcm_s16le’, ffmpeg_params=[“-ac”, “1”], logger=None)
video.close()
uploaded_file = genai.upload_file(path=audio_temp)
prompt = “Escreva APENAS o texto falado neste áudio. Transcreva exatamente o que ouvir.”
response = model_stt.generate_content([prompt, uploaded_file])
genai.delete_file(uploaded_file.name)
return response.text.strip()
except Exception as e: return f”[Erro STT: {e}]”
finally:
if os.path.exists(audio_temp): os.remove(audio_temp)
def gerar_conteudo_seo(transcricao):
“””Gera metadados SEO em formato JSON para o Metricool.”””
if not transcricao or “[” in transcricao: return None
prompt = f”””
Analise a seguinte transcrição de vídeo e gere conteúdo SEO estratégico:
Transcrição: “{transcricao}”
REQUISITOS:
1. Crie TRÊS descrições diferentes e otimizadas para SEO:
– Uma focada no Instagram/Facebook (mais visual e engajadora).
– Uma focada no TikTok (mais casual, trend-based).
– Uma focada no YouTube Shorts (focada em busca e curiosidade).
2. No final de CADA descrição, inclua exatamente 2 hashtags estratégicas.
3. Título curto e chamativo para YouTube (máx 100 caracteres).
4. Tags para YouTube separadas por vírgula.
O retorno DEVE ser um JSON nas chaves:
“descricao_ig”, “descricao_tt”, “descricao_yt”, “titulo_yt”, “tags_yt”
“””
try:
response = model_seo.generate_content(prompt)
content = response.text.strip()
# Limpar possíveis restos de markdown se o modelo não respeitar o MIME type
if content.startswith(““`json”):
content = content.replace(““`json”, “”).replace(““`”, “”).strip()
data = json.loads(content)
# Se o modelo retornar uma lista com um dicionário (comum em alguns comportamentos de prompt)
if isinstance(data, list) and len(data) > 0:
return data[0]
return data
except Exception as e:
print(f”❌ Erro ao gerar SEO: {e}”)
return None
def gerar_relatorio_csv():
# Coleta todos os vídeos .mp4 na pasta atual que não começam com ok_
videos_lista = [f for f in os.listdir(‘.’) if f.lower().endswith(‘.mp4’) and not f.startswith(‘ok_’)]
if not videos_lista:
print(“❌ Nenhum vídeo .mp4 (novo) encontrado na pasta.”)
return
# Limitar a 192 vídeos e embaralhar para serem aleatórios
random.shuffle(videos_lista)
videos_selecionados = videos_lista[:21]
template_path = ‘Modelo.csv’
if not os.path.exists(template_path):
print(f”❌ Erro: Arquivo template ‘{template_path}’ não encontrado.”)
return
# Lendo o cabeçalho original do Metricool
with open(template_path, mode=’r’, encoding=’utf-8′) as f:
reader = csv.reader(f)
header = next(reader)
print(f”🚀 Processando {len(videos_selecionados)} vídeos para o padrão Metricool…”)
# Lista de colunas booleanas para garantir que tenham true/false
colunas_booleanas = [
‘Draft’, ‘Facebook’, ‘Twitter/X’, ‘LinkedIn’, ‘GBP’, ‘Instagram’,
‘Pinterest’, ‘TikTok’, ‘Youtube’, ‘Threads’, ‘Bluesky’,
‘Youtube video for kids’, ‘TikTok disable comments’, ‘TikTok disable duet’,
‘TikTok disable stitch’, ‘TikTok Branded Content’, ‘TikTok Your Brand’,
‘TikTok Auto Add Music’, ‘Instagram Show Reel On Feed’
]
# Configuração de data dinâmica (Daqui a 1 hora)
hoje = datetime.now()
data_inicio = hoje + timedelta(hours=1)
novas_linhas = []
for i, video_name in enumerate(videos_selecionados):
print(f”🎙️ [{i+1}/{len(videos_selecionados)}] Transcrevendo: {video_name}…”)
texto = transcrever_video(video_name)
print(f”🤖 Gerando conteúdo IA…”)
seo = gerar_conteudo_seo(texto)
if not seo:
seo = {k: “” for k in [“descricao_ig”, “descricao_tt”, “descricao_yt”, “titulo_yt”, “tags_yt”]}
# Cálculo do agendamento: 3 vídeos por dia
dias_offset = i // 3
slot = i % 3
# Slot 1: 09:00 | Slot 2: 14:00 | Slot 3: 19:00
horas_slots = [9, 14, 19]
hora_base = horas_slots[slot]
data_hora_base = (hoje + timedelta(days=dias_offset + 1)).replace(
hour=hora_base, minute=0, second=0, microsecond=0
)
# Jitter de até 60 minutos dentro do slot (mais curto para não sobrepor)
jitter_minutos = random.randint(0, 59)
segundo_aleatorio = random.randint(0, 59)
# Ajustar a hora base com o jitter
data_hora_base = data_hora_base + timedelta(minutes=jitter_minutos, seconds=segundo_aleatorio)
# Renomear o arquivo fisicamente
novo_nome = f”ok_{video_name}”
try:
os.rename(video_name, novo_nome)
video_final_nome = novo_nome
except Exception as e:
print(f”⚠️ Erro ao renomear {video_name}: {e}”)
video_final_nome = video_name
# Criar os 3 agendamentos (linhas) para este vídeo
plataformas_config = [
# (Plataformas, Descrição, Minutos Adicionais em relação ao vídeo)
([‘Instagram’, ‘Facebook’], ‘descricao_ig’, 0),
([‘TikTok’], ‘descricao_tt’, 2),
([‘Youtube’], ‘descricao_yt’, 4)
]
for platforms, seo_key, total_mins_offset in plataformas_config:
# Calculando horário específico desta linha
data_hora_agendada = (data_hora_base + timedelta(minutes=total_mins_offset)).replace(second=segundo_aleatorio)
# Criando dicionário da linha com valores padrão “”
row_dict = {col: “” for col in header}
# Inicializar colunas booleanas como ‘false’ por padrão
for col in colunas_booleanas:
if col in row_dict:
row_dict
row_dict[‘Date’] = data_hora_agendada.strftime(‘%Y-%m-%d’)
row_dict[‘Time’] = data_hora_agendada.strftime(‘%H:%M:%S’)
row_dict[‘Picture Url 1’] = f”https://www.thiagoprogramador.com/videos/{video_final_nome}”
row_dict[‘Draft’] = ‘false’
row_dict[‘Text’] = seo.get(seo_key, ‘Vídeo gerado por Thiago Programador’)
# Ativando as plataformas específicas desta linha
for p in platforms:
if p in row_dict: row_dict[p] = ‘true’
# Configurações de Tipo e Privacidade
if ‘Instagram’ in platforms:
row_dict[‘Instagram Post Type’] = ‘REEL’
row_dict[‘Instagram Show Reel On Feed’] = ‘true’
if ‘Facebook’ in platforms:
row_dict[‘Facebook Post Type’] = ‘REEL’
if ‘Youtube’ in platforms:
row_dict[‘Youtube Video Type’] = ‘SHORT’
row_dict[‘Youtube Video Privacy’] = ‘PUBLIC’
row_dict[‘Youtube Video Title’] = seo.get(‘titulo_yt’, ”)
row_dict[‘Youtube Video Tags’] = seo.get(‘tags_yt’, ”)
if ‘TikTok’ in platforms:
row_dict[‘TikTok Post Privacy’] = ‘PUBLIC_TO_EVERYONE’
row_dict[‘TikTok Photo Cover Index’] = ‘0’
# Limpando títulos redundantes
row_dict[‘Facebook Title’] = “”
row_dict[‘TikTok Title’] = “”
# Adicionar linha final
novas_linhas.append([row_dict.get(col, “”) for col in header])
nome_final = ‘dados_metricool.csv’
with open(nome_final, mode=’w’, newline=”, encoding=’utf-8′) as f:
writer = csv.writer(f)
writer.writerow(header)
writer.writerows(novas_linhas)
print(f”\n✨ Sucesso! Arquivo ‘{nome_final}’ pronto com {len(videos_selecionados)} agendamentos.”)
if __name__ == “__main__”:
gerar_relatorio_csv()


