yueying

Deixe a IA assistir vídeos: arquivos locais ou URLs do YouTube/Bilibili -> transcrição com timestamps + folhas de contato de keyframes. Totalmente offline (legendas da plataforma primeiro, local faster-whisper caso contrário), ffmpeg incluído, sem chave de API. Seis ferramentas: watch_video, get_transcript, search_transcript, get_frames, get_frame_at, list_videos. Instalação: uvx yueying mcp

Documentação

yueying — deixe a IA assistir vídeos

Aponte o Claude, o Cursor ou qualquer cliente MCP para um vídeo e receba uma transcrição com timestamps e folhas de contato com keyframes — offline, sem chave de API. Arquivos locais primeiro; URLs (YouTube, Bilibili, Douyin, Xiaohongshu, TikTok, Vimeo, …) são vídeos que você tem direito de processar, baixados via yt-dlp em até 720p e excluídos após o processamento por padrão.

PyPI PyPI downloads License: MIT Python 3.10+ Add to Cursor Install in VS Code

中文说明 ↓

Yueying (阅影) significa "ler vídeo". Um único pacote oferece um servidor MCP, uma CLI e uma habilidade de agente.

O que você obtém

Claude Desktop: a YouTube link is pasted, the watch_video tool runs for about 40 seconds, and Claude answers with timestamped key points

Claude Desktop com yueying conectado: cole um link, aguarde cerca de quarenta segundos e receba o vídeo de volta como anotações com timestamps. Este vídeo possui legendas, então o reconhecimento de fala nunca foi executado, e o modelo pediu apenas a transcrição. Keyframes e folhas de contato retornam via get_frames quando ele precisa ver a tela. Vídeo de demonstração: GitInGifs: Git Branches por GitLab, CC BY.

A 3x3 contact sheet: nine keyframes, each with a yellow "#number mm:ss" label bottom-left

Folha de contato de um clipe de demonstração de 24 segundos (quatro capturas de tela do aplicativo com narração em chinês). O rótulo amarelo em cada bloco é o número do keyframe e o timestamp; o modelo os cita de volta para você.

A transcrição do mesmo clipe — reconhecimento de fala local, idioma detectado automaticamente como chinês:

[00:00] 这是阅读,一个安静的桌面小说阅读器。整本书连续滚动,按段落记住进度。
        第二个画面是桌面模式,窗口变透明,只留文字浮在桌面上。
        第三个画面是伪装皮肤,一键变成代码编辑器。
        最后是伪装成表格的样子。

(O aplicativo se chama 月读; o ASR ouviu o homófono 阅读. O reconhecimento de fala faz isso com nomes — o modelo corrige a partir do texto na tela nos quadros.)

Cada vídeo vira uma pasta:

report.md          index for the model: metadata, chapters, contact sheets, keyframes, transcript
transcript.txt     paragraphs with [mm:ss] timestamps
transcript.srt     subtitles for any player
grid_01.jpg …      3x3 contact sheets, 9 keyframes each, in time order
frames/            full-size keyframes, e.g. f003_00m15s.jpg
manifest.json      machine-readable result (paths, segments, chapters, options)

Por que yueying

  • Legendas primeiro, Whisper apenas quando necessário. Legendas da plataforma são usadas quando existem. Caso contrário, faster-whisper local: large-v3-turbo em uma GPU NVIDIA, small em CPU, com fallback automático para CPU — nada é enviado, sem chave.
  • ffmpeg incluído. Funciona no Windows 11 imediatamente (imageio-ffmpeg); sem ajustes de PATH.
  • Eficiente em tokens. Keyframes são capturados em mudanças de cena, quase duplicados são descartados e empacotados em folhas de contato 3x3 com timestamps gravados. Uma folha ≈ 1–2K tokens para nove momentos; uma transcrição com [mm:ss] parágrafos.
  • Plataformas chinesas e o resto. Bilibili (multipartes, coleções, vídeos de membros com seu login do navegador), Douyin, Xiaohongshu — e YouTube, TikTok, Vimeo, X e todos os outros sites do yt-dlp.
  • Zero chaves de API, zero telemetria. O único tráfego de rede é o site de vídeo que você indicar e um download do modelo Whisper. Veja a política de privacidade.

