Adicionar B-Roll a Vídeo
Adiciona um pequeno número de cortes visuais baseados em evidências à sequência canônica do Protocolo de Projeto compreendido. Leia broll-rules.md antes de planejar ou adquirir qualquer mídia. Use example-broll-plan.json como referência de formato do plano.
Contrato Inegociável
Siga todas as regras editoriais, de proveniência, de still, de revisão, de recuperação e de entrega em broll-rules.md. Operacionalmente:
- Use os scripts fornecidos para aquisição, validação, normalização, aplicação de recibo e verificação. Nunca use um caminho de download bruto ou substitua por outra fonte de banco de imagens.
- Nunca invente autoridade humana. A revisão do agente requer delegação explícita e um recibo do Agente verdadeiro.
- Mídia ausente, fraca ou rejeitada pelo downloader torna-se
skipped; nunca use mídia aleatória ou de fallback still.
Requisitos e Entradas
Requer Python, ffmpeg, ffprobe e Pillow. Para Pexels, primeiro use PEXELS_API_KEY do ambiente e, em seguida, procure por ela em skills/video-add-b-roll/.env. Se ambos estiverem ausentes ou vazios, pare e peça ao usuário para adicionar PEXELS_API_KEY=<chave> a esse arquivo e tente novamente após a confirmação. Peça a eles para fornecer a chave através do arquivo .env local, nunca pelo chat. Nunca coloque ou imprima a chave em um argumento de comando, plano, URL, log, artefato de revisão ou resposta.
/video-understand é um pré-requisito. Execute-o primeiro para que o B-roll use a transcrição validada em nível de palavra e a linha do tempo canônica.
Antes de começar, verifique se ele está instalado. Se não estiver, avise o usuário que este pré-requisito está ausente e pare antes de processar a mídia.
Execute a partir da raiz do repositório e resolva a raiz do projeto separada:
$RepoRoot = (Resolve-Path '.').Path
$ProjectRoot = (Resolve-Path 'caminho/para/projeto-video').Path
$BrollEnv = Join-Path $RepoRoot 'skills/video-add-b-roll/.env'
if ([string]::IsNullOrWhiteSpace($env:PEXELS_API_KEY) -and (Test-Path -LiteralPath $BrollEnv)) {
$PexelsKeyLine = Get-Content -LiteralPath $BrollEnv | Where-Object { $_ -match '^\s*PEXELS_API_KEY\s*=' } | Select-Object -Last 1
if ($PexelsKeyLine) { $env:PEXELS_API_KEY = ($PexelsKeyLine -split '=', 2)[1].Trim().Trim('"').Trim("'") }
}
$BrollScripts = Join-Path $RepoRoot 'skills/video-add-b-roll/scripts'
$ProjectLib = Join-Path $RepoRoot 'skills/video-understand/scripts'
$ReviewVideo = & python -c "import sys; from pathlib import Path; sys.path.insert(0,sys.argv[2]); import projectlib; root=Path(sys.argv[1]); project=projectlib.load_json(root/'work/project.json'); assert project.get('render',{}).get('status') == 'verified', 'a entrega upstream atual não está verificada'; path=projectlib.resolve_project_path(root,project['render']['output']); assert path.is_file(), 'a entrega upstream atual está ausente'; print(path)" $ProjectRoot $ProjectLib
if ($LASTEXITCODE -ne 0) { throw 'Complete a entrega upstream ativa antes da revisão de B-roll.' }
$ReviewVideo = (Resolve-Path -LiteralPath $ReviewVideo).Path
Consuma estas entradas canônicas em vez de re-transcrever ou re-analisar:
work/project.jsonwork/timeline.jsonwork/understand/transcript.jsonwork/understand/understanding.json- um vídeo de revisão do tempo do programa atual cujos pixels incluem trabalho de corte e correção de cor ativo
$ReviewVideo é essa entrega upstream verificada existente, não um nome de arquivo a ser inventado ou uma nova renderização de B-roll. Ela já deve corresponder à duração, dimensões e FPS da linha do tempo ativa. Se estiver ausente ou desatualizada, termine a entrega de corte/correção de cor upstream primeiro, depois resolva e faça o hash dela antes de continuar.
A operação sempre depende de understanding, mais cut e color-grade quando essas operações estão ativas na sequência alvo. Copie suas revisões atuais de inteiro positivo para based_on. Quando a correção de cor estiver ativa, registre tanto o plano de gradação quanto os hashes da LUT selecionada; a normalização deve receber essa LUT selecionada exata e pré-aplicá-la a cada take de B-roll selecionado.
A ordem canônica da sequência é:
cut -> color-grade -> b-roll -> captions -> content-cards -> graphic-motion
A operação registrada deve ter changes_video_pixels: true, adicionar a faixa b-roll e deixar a linha do tempo, geometria e áudio inalterados. broll_plan.register_operation() escreve este contrato; não construa a operação manualmente.
Arquivos Duráveis e Descartáveis
work/b-roll/broll-plan.json # plano de domínio durável
work/b-roll/presentation-decision.json # decisão de rota de chat do Agente durável
work/b-roll/broll-interaction.json # recibo aplicado durável
work/b-roll/broll-selection.json # seleção exata aprovada e vínculo de página consumida duráveis
work/b-roll/speaker-inset-analysis.json # pacote de cena/evidência durável
work/b-roll/speaker-inset-agent-input.json # decisões de ROI do Agente duráveis
work/b-roll/speaker-inset-preview.json # pré-visualizações exatas duráveis
work/b-roll/speaker-inset-clearance.json # verificação de obstrução do Agente durável
work/b-roll/broll-revision-request-<UUID>.json # bytes de solicitação de revisão não aprovados duráveis
work/b-roll/candidate-search.json # consulta durável e ordem do provedor
work/b-roll/candidate-analysis.json # evidência determinística durável
work/b-roll/candidate-ranking.json # classificação durável do Agente e Top 3
work/cache/b-roll/candidate-analysis/media/ # variantes de análise descartáveis
work/cache/b-roll/candidate-analysis/frames/ # amostras e recortes reproduzíveis
work/cache/b-roll/candidates/ # mídia adquirida congelada
work/cache/b-roll/speaker-inset/ # evidências e pré-visualizações reproduzíveis
work/cache/b-roll/normalized/ # sobreposições silenciosas reproduzíveis
review/03-b-roll/candidate-analysis-<UUID>/ # pacote de análise imutável
review/03-b-roll/candidate-analysis-<UUID>.md # análise e resumo da linha de base
review/03-b-roll/candidate-analysis-<UUID>/candidate-index.html
review/03-b-roll/b-roll-review-<UUID>.html # revisão de candidato imutável
review/03-b-roll/b-roll-review.html # alias de conveniência mais recente
review/03-b-roll/stills/ # quadros de verificação primeiro/meio/último
review/03-b-roll/contact-sheet.jpg
review/03-b-roll/boundary-reel.mp4
review/03-b-roll/b-roll-summary.md
Mantenha o plano e o recibo fora de work/cache/. Trate os arquivos candidatos e normalizados como reproduzíveis, mas vinculados por hash.
Fluxo de Trabalho
1. Estabelecer Dependências Atuais
Leia a sequência ativa, revisões de operação, linha do tempo, transcrição, entendimento, plano de gradação ativo e LUT selecionada. Confirme que o vídeo de revisão corresponde à duração, dimensões e FPS racional da linha do tempo ativa. Faça o hash da transcrição, linha do tempo, vídeo de revisão e entradas de gradação ativas em input_hashes.
Use broll_plan.active_dependencies(project) para derivar a lista de dependências exata. Uma linha do tempo alterada, transcrição, revisão de dependência, plano de gradação, LUT, vídeo de revisão, manifesto de candidato ou ativo revisado torna o trabalho downstream obsoleto; atualize o plano e repita a revisão em vez de carregar um recibo antigo adiante.
2. Elaborar um Plano Dinâmico-Social
Elabore manualmente work/b-roll/broll-plan.json; os scripts executam precisão, não julgamento editorial. Para cada take proposto:
- escolha um intervalo de programa positivo, semiaberto e não sobreposto em ordem cronológica;
- mapeie-o através de
work/timeline.jsonemsource_rangesexatas; - preserve pelo menos uma palavra de transcrição mapeada exata com intervalos de origem/programa e ID do clipe;
- declare uma
editorial_reasonevisual_intentconcretas; - defina
brief.search_contextcom umtopic,visual_directione1-12 palavras-chave únicasconcretos; - defina cada
semantic_rolecomodirect,supportiveouatmospheric; - escreva duas ou três consultas literais em inglês em camadas: uma consulta
direct subject/action, uma consultadefensible context/processe, quando uma terceira consulta for útil, umatheme-enhancing variant; - comece com
planned, mova paracandidates_readyapós a aquisição ou useskippedquando nenhum candidato relevante existir.
Mantenha brief.density igual a dynamic-social. A cobertura planejada começa com uma varredura A-roll completa da transcrição e linha do tempo mapeadas, seguida por intervalos cronológicos, não sobrepostos e editorialmente válidos, escritos manualmente. Trate 0,40 a 0,70 como um alvo suave. Abaixo de 0,40, faça uma segunda passagem e adicione ou estenda apenas intervalos defensáveis. Acima de 0,70, revise internamente o encobrimento A-roll. Nunca adicione preenchimento irrelevante ou enfraqueça relevância, direitos, qualidade ou outra porta de elegibilidade para atingir o alvo. Termos tópicos genéricos como tech ou entertainment podem refinar uma consulta apenas; eles nunca substituem a relação visível por take entre o candidato e a reivindicação da transcrição. Se nenhum momento merecer B-roll, um plano aprovado com todos skipped é um no-op válido.
Não adicione speaker_inset_style durante a elaboração do rascunho. Após a aquisição do candidato, a decisão explícita de apresentação do chat do Agente seleciona a rota comum ou de recorte do apresentador. Este último instala automaticamente o estilo de retângulo arredondado estrito do nível do projeto: width_ratio: 0,39, borda cinza, proporção de aspecto, raio de canto, margens e área inferior segura para legendas. Predefinição e âncora não pertencem ao estilo. O Agente registra project_layout_strategy mais uma layout_recommendation por take após inspecionar a mídia selecionada exata. Nunca introduza um detector de rosto, modelo de segmentação, rastreador de identidade de corte transversal ou ROI adivinhado. Ajuste os pixels de ROI do apresentador na janela com dimensionamento de capa com preservação de aspecto; nunca os estique para a proporção de aspecto configurada. Centralize o corte horizontalmente e ancore-o ao topo para que a cabeça e o rosto completos tenham prioridade sobre a cobertura da parte inferior do corpo.
Valide o rascunho após cada edição material:
python -c "import sys; from pathlib import Path; root=Path(sys.argv[1]); sys.path.insert(0,sys.argv[2]); import broll_plan,projectlib; plan=projectlib.load_json(root/'work/b-roll/broll-plan.json'); timeline=projectlib.load_json(root/'work/timeline.json'); transcript=projectlib.load_json(root/'work/understand/transcript.json'); project=projectlib.load_json(root/'work/project.json'); errors=broll_plan.validate_plan(plan,timeline,transcript,project=project,project_root=root,verify_files=True); print('\n'.join(errors) if errors else 'B-roll plan valid'); raise SystemExit(bool(errors))" $ProjectRoot $BrollScripts
3. Analisar, Classificar e Congelar Candidatos
A análise de candidatos é uma evidência consultiva antes de candidates_ready. Ela não seleciona mídia, aprova um take, adiciona um recibo ou altera o ciclo de vida. Mantenha as duas ou três consultas literais existentes para cada take.
Para vídeo local, escreva a proveniência verdadeira e importe-a através do caminho de aquisição existente:
python "$BrollScripts/pexels.py" import-local `
"$ProjectRoot/input/example-owned-footage.mp4" `
"$ProjectRoot/work/cache/b-roll/candidates/example-owned-footage.mp4" `
"$ProjectRoot/work/b-roll/example-local-provenance.json"
Copie o registro retornado para os candidates do take. A análise do candidato lê esse arquivo de cache congelado exato; ela não o copia para outro provedor ou sistema de análise. Use --local-only quando o plano não deve consultar o Pexels.
Colete os resultados do Pexels com mesclagem de consulta round-robin, deduplicação de ID do provedor e um máximo de oito vídeos de provedor únicos por take. Escolha a orientação que corresponda à linha do tempo:
$CandidateAnalysis = Join-Path $BrollScripts 'candidate_analysis.py'
python $CandidateAnalysis search `
$ProjectRoot `
"$ProjectRoot/work/b-roll/broll-plan.json" `
"$ProjectRoot/work/b-roll/candidate-search.json" `
--orientation portrait `
--per-page 8
Para análise apenas local, adicione --local-only. O registro de pesquisa preserva todas as consultas literais, sua ordem original do provedor, a ordem round-robin e ambas as variantes do Pexels. A variante de análise é o menor arquivo com orientação correspondente cuja borda curta tenha pelo menos 480 pixels, ou o maior arquivo correspondente válido quando nenhum se qualifica. A variante de entrega permanece o arquivo de resolução mais alta com orientação correspondente.
Baixe e decodifique completamente apenas as variantes de análise, amostre-as em 10/30/50/70/90 por cento e escreva evidências de máquina determinísticas:
python $CandidateAnalysis analyze `
$ProjectRoot `
"$ProjectRoot/work/b-roll/broll-plan.json" `
"$ProjectRoot/work/b-roll/candidate-search.json" `
"$ProjectRoot/work/timeline.json" `
"$ProjectRoot/work/b-roll/candidate-analysis.json"
A análise contém verificações rígidas, avisos objetivos, hashes de quadros amostrados e de corte central, folhas de contato, evidências de luma/clipping/edge/motion e evidências de duplicatas. Ela preserva o limite de rejeição exata local do take e o limite perceptual estrito e, em seguida, adiciona identidade exata em todo o projeto, grupos perceptuais estritos e dicas de possible_series não supressoras. A rejeição rígida é limitada às falhas objetivas em reference/broll-rules.md.
Inspecione a evidência exata da transcrição, cinco quadros, simulações de corte, avisos e evidências de duplicatas. Escreva work/cache/b-roll/candidate-ranking-input.json com esta forma:
{
"schema_version": 1,
"analysis_sha256": "<SHA-256 canônico de candidate-analysis.json>",
"mode": "agent",
"actor": "<nome real do Agente>",
"timestamp": "<timestamp com fuso horário>",
"overall_rationale": "<justificativa não vazia>",
"near_duplicate_groups": [{
"group_id": "<id de grupo estável>",
"match_type": "same_series",
"actor": "<nome real do Agente>",
"timestamp": "<timestamp com fuso horário>",
"members": [
{"shot_id": "<id do take>", "candidate_id": "<id do candidato>"},
{"shot_id": "<id do outro take>", "candidate_id": "<id do outro candidato>"}
],
"rationale": "<repetição visível específica entre os dois momentos da transcrição>"
}],
"shots": [{
"shot_id": "<id do take>",
"candidates": [
{
"candidate_id": "<id do candidato>",
"label": "<rótulo legível por humanos>",
"provenance": {
"provider": "pexels" | "local",
"provider_id": "<id do provedor>",
"source_url": "<url da fonte>",
"license": "<tipo de licença>",
"attribution": {
"name": "<nome do artista>",
"url": "<url do artista>"
},
"import_sha256": "<SHA-256 do arquivo importado>",
"import_timestamp": "<timestamp com fuso horário>",
"original_sha256": "<SHA-256 do arquivo original, se disponível>"
},
"technical": {
"width": 1920,
"height": 1080,
"fps": 30.0,
"duration_seconds": 15.5,
"codec": "h264",
"bitrate_kbps": 5000
},
"analysis": {
"hard_rejection": null,
"warnings": ["luma_clipping_highlights"],
"luma": {"min": 0.1, "max": 0.95, "mean": 0.5, "std": 0.2},
"motion": {"mean": 0.02, "std": 0.01, "max": 0.1},
"edge_sharpness": {"mean": 0.6, "std": 0.1},
"frame_hashes": {
"sample_frames": ["hash1", "hash2", "hash3", "hash4", "hash5"],
"center_crop": "hash_central"
},
"duplicate_evidence": {
"exact_match": false,
"perceptual_match": {"is_match": false, "distance": 0.15},
"possible_series": {"is_series": false, "confidence": 0.1}
}
},
"ranking": {
"rank": 1,
"score": 0.85,
"rationale": "<por que este candidato é o melhor para este take>"
}
}
],
"selection": {
"selected_candidate_id": "<id do candidato selecionado>",
"alternative_candidate_ids": ["<candidato alternativo 1>", "<candidato alternativo 2>"]
}
}],
"metadata": {
"agent_version": "1.0.0",
"skill_version": "1.0.0",
"model": "claude-3-opus-20240229"
}
}
4. Aplicar Recebimento e Aprovação
Após a classificação, se nenhum take tiver um selected_candidate_id de selection, o Agente deve registrar que o plano está approved_all_skipped. Caso contrário, para cada take selecionado:
- Baixe a variante de entrega (resolução máxima) do cache de candidatos
- Normalize a mídia: corte silenciosamente para a duração do take, dimensione para as dimensões da linha do tempo, aplique a LUT de correção de cor, se ativa
- Gere recorte do apresentador, se necessário, com base na decisão
presentation_decision - Escreva
work/b-roll/broll-interaction.jsoncom um registro por take contendo:shot_idselected_candidate_idnormalized_sha256applied_operation(ex.:overlay,speaker_inset)timing_in_out(quadros de entrada/saída precisos na linha do tempo)source_ranges(do plano)transcript_words(palavras mapeadas)editorial_reasonvisual_intent
5. Revisão e Entrega
- Gere artefatos de revisão em
review/03-b-roll/: stills, contact sheet, boundary reel, summary markdown - O Agente revê cada take quanto à qualidade, sincronização e adesão editorial
- Se aprovado, o recibo é
approved; caso contrário,revision_requestcom comentários - A entrega final é a faixa B-roll aplicada ao vídeo de revisão, produzindo um novo vídeo de revisão para a próxima operação da sequência (
captionsoucontent-cards)
A saída final é um vídeo revisado atualizado com a faixa B-roll incorporada, pronto para processamento downstream.