Communitygithub.com

Localização de vídeo: do link à versão legendada

Transforme um link do YouTube, X, Instagram, TikTok ou Bilibili em versão localizada com o Porter: baixar, transcrever, traduzir e gravar com FFmpeg legendas bilíngues ou só em chinês, com cada etapa salva em disco.

O que é Localização de vídeo: do link à versão legendada?

Receita Localização de vídeo, passo 1 (o pipeline de ponta a ponta), de RolinShmily/porter-workflow. O Porter executa quatro etapas retomáveis — download → transcrição → tradução → gravação — e grava cada resultado em disco, então uma falha nunca perde o trabalho pronto. O agente roda `plan` primeiro para ver se o vídeo tem faixa de legenda nativa (sem ASR nem chave) ou precisa de transcrição compatível com Whisper, e então gera SRTs bilíngues e em chinês e MP4s com legendas gravadas via libass. Um só motor: CLI, servidor MCP, bancada web e esta Agent Skill.

Funciona com~Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/RolinShmily/porter-workflow/tree/HEAD/skills/porter-skill

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Habilidade Porter (Streaming Porter)

Transforma um link de vídeo em um vídeo finalizado com legendas duras em chinês. Executado em quatro estágios em ordem: Obter → Transcrever → Traduzir → Queimar. Cada estágio escreve seus artefatos no disco, então falhas no meio do processo não perdem o que já foi concluído.


⚠️ Pré-requisitos: Transcrição requer Chave

Isso deve ser confirmado primeiro, caso contrário a tarefa falhará na fase de transcrição.

CapacidadePrecisa de Chave?
Download, tradução, queimaNão
Transcrição de fala (ASR)Requer OPENAI_API_KEY (ou WHISPER_API_KEY), ou VideoCaptioner CLI instalado
Faixas de legenda nativas da plataforma (YouTube / Bilibili, etc.)Não — se houver faixa nativa, não executa ASR

A afirmação da v0.1 de "ciclo fechado zero chave puramente Python" não é mais válida: todos os pontos de extremidade de reconhecimento de fala sem chave foram desativados (verificado em 2026-09-22; ou use o extra [asr-local] para reconhecimento local sem chave). Sem chave, se o vídeo também não tiver faixa de legenda da plataforma, a tarefa terminará na fase transcribe com every speech-to-text backend failed.

Portanto: Execute plan primeiro — ele informará diretamente se este vídeo usará faixas de legenda nativas ou ASR, e se é viável.


Ponto de Entrada

O ponto de entrada da CLI é executado via uvx. No Windows PowerShell, use o .ps1 nativo, não assuma que Git Bash / WSL está disponível:

ScriptPropósito
scripts/porter.shPonto de entrada principal Bash, encaminha para a CLI porter.
scripts/porter.ps1Ponto de entrada principal Windows PowerShell, também suporta subcomandos inspect / plan / run / jobs.
scripts/inspect.shPré-verificação Bash, equivalente a porter.sh inspect.
scripts/bootstrap.shPonto de entrada alternativo para criar .venv a partir do checkout do repositório; não instala código-fonte Python com a habilidade.
# Pré-verificação
<SKILL_DIR>/scripts/inspect.sh "https://youtu.be/dQw4w9WgXcQ"
# Planejamento
<SKILL_DIR>/scripts/porter.sh plan "https://youtu.be/dQw4w9WgXcQ"
# Execução
<SKILL_DIR>/scripts/porter.sh run "https://youtu.be/dQw4w9WgXcQ" -o ./porter_output

No Windows PowerShell, use & '<SKILL_DIR>\scripts\porter.ps1' inspect '<URL>' --json; plan / run / jobs também usam o mesmo ponto de entrada. inspect.sh e os comandos nohup, grep abaixo são exemplos Bash; não devem ser copiados diretamente para o PowerShell.

uvx requer conexão de rede na primeira execução para resolver dependências. Por padrão, instala apenas porter-workflow[llm] (o pacote base já inclui yt-dlp); para ASR local, com consentimento do usuário, define PORTER_SKILL_SPEC=porter-workflow[llm,asr-local]. Para instalação offline, prepare as dependências localmente no checkout do repositório, em vez de esperar que o diretório da habilidade contenha código-fonte.