Benchmark: um vídeo de 6 minutos do Bilibili → relatório em ~90 s em um laptop RTX 5060; em CPU com model=small espere ~1–2 min por 10 min de fala.

Início rápido

  1. Instale uv (Python não é necessário):
    winget install astral-sh.uv                         # Windows
    brew install uv                                     # macOS
    curl -LsSf https://astral.sh/uv/install.sh | sh     # Linux / macOS
    
  2. Aqueça e verifique tudo uma vez (instala o pacote, testa a GPU, baixa o modelo de fala, executa um teste rápido de 2 segundos e imprime a configuração para colar):
    uvx yueying mcp --setup
    
  3. Adicione o servidor ao seu cliente (abaixo) e então pergunte: "Assista C:\videos\lecture3.mp4 e transforme os passos em anotações" ou "O que este vídeo diz sobre docker compose: https://www.bilibili.com/video/BV…".

Claude Desktop

%APPDATA%\Claude\claude_desktop_config.json (Windows) · ~/Library/Application Support/Claude/claude_desktop_config.json (macOS). Saia e reabra o Claude completamente depois.

{ "mcpServers": { "yueying": { "command": "uvx", "args": ["yueying", "mcp"], "env": { "PYTHONUTF8": "1" } } } }

Nota para Windows: o Claude Desktop nem sempre enxerga seu PATH — se o servidor falhar ao iniciar ("spawn uvx ENOENT"), use o caminho absoluto, ex.: "command": "C:\\Users\\<you>\\.local\\bin\\uvx.exe" (where uvx imprime isso). Logs: %APPDATA%\Claude\logs\mcp-server-yueying.log (~/Library/Logs/Claude/ no macOS). Mantenha wait_seconds no padrão ali; veja a regra RUNNING.

Claude Code

claude mcp add --transport stdio --scope user yueying --env PYTHONUTF8=1 -- uvx yueying mcp

Ou coloque o .mcp.json deste repositório em um projeto (ele vem com "timeout": 1800000 para que uma única chamada watch_video possa aguardar um vídeo longo). Para aumentar o timeout de ferramentas do Claude Code globalmente, defina MCP_TOOL_TIMEOUT=1800000 (ms) no seu ambiente. O repositório também é um plugin do Claude Code (.claude-plugin/plugin.json: servidor + habilidade).

Cursor

Clique no selo Add to Cursor acima, ou coloque o mesmo JSON em ~/.cursor/mcp.json (global) ou .cursor/mcp.json (projeto):

{ "mcpServers": { "yueying": { "command": "uvx", "args": ["yueying", "mcp"], "env": { "PYTHONUTF8": "1" } } } }

Cline

MCP Servers → Configure (cline_mcp_settings.json). timeout está em segundos; as cinco ferramentas somente leitura são seguras para aprovação automática. Instruções passo a passo para agentes: llms-install.md.

{
  "mcpServers": {
    "yueying": {
      "type": "stdio",
      "command": "uvx",
      "args": ["yueying", "mcp"],
      "env": { "PYTHONUTF8": "1" },
      "timeout": 1800,
      "autoApprove": ["get_transcript", "search_transcript", "get_frames", "get_frame_at", "list_videos"]
    }
  }
}

Windsurf

~/.codeium/windsurf/mcp_config.json:

{ "mcpServers": { "yueying": { "command": "uvx", "args": ["yueying", "mcp"], "env": { "PYTHONUTF8": "1" } } } }

VS Code (modo agente do Copilot)

Clique no selo Install in VS Code acima, ou crie .vscode/mcp.json (observe a chave raiz servers):

{ "servers": { "yueying": { "type": "stdio", "command": "uvx", "args": ["yueying", "mcp"], "env": { "PYTHONUTF8": "1" } } } }

