¿Qué hace dsh-bilibili-subtitles?
Convierte un enlace de video de Bilibili en un documento de subtítulos legible, buscable y entregable.
Principio fundamental: Primero toma los subtítulos existentes, luego considera transcripción por voz o OCR. No descargues el video/audio para Whisper a menos que sea necesario; los subtítulos de la plataforma Bilibili (incluyendo los generados por IA) suelen ser de mejor calidad y más rápidos.
Cuándo usarlo
Adecuado cuando:
- El usuario proporciona un enlace de video de Bilibili, número BV, número av, enlace de serie ep/ss o enlace corto b23.tv, y solicita "extraer subtítulos/convertir a documento/exportar a Word/Markdown".
- El usuario tiene un video local con subtítulos externos y quiere convertirlos por lotes a documentos.
- El usuario necesita un guion de subtítulos con marcas de tiempo, comparación bilingüe o combinación de múltiples episodios.
- El usuario requiere un informe de calidad de los subtítulos para decidir si vale la pena la revisión manual.
No adecuado cuando:
- Se necesita "traducir" subtítulos: esta habilidad solo hace alineación bilingüe, no traducción automática.
- Se necesita separación precisa de hablantes: la diarización automática no está habilitada; solo se conservan las etiquetas
[hablante]existentes en los subtítulos. - Se necesita evitar restricciones de inicio de sesión, pago o región de Bilibili: pide al usuario que proporcione una cookie que tenga derecho a usar, o que use archivos locales.
Instalación y uso
- Plugin: https://github.com/Chenfan2/dsh-bilibili-subtitles (en DSH Desktop: "Plugins → Añadir plugin" pega la URL, o ejecuta
dsh plugin --profile web add github:Chenfan2/dsh-bilibili-subtitles). - Solo skill: Copia todo el directorio al directorio
skillsde DSH (o ejecutainstall.ps1).
Después de la instalación, ejecuta en el directorio:
python main.py "https://www.bilibili.com/video/BV1xx411c7mD" --format md,docx
Si solo es para uso temporal, también puedes ejecutar main.py directamente en el directorio del skill.
Un solo comando
python main.py "https://www.bilibili.com/video/BV1xx411c7mD" --format md,docx
Salida en output/:
Título_BVxx.mdTítulo_BVxx.docxTítulo_BVxx.quality.json(informe de calidad)Título_BVxx.segments.json(subtítulos estructurados limpios)_manifest.json(resumen de la ejecución actual)
Contrato de entrada / salida
Entrada
| Tipo | Ejemplo |
|---|---|
| Video de Bilibili | https://www.bilibili.com/video/BV1xx411c7mD?p=2 |
| Número BV / av | BV1xx411c7mD, av80433022 |
| Serie / Episodio | https://www.bilibili.com/bangumi/play/ep123456, .../ss28747 |
| Enlace corto | https://b23.tv/xxxxxx |
| Video local | input.mp4, input.mkv |
| Subtítulos externos | --subtitle input.srt (también .ass/.vtt/.json/.txt) |
| Directorio / lote | python main.py ./videos --format md,docx |
Salida
- Ruta del archivo de documento (Markdown/Word/PDF/TXT/SRT).
- Subtítulos estructurados:
[{start, end, text, speaker?, lang?, confidence?, translation?}]. - Informe de calidad: origen de subtítulos, idioma, cobertura, segmentos de baja confianza, advertencias, muestras de inicio/medio/final.
- Registro de intentos de procesamiento: éxito/fallo/salto de cada proveedor con su motivo.
Prioridad de fuentes de subtítulos
Se intentan en el siguiente orden; si falla, se degrada automáticamente, a menos que se deshabilite explícitamente:
- Subtítulos externos del usuario (
--subtitle): máxima calidad, completamente controlable. - Subtítulos de plataforma Bilibili / subtítulos AI: se leen a través de
x/player/v2, requiereSESSDATA. - Subtítulos incrustados en el video local: detección con
ffprobe+ extracción a SRT conffmpeg. - OCR de subtítulos duros: solo para videos locales, requiere
--ocr; experimental. - Transcripción por voz Whisper: se habilita con
--asro como respaldo automático; la primera vez descarga el modelo.
Sin inicio de sesión, Bilibili generalmente no devuelve la lista de subtítulos. En este caso, se mostrará
LOGIN_REQUIREDy se pedirá la cookie o se habilitará ASR. Es una limitación de la plataforma, no un error del enlace.
Inicio de sesión en Bilibili (necesario para subtítulos de plataforma)
La API de subtítulos de plataforma solo devuelve subtitle_url para sesiones iniciadas. Se recomienda usar variables de entorno para evitar que aparezcan en el historial de comandos:
$env:BILIBILI_SESSDATA = "tu_SESSDATA"
python main.py "https://www.bilibili.com/video/BV1xx411c7mD" --format md,docx
Cómo obtenerlo: Inicia sesión en bilibili.com desde el navegador → Herramientas de desarrollador → Application/Aplicación → Cookies → bilibili.com → Copia el valor de SESSDATA.
También se admite:
python main.py URL --sessdata "valor_de_SESSDATA"
python main.py URL --cookie "SESSDATA=...; bili_jct=..."
python main.py URL --cookies cookies.txt
- La cookie equivale a las credenciales de la cuenta, no debes escribirla en el repositorio, en documentos ni enviarla a canales públicos.
- Este skill solo usa la cookie en memoria; en los registros e informes se oculta.
- Cuando la cookie expire, solo tienes que volver a copiarla.
Parámetros comunes
| Parámetro | Función |
|---|---|
--format md,docx,pdf,txt,srt,json | Formatos de salida, separados por comas; por defecto md |
-o, --output PATH | Especifica el archivo de salida para una sola entrada y formato |
--out-dir DIR | Directorio de salida, por defecto output |
--title TEXT | Sobrescribe el título del documento (por defecto se usa el título del video / nombre del archivo) |
--subtitle PATH | Archivo o directorio de subtítulos externos (prioridad máxima) |
--language zh | Idioma preferido para subtítulos/transcripción; los subtítulos de plataforma se filtran por idioma |
--bilingual | Modo bilingüe; si hay dos pistas, se alinean por tiempo; si solo una, se intenta dividir por líneas |
--timestamps / --no-timestamps | Muestra [00:12] en el texto; por defecto se muestra |
--merge-sentences / --no-merge-sentences | Combina oraciones cortas cortadas artificialmente; por defecto se combinan |
--no-auto-punctuation | Desactiva la puntuación automática para ASR/OCR (por defecto activada) |
--pages auto/all/1,3-5 | Selección de episodios; por defecto solo el episodio especificado en el enlace; si no se especifica, P1 |
--template default/minimal/archivo.md | Plantilla de Markdown |
--quality-report PATH | Ruta del informe de calidad JSON |
--no-quality | No genera informe de calidad ni incluye información de procesamiento en el documento |
--glossary terms.json | Reemplazo de términos, ej. {"DeepSeek":"Shenzhen DeepSeek"} |
--json-summary | Salida estándar de un resumen legible por máquina (útil para que el agente lo lea) |
--asr / --no-asr | Permite / prohíbe el respaldo de Whisper; por defecto automático (solo si está instalado) |
--asr-model small | tiny/base/small/medium; por defecto small |
--model-dir DIR | Directorio de caché del modelo Whisper (por defecto ./.vsub-models-cache) |
--ocr | Realiza OCR en subtítulos duros de videos locales (experimental) |
--ffmpeg PATH | Especifica la ruta de ffmpeg/ffprobe |
--strict | Devuelve código de salida distinto de cero si falla alguna entrada o la calidad es fail |
Parámetros completos: python main.py --help.
Flujo de trabajo recomendado (para el agente)
-
Determina la entrada:
- Enlace Bilibili / BV / av → ejecútalo directamente.
- Video local → busca archivos
.srt/.vtt/.asscon el mismo nombre, si existen usa--subtitle; si no, intenta subtítulos incrustados. - Solo archivo de subtítulos → también se puede usar como entrada directa.
-
Primero ejecuta la salida por defecto, no actives ASR sin antes revisar el informe de calidad:
python main.py "<enlace>" --format md,docx --out-dir output -
Si aparece
LOGIN_REQUIRED:- Informa al usuario de que los subtítulos de plataforma necesitan
SESSDATAy proporciona el método de configuración; no reintentes repetidamente. - Si el usuario no tiene cookie, entonces sugiere
--asr(explica que la primera vez descarga el modelo, lleva tiempo y puede producir errores de reconocimiento).
- Informa al usuario de que los subtítulos de plataforma necesitan
-
Revisa
<stem>.quality.json:status=ok: entrega directamente.status=warn: revisawarnings, especialmente cobertura, solapamientos, baja confianza; advierte en la entrega.status=fail: no finjas éxito; informa del motivo del fallo y sugiere subtítulos externos / ASR / OCR.
-
Usa
presentpara entregar el.md/.docxcomo archivo final; el informe de calidad solo se adjunta si el usuario lo solicita.
Entorno de ejecución:
-
Prioriza el Python devuelto por
load_workspace_dependencies(incluyepython-docx). -
Ejemplo de invocación en Windows PowerShell:
& "C:\...\python.exe" main.py "<enlace>" --format md,docx --out-dir output -
Todos los archivos de salida y temporales deben colocarse dentro del directorio de trabajo de la sesión; no uses el directorio temporal del sistema (podría ser rechazado por la sandbox).
Campos del informe de calidad
{
"status": "ok | warn | fail",
"score": 96.5,
"source": "bilibili",
"language": "zh",
"segments": 320,
"paragraphs": 86,
"duration": 1260.0,
"duration_covered": 0.96,
"coverage_span": 0.99,
"overlaps": 0,
"low_confidence_segments": 3,
"duplicate_segments": 1,
"gaps_over_10s": 2,
"warnings": ["..."],
"samples": {"head": [], "middle": [], "tail": []}
}
duration_covered: relativo a la duración total del video; puede ser bajo si se limpiaron anuncios de inicio/fin.coverage_span: relativo al intervalo entre el primer y el último subtítulo; refleja mejor si "la parte hablada está cubierta".samples: hasta 5 segmentos de inicio, medio y final, para facilitar la revisión manual.- Causas comunes de
status=fail: sin segmentos, cobertura inferior al 30%, todos los episodios fallaron.
Fallos y degradación
| Situación | Comportamiento |
|---|---|
| Fallo al analizar subtítulos externos | Registra el fallo, continúa con subtítulos de plataforma/incrustados |
Subtítulos de plataforma: LOGIN_REQUIRED | Solicita configurar SESSDATA; si faster-whisper está instalado y ASR está permitido, transcripción automática |
| Plataforma sin pista de subtítulos | Muestra NO_SUBTITLE; se puede usar --asr o --subtitle |
| Subtítulo incrustado es mapa de bits PGS/VobSub | No se puede convertir directamente a SRT; sugiere usar OCR o subtítulos externos |
| ASR no instalado | Salta y muestra pip install faster-whisper; no falla en silencio |
| Fallo en algún formato de salida | Los demás formatos continúan; se registra en quality.warnings; solo RENDER_FAILED si todos fallan |
| Fallo parcial en lote | Los que tienen éxito se entregan; el fallo se registra en _manifest.json y *.error.json |
Códigos de salida:
0Éxito (en lote: al menos uno tuvo éxito).2Error de entrada/enlace/API/análisis.3Sin subtítulos, requiere inicio de sesión, calidad fallida.4Falta dependencia (ffmpeg/Whisper/docx, etc.).5Error al renderizar el documento.1Error inesperado.
Ejemplos
# Básico: subtítulos de plataforma → Markdown + Word
python main.py "https://www.bilibili.com/video/BV1xx411c7mD" --format md,docx
# Solo Word, especificando nombre de archivo
python main.py "BV1xx411c7mD" --format docx -o "notas_papel.docx"
# Múltiples episodios + marcas de tiempo + informe de calidad
python main.py "https://www.bilibili.com/video/BV1xx411c7mD?p=1" --pages all --format md
# Priorizar subtítulos externos
python main.py "input.mp4" --subtitle "input.srt" --format md,docx
# Bilingüe (cuando la plataforma tiene dos pistas, se alinean automáticamente)
python main.py "BV1xx411c7mD" --bilingual --language zh --format md,docx
# Sin inicio de sesión, con respaldo ASR (primera vez descarga modelo)
python main.py "BV1xx411c7mD" --asr --asr-model small --format md,docx
# Directorio por lotes
python main.py "./videos" --format md,docx --out-dir output/lote
# OCR de subtítulos duros locales (experimental)
python main.py "input.mp4" --ocr --ocr-fps 2 --format md
Limitaciones
- La disponibilidad de subtítulos de plataforma depende del video, la cuenta, la región y la configuración del creador; esta habilidad no puede eludir los permisos.
- Los subtítulos generados por IA pueden contener errores, omisiones o desplazamiento en la línea de tiempo; el informe de calidad solo advierte, no sustituye la revisión manual.
- El modo bilingüe es "alineación por tiempo", no traducción; solo se muestra comparación si las dos pistas están en diferentes idiomas.
- La separación automática de hablantes no está implementada; solo se analizan etiquetas como
[Zhang San],【Zhang San】,Zhang San:en los subtítulos. - OCR solo para videos locales, por defecto en el 30% inferior de la imagen; para animación/pantalla vertical/subtítulos en movimiento, se necesita ajustar
--ocr-cropo--ocr-full-frame. - PDF requiere LibreOffice o
reportlab; si no, se informa del error claramente y no afecta a md/docx. - El ASR para videos largos puede ser lento; el modelo
smallocupa aproximadamente 460 MB en la primera descarga.
Derechos de autor y privacidad
- Solo procesa videos/subtítulos que el usuario tenga derecho a usar; no uses esta habilidad para descargar en masa contenido protegido por derechos de autor.
- Los documentos de subtítulos conservan el título original del video, el nombre del creador y el enlace para facilitar la trazabilidad.
- Las cookies y las URL de CDN firmadas no se escriben en registros/informes de calidad; aun así, se recomienda que el usuario no pegue cookies en lugares públicos.
- Los archivos temporales de audio/cuadros se guardan por defecto en el directorio
.vsub-tmpdentro del directorio de salida y se eliminan automáticamente al finalizar;--keep-temppermite conservarlos para depuración.
Estructura de archivos
dsh-bilibili-subtitles/
├── SKILL.md
├── README.md
├── main.py # Punto de entrada CLI
├── vsub/
│ ├── bilibili.py # URL/API/subtítulos/audio
│ ├── input_adapter.py # Adaptador de entrada
│ ├── pipeline.py # Orquestación de cinco capas
│ ├── providers/ # external/bilibili/embedded/ocr/asr
│ ├── parsers/ # srt/vtt/ass/bilibili-json/plain
│ ├── cleaners/ # Limpieza, combinación, bilingüe, glosario
│ ├── renderers/ # md/docx/pdf/txt/srt/json
│ └── quality.py # Validación de calidad
├── templates/
├── tests/
└── requirements.txt