Em hosts com espaço de trabalho restrito para escrita, primeiro confirme os diretórios absolutos permitidos, defina PORTER_SKILL_STATE_DIR para um .state dentro dele, execute porter.sh --host-check ou porter.ps1 --host-check; ele redirecionará o cache de uv, yt-dlp e o registro de tarefas para lá (substituindo quaisquer caminhos de cache já definidos pelo host). A saída -o também deve estar dentro do diretório permitido. Quando não definido, mantém os caminhos padrão do host. Comandos, limitações e exemplos do Windows estão em references/HOSTS.md.


Ciclo Fechado do Fluxo de Trabalho

Executa em ordem. Cada etapa é mais barata que a próxima, projetada para rejeitar entradas ruins antes de gastar tempo computacional longo.

1. Pré-verificação — inspect

<SKILL_DIR>/scripts/inspect.sh "<URL>" --json

Retorna plataforma, título, duração, resolução, proporção, se há faixa de legenda. Concluído antes de baixar qualquer mídia, em segundos.

Interpretação: is_valid significa "link utilizável", ok significa apenas "chamada bem-sucedida". Quando o link está quebrado, is_valid=false; neste caso, não tente novamente — tentar links mortos é inútil.

Código de saída 1 significa link indisponível.

2. Planejamento — plan

<SKILL_DIR>/scripts/porter.sh plan "<URL>" --json

Este é o passo que mais economiza tempo — responde "como este vídeo será processado e se pode ser concluído":

  • subtitles.route: platform (usa faixas de legenda nativas da plataforma) ou asr (executa reconhecimento de fala)
  • translation.needed: false se já houver faixa em chinês; pode pular toda a tradução
  • feasible / blocking_issues: Se false, pare; não inicie tarefa
  • notes: Leitura obrigatória. Duas mais importantes:
    • Faixa de legenda de plataforma é "solicitada, não garantida" — a captura pode falhar (limitação de taxa da plataforma, HTTP 429) e reverter para reconhecimento de fala
    • Se os backends disponíveis são todos endpoints reversos não testados, a nota será clara

Código de saída 1 significa inviável.

3. Confirmação com o Usuário

Uma tarefa pode baixar centenas de MB e levar minutos. Informe as conclusões de plan ao usuário e obtenha consentimento antes de executar (qual rota seguir, quais estágios executar, se deve queimar). Se feasible=false, relate o problema bloqueador, não inicie tarefa.

4. Execução — run

<SKILL_DIR>/scripts/porter.sh run "<URL>" -o ./porter_output

Para vídeos longos, não use chamada em primeiro plano esperando terminar. Inicie em segundo plano e depois consulte o registro de tarefas:

nohup <SKILL_DIR>/scripts/porter.sh run "<URL>" -o ./porter_output > run.log 2>&1 &
# Consulta (registro da tarefa escrito em arquivo de registro compartilhado, visível entre processos)
<SKILL_DIR>/scripts/porter.sh jobs list
<SKILL_DIR>/scripts/porter.sh jobs status <job_id>

No PowerShell, use a ferramenta de tarefa em segundo plano fornecida pelo host para iniciar assincronamente & '<SKILL_DIR>\scripts\porter.ps1' run ... e continue consultando jobs status usando o mesmo PORTER_SKILL_STATE_DIR. Não use Out-String para acumular o progresso de comandos longos até o final.

Não use "definir tempo limite da ferramenta para 1200 segundos" para suportar tarefas longas (como na v0.1). Isso ainda falha quando o vídeo é mais longo, e você não obtém nenhum progresso. O registro de tarefas foi projetado para isso.

5. Verificação de Qualidade (Obrigatória)

Não confie apenas no código de saída para dizer que está concluído. Pelo menos confirme:

# 1. Legendas em chinês existem e contêm CJK (evita "legendas não traduzidas que parecem prontas")
grep -qP '[\x{4e00}-\x{9fff}]' ./porter_output/<task>/cooked/subtitle_zh.srt \
  && echo "OK: Contém chinês" || echo "FAIL: Sem chinês"

# 2. Vídeo finalizado é decodificável e o atom moov está intacto (evita arquivos truncados na publicação)
ffprobe -v error -show_entries format=duration -of csv=p=0 ./porter_output/<task>/cooked/video_zh.mp4

Um tamanho de arquivo finalizado anormalmente pequeno geralmente significa falha na queima, não vídeo curto.

6. Em Caso de Erro

<SKILL_DIR>/scripts/porter.sh doctor     # Esta máquina pode trabalhar: ffmpeg/libass, runtime JS, fontes, codecs
<SKILL_DIR>/scripts/porter.sh config list # Configuração analisada (chaves mascaradas)