Links diretos para hosts que aceitam esquemas de URL personalizados: cursor://anysphere.cursor-deeplink/mcp/install?name=yueying&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyJ5dWV5aW5nIiwibWNwIl0sImVudiI6eyJQWVRIT05VVEY4IjoiMSJ9fQ== e vscode:mcp/install?%7B%22name%22%3A%22yueying%22%2C%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22yueying%22%2C%22mcp%22%5D%2C%22env%22%3A%7B%22PYTHONUTF8%22%3A%221%22%7D%7D.

Sem uv (pip / pipx) e Windows com um clique

pip install yueying            # or: pipx install yueying
yueying mcp --setup            # prints a config with the absolute path of the yueying-mcp executable

Use esse caminho absoluto como "command" sem args (Windows: ...\Scripts\yueying-mcp.exe; também funciona como python -m yueying mcp). Usuários de Windows sem ferramentas Python podem dar dois cliques em install.cmd a partir de um checkout: ele cria %LOCALAPPDATA%\yueying\venv, instala a habilidade do Claude Code, executa yueying mcp --setup e imprime o bloco JSON com o caminho correto.

GPU

uvx --from "yueying[cuda]" yueying mcp     # NVIDIA: adds the CUDA runtime wheels (cuBLAS, cuDNN)
pip install "yueying[cuda]"

Dispositivo e modelo são escolhidos automaticamente (model=auto: large-v3-turbo em CUDA, small em CPU); se o teste de GPU falhar, o reconhecimento cai para CPU sozinho.

Docker

docker build -t yueying .
docker run --rm -i -v yueying-data:/data -v "$PWD/videos:/videos:ro" yueying

A imagem é somente CPU (contêineres não recebem GPU por padrão), então ela usa o modelo small por padrão. Monte seus vídeos como somente leitura e dê caminhos de contêiner às ferramentas (/videos/lesson.mp4); os resultados e os pesos do Whisper baixados ficam no volume /data. Em uma configuração de cliente, o command é docker e args são ["run", "--rm", "-i", "-v", "yueying-data:/data", "-v", "/your/videos:/videos:ro", "yueying"].

Ferramentas

FerramentaQuando o agente a usaO que retornaLimites
watch_video(video, mode="full", language="auto", model="auto", frame_interval_seconds=None, cookies_from_browser=None, output_dir=None, refresh=False, wait_seconds=45, max_chars=12000)Primeira chamada para qualquer vídeo: um caminho local absoluto ou uma URL. mode: full (transcrição + keyframes), transcript, frames.Visão geral DONE: título, fonte, duração, fonte do texto, pasta, arquivos, capítulos, intervalos das folhas de contato, transcrição em [mm:ss] parágrafos — ou RUNNING com estágio/percentual/ETA, ou ERROR com uma dica em inglês simples.Bloqueia por até wait_seconds (0–1500). Transcrição truncada em max_chars com um tempo de início get_transcript. Em cache por vídeo; refresh=true reprocessa.
get_transcript(video, start="0", end=None, format="paragraphs", max_chars=8000)A visão geral foi truncada, um intervalo de tempo específico ou exportação de legendas (format="srt").Cabeçalho + [mm:ss] parágrafos / [mm:ss-mm:ss] segmentos / blocos SRT; TRUNCATED — next_start="…" quando cortado.max_chars 1000–100000. Tempos: segundos, mm:ss, h:mm:ss.
search_transcript(video, query, context_seconds=15, limit=10)"Quando ele menciona X?"Correspondências com tempo, frases ao redor, número do keyframe mais próximo e número da folha de contato.Termos separados por espaço, qualquer correspondência, mais termos classificam mais alto; limit ≤ 50.
get_frames(video, kind="grids", start=1, count=2, max_width=1280)Ver o que está na tela: folhas de contato primeiro (grids), keyframes individuais (frames) apenas para detalhes.Caminho absoluto + JPEG por imagem, em ordem de tempo; Next: get_frames(start=…) quando houver mais.≤ 3 imagens por chamada (padrão 2, mantenha ≤ 2 no Claude Desktop); ~150 KB por folha em 1280 px.
get_frame_at(video, time, max_width=960)Ler código, um slide, um gráfico ou interface em um momento específico.O quadro exato (extraído da fonte quando o arquivo local ainda existe) ou o keyframe em cache mais próximo, além dos parágrafos falados naquele momento.Uma imagem, ~100 KB em 960 px.
list_videos(limit=20)O usuário se refere a um vídeo anterior ou para verificar o uso de disco.Tabela: video_id, título, duração, fonte do texto, data, tamanho, pasta; trabalhos em execução.Instantâneo, somente leitura.

video para as ferramentas de leitura aceita o video_id de watch_video/list_videos, a pasta de resultados ou o mesmo caminho/URL que você deu a watch_video.

A regra RUNNING

O processamento pode levar minutos, e a maioria dos hosts limita uma chamada de ferramenta a cerca de um minuto. Então watch_video espera no máximo wait_seconds e então responde RUNNING video_id=… · stage 2/4 speech recognition 40% · elapsed 46 s · est. ~1 min remaining. O agente simplesmente chama watch_video novamente com o mesmo video — ele se reconecta ao mesmo trabalho (opções são ignoradas enquanto ele roda; refresh=true reinicia). wait_seconds recomendado:

Hostwait_secondsPor quê
Claude Desktop45 (padrão)timeout duro do cliente ~60 s
Cursor45 (padrão)60–120 s
Claude Codeaté 1500com .mcp.json timeout / MCP_TOOL_TIMEOUT = 1800000 ms
Clineaté 1500com "timeout": 1800 (s)

Notificações de progresso são enviadas a cada 1,5 s para hosts que as exibem. Um vídeo é processado por vez por servidor; solicitações extras entram na fila.

Primeira execução: o primeiro reconhecimento de fala baixa um modelo Whisper uma vez (~480 MB small em CPU, ~1,6 GB large-v3-turbo em GPU). uvx yueying mcp --setup faz isso antecipadamente; caso contrário, a linha RUNNING diz "first run downloads ~… this can take several minutes".

Onde os arquivos vão

Raiz: $YUEYING_OUT_DIR se definido, senão ~/yueying_out. Uma entrada por vídeo, nomeada <slug>-<video_id> (yt-<id>, bili-<BV> ou o nome do arquivo) — nunca renomeada; o título fica em manifest.json.

~/yueying_out/
└── bili-BV1xx-3f9a2c1e/
    ├── report.md  transcript.txt  transcript.srt  manifest.json
    ├── grid_01.jpg … grid_07.jpg
    ├── frames/            f001_00m02s.jpg …   (+ frames/extra/ for get_frame_at)
    ├── .job               only while a job runs
    └── _download/         only with YUEYING_KEEP_SOURCE=1
Variável de ambienteSignificadoPadrão
YUEYING_OUT_DIRpasta raiz para resultados (absoluta, ~ ok)~/yueying_out
YUEYING_MODELpadrão para o parâmetro modelauto
YUEYING_DEVICEauto / cuda / cpuauto
YUEYING_LANGidioma do report.md escrito pelo servidor (en/zh)en
YUEYING_COOKIES_FROM_BROWSERnavegador padrão para cookies (chrome, edge, firefox, …)não definido
YUEYING_KEEP_SOURCE1 mantém a fonte baixada em ≤720p em _download/ (permite quadros de momento exato para URLs)não definido
YUEYING_MAX_JOBSpipelines rodando ao mesmo tempo por servidor1
YUEYING_JOB_TIMEOUTlimite rígido por vídeo, em segundos7200
HF_HOMEcache do Hugging Face (os pesos do Whisper ficam aqui)padrão do HF
HF_ENDPOINTespelho, ex.: https://hf-mirror.comhuggingface.co
PYTHONUTF8defina como 1 no Windows para evitar mojibake

Orçamento de disco: ≈ 25 MB por hora de vídeo; 300–600 MB/h a mais com YUEYING_KEEP_SOURCE=1. Nada é excluído automaticamente — list_videos mostra tamanhos; exclua uma pasta para liberar espaço; watch_video(refresh=true) reprocessa um vídeo. Editar um arquivo local muda seu tamanho/mtime e, portanto, gera uma nova entrada.