Parâmetros Comuns

# Apenas legendas, sem queima
run "<URL>" --burn skip

# Apenas vídeo finalizado em chinês (sem bilíngue)
run "<URL>" --burn zh_only

# Especificar diretório de saída / idioma alvo
run "<URL>" -o /path/to/out --target-lang zh-Hans

# Deixar um backend específico tentar primeiro (os outros ainda como fallback, não "usar apenas este")
run "<URL>" --translator google
run "<URL>" --asr-engine whisper-api

# Trocar para um modelo LLM diferente para esta tarefa (não altera configuração)
run "<URL>" --llm-model deepseek-reasoner

# Já tem legendas fonte prontas: usar diretamente, sem reconhecimento (.srt / .vtt)
run "<URL>" --subtitle-file ./my_subtitles.srt

# Vídeos que exigem login
run "<URL>" --cookies-from-browser chrome
run "<URL>" --cookies ./cookies.txt

# Reexecutar (ignorar resultados de estágios em cache)
run "<URL>" --force

# Para consumo por script
run "<URL>" --json

A semântica de --only-phase é "até este estágio", não "apenas este estágio" — cada estágio consome a saída do anterior, então estágios anteriores ainda são executados.


Estrutura dos Artefatos

<task_dir>/
├── raw/                       # Materiais mestres e artefatos intermediários
│   ├── video.mp4              # Mestre padronizado (stream copy sem perdas, sem recompressão)
│   ├── audio.wav              # Faixa de áudio base
│   ├── audio_enhanced.wav     # Faixa de áudio aprimorada para ASR (redução de ruído + equalização de fala), não usada no vídeo finalizado
│   ├── subtitle.srt           # Legendas no idioma fonte (faixa da plataforma ou resultado ASR)
│   ├── transcript.json/.txt   # Roteiro estruturado
│   ├── cover.jpg
│   └── metadata.json
└── cooked/                    # Produtos finais
    ├── subtitle.srt / .ass    # Bilíngue
    ├── subtitle_zh.srt / .ass # Apenas chinês
    ├── video_bilingual.mp4    # Vídeo com legendas duras bilíngües
    └── video_zh.mp4           # Vídeo com legendas duras apenas em chinês

O áudio dos vídeos finalizados é cópia direta (-c:a copy) do mestre original; a faixa de áudio aprimorada é usada apenas para reconhecimento — combinando precisão de reconhecimento com qualidade de áudio no produto final.


Configuração

Ordem de busca de configuração (a posterior substitui a anterior):

  1. Valores padrão embutidos
  2. Variáveis de ambiente: OPENAI_API_KEY, OPENAI_BASE_URL, OPENAI_MODEL, WHISPER_API_KEY, PORTER_ASR_ENGINE
  3. Configuração do usuário (porter config list imprime o caminho real)
  4. Configuração do projeto: porter.json / porter.toml / config.json no diretório atual
  5. --config <path>

Veja a tabela completa de chaves em references/CONFIG.md e o modelo em assets/config.example.json.


Usando via MCP (Opcional, mas Melhor)

Se o host já tiver configurado o servidor MCP porter, prefira usá-lo em vez do shell:

  • Resultados estruturados, sem necessidade de analisar stdout (evitando problemas de escape e codificação do shell)
  • porter_job_start retorna imediatamente + porter_job_status para consulta, tarefas longas não atingem tempo limite da ferramenta
  • Única maneira de obter "tradução de nível LLM com zero chave": §8.3 sampling usa o modelo do host para traduzir; o processo CLI não tem acesso ao modelo do host

Veja a tabela de nomes de ferramentas e configuração em references/MCP.md.

Nota: npx skills add instala apenas o diretório desta habilidade, não instala o servidor MCP. Para instalação nova, o caminho da CLI é o padrão.


Arquivos de Referência

ArquivoConteúdo
references/ARCHITECTURE.mdPipeline de quatro estágios, cadeia de fallback de plataforma e backend, restrições de design
references/CONFIG.mdTodas as chaves de configuração, variáveis de ambiente, prioridades
references/MCP.mdTabela de ferramentas MCP e método de configuração
references/HOSTS.mdPonto de entrada nativo Windows e pré-verificação de host restrito
assets/config.example.jsonModelo de configuração

Habilidades Relacionadas