Fontes suportadas

  • Arquivos locais: qualquer coisa que o ffmpeg leia — mp4, mkv, mov, webm, avi, flv, ts e áudio (mp3, m4a, wav, …). Entrada somente de áudio gera uma transcrição sem quadros.
  • URLs: todos os sites suportados pelo yt-dlp. Baixados em ≤720p e excluídos após o processamento, a menos que YUEYING_KEEP_SOURCE=1.
  • Bilibili: sem login, o Bilibili serve 480p — suficiente para slides e código. Para HD ou vídeos exclusivos de membros, passe cookies_from_browser="chrome" (ou edge, firefox, brave, chromium, safari); no Windows, feche o Chrome primeiro, ele bloqueia o banco de dados de cookies. Vídeos em várias partes e coleções: links p= são entradas separadas; o --all da CLI processa todos.
  • Não para transmissões ao vivo ou imagens. Links curtos (b23.tv, v.douyin.com) são processados, mas não deduplicados contra sua forma longa (o servidor nunca resolve URLs por conta própria).

Também uma CLI e uma habilidade de agente

yueying video.mp4
yueying "https://www.bilibili.com/video/BVxxxx" --ui-lang en
yueying "https://www.youtube.com/watch?v=xxxx" --out ./notes/xxx
yueying lesson1.mp4 lesson2.mp4 "https://www.bilibili.com/video/BVyyyy"   # several at once, one folder each + index.md
yueying "https://www.bilibili.com/video/BVxxxx" --all                      # every part of a multi-part video / collection
yueying --install-skill                                                    # Claude Code skill -> ~/.claude/skills/yueying

Saída padrão: ./yueying_out/<name>/ (pasta pai quando há várias entradas). As linhas de log da CLI e o report.md são em chinês por padrão (--ui-lang en para inglês); 0.3 mudará o padrão para inglês.

SinalizadorSignificado
--out DIRpasta de saída (padrão ./yueying_out/<name>; a pasta pai quando há várias entradas)
--allquando a URL é um vídeo de múltiplas partes / coleção / playlist do Bilibili, processa todas as entradas (padrão: apenas a primeira)
--lang zhcódigo do idioma falado (zh, en, ja, …); padrão: detecção automática
--model automodelo Whisper: auto / tiny / base / small / medium / large-v3 / large-v3-turbo (padrão da CLI). auto = large-v3-turbo em GPU NVIDIA, small em CPU
--device cpuforçar CPU (auto / cuda / cpu)
--interval 3aproximadamente um quadro-chave a cada N segundos. Padrão por duração: 2 s abaixo de 1 min, 3 s abaixo de 3 min, 6 s abaixo de 10 min, 12 s abaixo de 30 min, 20 s além disso
--frames 30número máximo de quadros-chave (padrão por duração, limite 150; 300 com --interval)
--scene 0.2sensibilidade a mudanças de cena 0–1, menor = mais sensível (padrão 0.3)
--no-dedupemanter quadros quase idênticos ao anterior (padrão: descartá-los: < 2 % dos pixels da miniatura alterados)
--no-asrsem reconhecimento de fala mesmo sem legendas (apenas imagens)
--no-framessem quadros-chave (apenas texto)
--force-asrexecutar reconhecimento de fala mesmo quando existem legendas
--cookies-from-browser chromebaixar com o login do seu navegador (vídeos HD / de membros do Bilibili, YouTube com restrição de login)
--keepmanter o vídeo de origem baixado
--ui-lang enidioma dos títulos e rótulos do report.md: zh (padrão) ou en
--jsonimprimir uma linha do manifesto JSON no final (para scripts)
--install-skillinstalar a habilidade do agente em ~/.claude/skills/yueying
mcpexecutar o servidor MCP (mcp --setup, mcp --check, mcp --version)

A habilidade (src/yueying/skill/SKILL.md) diz a um agente de codificação para preferir as ferramentas MCP quando presentes e, caso contrário, executar a CLI e ler report.md além das folhas de contato. Ferramentas que suportam o padrão Agent Skills podem copiar ~/.claude/skills/yueying/SKILL.md para sua própria pasta de habilidades.

Comparação com projetos semelhantes (setembro de 2026)

yueyingclaude-videoclaude-real-videomcp-video-analyzer
Servidor MCPsimnão (apenas habilidade)não (habilidade)sim (Node)
Reconhecimento de fala offlinesim — legendas primeiro, faster-whisper local caso contráriofallback de Whisper em nuvemASR primeirowhisper instalado separadamente
Detecção automática de GPU + fallback de CPUsim
ffmpeg incluídosimffmpeg manual
Testado no Windowssim (Windows 11)
Folhas de contato (3x3)sim
Carimbos de data/hora nos quadrossim
Bilibili / Douyin / Xiaohongshusim

"–" significa que o projeto não anunciava o recurso quando olhamos; verifique os READMEs deles, podem ter evoluído.

Política de privacidade

O yueying não coleta nada e não tem telemetria, análises, relatórios de falhas ou verificações de atualização. Todo o processamento é local. As únicas conexões de rede são (1) ao site de vídeo da URL que você passa, via yt-dlp, e (2) ao Hugging Face (ou HF_ENDPOINT) para baixar um modelo Whisper uma vez. As saídas são armazenadas na sua pasta até você excluí-las. A transcrição e quaisquer quadros solicitados são enviados apenas ao modelo que seu cliente MCP está configurado para usar — essa transferência é regida pelos termos do seu cliente e provedor, não pelo yueying. Perguntas: GitHub issues. Texto completo: docs/privacy.md.

Solução de problemas / FAQ

  • "Nenhum resultado recebido" no Claude Desktop. Mantenha wait_seconds em 45 (o agente então re-chama watch_video) e execute uvx yueying mcp --setup uma vez para que a primeira chamada não seja também o download do modelo.
  • spawn uvx ENOENT / servidor falha ao iniciar. O host não consegue ver seu PATH: use o caminho absoluto para uvx (where uvx / which uvx) ou para yueying-mcp como "command".
  • Janelas de console piscam no Windows. Atualize para 0.2.0+: processos filhos são iniciados sem janela. Se ainda os vir, você está executando uma instalação antiga (uv cache clean yueying).
  • Mojibake / ????? em títulos. Adicione "env": { "PYTHONUTF8": "1" } à configuração do servidor (todos os trechos acima o incluem).
  • Erro 412 / "-352" do Bilibili. O site quer um login: cookies_from_browser="edge" ou "chrome" (feche o Chrome primeiro no Windows).
  • YouTube "Faça login para confirmar que você não é um robô". Mesma correção: cookies_from_browser. Também tente atualizar o yt-dlp: uv cache clean yueying ou pip install -U yt-dlp.
  • Lento na CPU. model="small" já é a escolha automática sem GPU NVIDIA; use mode="frames" quando apenas as imagens importam, ou mode="transcript" para pular quadros-chave.
  • Nomes, números e código errados na transcrição. Esperado com qualquer ASR — o agente é instruído a confiar no texto na tela; peça para get_frame_at o momento.
  • Download do modelo lento ou bloqueado (China continental). Defina HF_ENDPOINT=https://hf-mirror.com no env do servidor (a CLI alterna para o espelho automaticamente quando huggingface.co está inacessível).
  • Erro de GPU (CUDA / cuDNN / memória insuficiente). model="small" ou YUEYING_DEVICE=cpu; instale os wheels CUDA com yueying[cuda].
  • Quer reprocessar com configurações diferentes. watch_video(video=…, refresh=true, …) — ele encerra um trabalho em execução para aquele vídeo, exclui a entrada e recomeça.

Como funciona

video / URL ──► yt-dlp (≤720p) + platform subtitles
            ──► ffmpeg 16 kHz audio ──► faster-whisper (skipped when subtitles exist)
            ──► ffmpeg scene detection ──► keyframes (near-duplicates dropped)
            ──► Pillow: burn "#n mm:ss", pack 3x3 contact sheets
            ──► report.md · transcript.txt · transcript.srt · manifest.json

MCP client ──stdio──► mcp_server.py ──spawns──► python -m yueying.cli <video> --json --ui-lang en
                       │  parses the child's progress lines, long-polls, caches per video
                       └─► store.py (cache keys / folders) · query.py (paging, search, frames)

O processo do servidor nunca carrega yt-dlp, Whisper ou CUDA; todo o trabalho pesado roda em um processo filho que é encerrado junto com o servidor. Tudo vive em src/yueying/:

ArquivoResponsabilidade
cli.pyentrada de linha de comando; executa o pipeline; despacho de subcomando mcp; --install-skill
mcp_server.pyo servidor MCP: seis ferramentas, executor de trabalhos, análise de progresso, renderização DONE/RUNNING/ERROR, --setup
store.pyraiz de saída, URLs canônicas, chaves de cache e nomes de pasta por vídeo, marcadores .job
query.pyfunções puras sobre um manifesto: paginação de transcrição, busca, quadro mais próximo, intervalos de folha de contato, redução de imagem
models.pynomes de modelos Whisper, tamanhos e repositórios Hugging Face (sem imports pesados)
download.pydownload via yt-dlp, escolha de idioma de legenda, listagem de playlist/coleção
ffm.pywrapper ffmpeg: sondagem, extração de áudio, legendas incorporadas, timeouts
subs.pyanálise de legendas srt / vtt / JSON do Bilibili, deduplicação de legendas automáticas do YouTube
asr.pytranscrição faster-whisper, seleção GPU/CPU, modelo auto, fallbacks
frames.pydetecção de cena, temporização de quadros, extração, deduplicação, carimbo de data/hora, folhas de contato
report.pyreport.md, arquivos de transcrição, manifest.json (rótulos zh/en), carregamento de manifesto
skill/SKILL.mda habilidade do agente

Roadmap

  • próximo.mcpb pacote de um clique para Claude Desktop, listagem no Smithery.
  • 0.3 — ferramentas forget_video / poda, inglês como idioma padrão de relatório da CLI, --all (playlists) via MCP.

Créditos

Licença

MIT — veja LICENSE.


中文说明

阅影(yueying)让 AI 看懂视频。 给 Claude Desktop、Claude Code、Cursor 等支持 MCP 的工具一个本地视频文件或视频链接(B站 / YouTube / 抖音 / 小红书 …),它就能拿到带时间戳的文字稿和关键帧九宫格:字幕优先,没有字幕就本地 faster-whisper 识别,全程离线,不上传、不要 API key。链接通过 yt-dlp 以 ≤720p 下载,处理完默认删除原视频。完整文档见上方英文部分。

安装

# 1. 装 uv(不需要先装 Python)
winget install astral-sh.uv          # Windows;macOS: brew install uv
# 2. 预热:安装、探测显卡、下载模型、跑 2 秒冒烟测试、打印配置
uvx yueying mcp --setup

不用 uv:pip install yueying(有 NVIDIA 显卡再加 pip install "yueying[cuda]"),然后 yueying mcp --setup 会打印 yueying-mcp 的绝对路径。Windows 也可以下载仓库后双击 install.cmd,它会建独立环境、装 Claude Code 技能、跑 --setup 并打印可粘贴的配置。

配置

Claude Desktop(%APPDATA%\Claude\claude_desktop_config.json,改完完全退出再打开;Windows 下 uvx 找不到就写绝对路径,如 C:\\Users\\<你>\\.local\\bin\\uvx.exe)、Cursor(~/.cursor/mcp.json)、Windsurf(~/.codeium/windsurf/mcp_config.json)都是同一段:

{ "mcpServers": { "yueying": { "command": "uvx", "args": ["yueying", "mcp"], "env": { "PYTHONUTF8": "1" } } } }

Claude Code 一行:

claude mcp add --transport stdio --scope user yueying --env PYTHONUTF8=1 -- uvx yueying mcp

Cline 在同一段里加 "type": "stdio""timeout": 1800,并把 get_transcriptsearch_transcriptget_framesget_frame_atlist_videos 放进 autoApprove。VS Code 的 .vscode/mcp.json 根键是 servers 并加 "type": "stdio"

六个工具

工具用途
watch_video(video, mode, language, model, frame_interval_seconds, cookies_from_browser, output_dir, refresh, wait_seconds, max_chars)看一个视频:本地绝对路径或链接。返回 DONE(概览 + 文字稿)、RUNNING(进度,用同一个 video 再调一次即可继续等)或 ERROR(英文提示)。结果按视频缓存,refresh=true 重做
get_transcript(video, start, end, format, max_chars)按时间段读文字稿;format="srt" 导出字幕
search_transcript(video, query, context_seconds, limit)找「哪里提到了 X」,给出时间、上下文、最近的关键帧号和九宫格号
get_frames(video, kind, start, count, max_width)看画面:先看九宫格(grids),需要细节再看单帧(frames);每次最多 3 张
get_frame_at(video, time, max_width)看某一时刻:代码、PPT、图表、界面;本地文件还在就精确抽帧
list_videos(limit)列出处理过的视频(video_id、标题、时长、文字来源、日期、大小、目录)和正在跑的任务

Claude Desktop / Cursor 里 wait_seconds 保持默认 45;Claude Code / Cline 配好 timeout 后可以给到 1500,一次调用就等到结果。第一次语音识别要下载模型(CPU 约 480 MB 的 small,显卡约 1.6 GB 的 large-v3-turbo),--setup 会提前下好。

输出目录与环境变量

结果在 ~/yueying_out/<名字>-<video_id>/YUEYING_OUT_DIR 可改),每个视频一个文件夹:report.mdtranscript.txttranscript.srtgrid_01.jpg …frames/manifest.json。约每小时视频 25 MB;不会自动删,删文件夹即可。常用环境变量:YUEYING_OUT_DIR(输出根目录)、YUEYING_MODEL(默认 auto:有 NVIDIA 显卡用 large-v3-turbo,否则 small)、YUEYING_DEVICEauto/cuda/cpu)、YUEYING_LANG(服务端 report.md 语言,默认 en,中文写 zh)、YUEYING_KEEP_SOURCE=1(保留下载的原视频)、YUEYING_JOB_TIMEOUT(单个视频上限秒数,默认 7200)、PYTHONUTF8=1(Windows 防乱码)。

B站 cookie

不登录 B站 只给 480p,看 PPT 和代码够用;高清或会员视频传 cookies_from_browser="chrome"(或 edge),Windows 下先关掉 Chrome,否则读不到 cookie 数据库。遇到 412 / -352 也是同样的处理。

国内镜像

下载模型慢或被墙:在服务器配置的 env 里加 "HF_ENDPOINT": "https://hf-mirror.com"。命令行版在 huggingface.co 连不上时会自动切到镜像。

命令行用法

yueying 视频.mp4
yueying "https://www.bilibili.com/video/BVxxxx"
yueying "https://www.youtube.com/watch?v=xxxx" --out ./notes/xxx
yueying 第1课.mp4 第2课.mp4 "https://www.bilibili.com/video/BVyyyy"   # 多个一起,各出各的文件夹 + index.md
yueying "https://www.bilibili.com/video/BVxxxx" --all                      # B站 分 P / 合集 全部处理
yueying --install-skill                                                    # 装 Claude Code 技能

默认输出 ./yueying_out/<视频名>/,日志和 report.md 默认中文(--ui-lang en 切英文)。常用参数:--lang zh 指定语言、--model small 换小模型(auto 自动选)、--device cpu--interval 3 抽帧间隔、--frames 30 最多帧数、--scene 0.2 场景灵敏度、--no-dedupe 不去重、--no-asr 只要画面、--no-frames 只要文字、--force-asr 有字幕也识别、--cookies-from-browser chrome--keep 保留原视频、--json 末尾打印一行 manifest。完整说明见上方英文表格。