Transform YouTube URL(s) into readable articles, with raw material preserved for auditing.
Do not deliver stenography with time markers. The final artifact is editorial prose faithful to the meaning of the exposition.
This skill is self-sufficient: the flow and the cleaning script are here. Do not depend on external documents from the user's collection. Do not use paths, machine names, personal folders, or anyone's example collections.
When to use
- Transcribe sermon / exposition / class / lecture from YouTube
- Process playlist or batch of URLs
- Clean
.srt/.vttwith auto-caption echo - Rewrite orality into an article with paragraphs and punctuation
- Organize collection
raw/+artigos/+ index
When NOT to use
- Create a sermon or new text from scratch (without audio/video source)
- Write a book or ebook (
teo-livro) — the article from this skill can be input for/teo-livro, not the volume - Technical exegesis disconnected from a spoken source
- Download the video itself (this skill downloads only subtitles, unless explicitly requested otherwise)
- Word-for-word subtitles with time markers for video captioning
Prerequisites
yt-dlpinPATH(install/update if the extractor fails or there is a 429)- Python 3
- Network access to YouTube
which yt-dlp && yt-dlp --version
python3 --version
Locate the skill script
teo-transcricao/
├── SKILL.md
└── scripts/
└── limpar_legendas.py
Resolve the path from this skill's directory (as the agent loaded it):
python3 "$SKILL_DIR/scripts/limpar_legendas.py" --help
Do not hardcode machine paths in the procedure. Use the destination folder provided by the user (or the cwd).
Default output (collection folder)
<colecao>/
├── README.md
├── artigos/ # prosa final
│ ├── 01-slug-do-titulo.md
│ └── ...
└── raw/
├── legendas-brutas/ # .srt / .vtt
└── textos-limpos/ # texto corrido oral, sem marcações de tempo
Conventions:
- Numbering
01,02, … in collection order - Clean text:
NN - [Autor] | [Título] | [VIDEO_ID].txt - Article:
NN-slug-do-titulo.md - Always preserve the raw files in
raw/ - Do not overwrite an article already edited by hand without backup or confirmation
Flow (fixed order)
URL(s)
→ 1. Metadados
→ 2. Legendas (yt-dlp)
→ 3. Texto limpo (script desta skill)
→ 4. Artigo(s) Markdown com bloco de metadados
→ 5. Verificação de qualidade + README da coleção
Do not skip to the article without clean text. Do not delete raw subtitles after cleaning.
1) Metadata
For each URL (or playlist item), collect rich fields — they go into the article:
yt-dlp --skip-download --flat-playlist \
--print "%(playlist_index)s|%(id)s|%(title)s|%(channel)s|%(uploader)s|%(upload_date)s|%(duration)s|%(webpage_url)s|%(playlist_title)s|%(playlist_id)s" \
"URL_OU_PLAYLIST"
Fields to capture:
| Field | Typical source | Required in the article? |
|---|---|---|
url |
webpage_url |
yes |
id |
video id | yes (tracking / filename) |
title |
video title | yes |
author / preacher |
title, channel, description, or user | yes |
channel |
YouTube channel | recommended |
date / upload_date |
YYYYMMDD → YYYY-MM-DD |
recommended |
duration |
seconds → readable (45 min) |
optional |
series / playlist |
playlist title, if any | optional |
passage / topic |
title or content | optional |
NN |
next free index in the collection | yes in the collection |
If the playlist mixes authors, record the correct authorship for each item. Do not invent author, date, or URL.
2) Download subtitles
Subtitles only — not the video:
mkdir -p raw/legendas-brutas raw/textos-limpos artigos
yt-dlp \
--skip-download \
--write-auto-subs \
--write-subs \
--sub-langs "pt,pt-BR,pt-PT,en,en-US,en-GB" \
--convert-subs srt \
--sleep-requests 1 \
--sleep-interval 1 \
--max-sleep-interval 3 \
-o "raw/legendas-brutas/%(id)s - %(title)s" \
"URL_1" "URL_2"
Adjust --sub-langs if the user requests another language. Default priority in cleanup: pt > pt-BR > pt-PT > en > en-US > en-GB.
Common problems:
| Symptom | Action |
|---|---|
| HTTP 429 | pause; rerun only the missing ID; keep pauses between requests |
was .vtt |
ok — the script reads srt and vtt |
| no subtitle in the preferred language | use the best alternative language; the article text already reveals the language |
| browser emulation warning | ignorable if the file downloaded |
| video without subtitles | inform the user; do not invent the monologue |
3) Clean text (removal of duplications in rolling subtitles)
YouTube auto-subtitles repeat the end of the previous block on each new line. Without merging, the text becomes unreadable.
python3 "$SKILL_DIR/scripts/limpar_legendas.py" \
--input-dir "raw/legendas-brutas" \
--output-dir "raw/textos-limpos" \
--id VIDEO_ID \
--num 07 \
--title "Título do vídeo" \
--preacher "Nome do autor" \
--url "https://..."
Batch (JSON manifest = list of objects with id, n, title, preacher, url):
python3 "$SKILL_DIR/scripts/limpar_legendas.py" \
--input-dir "raw/legendas-brutas" \
--output-dir "raw/textos-limpos" \
--manifest "raw/novos-videos.json"
The script: chooses language → removes time markers and tags → merges rolling blocks → paragraphs → .txt with source header.
Check before continuing: start without echo; words in the order of magnitude of the duration; language readable in the text itself.
The clean text is still oral. The final prose is in step 4.
4) Rewrite as an article
One file per talk. In batches, parallelize (one task per video).
Mandatory article format
Every article starts with title + metadata block and only then the body. Use YAML metadata (preferred) or equivalent Markdown block — but be consistent in the collection.
Preferred (YAML metadata):
---
title: "Título do artigo"
author: "Nome do autor/pregador"
source: "https://www.youtube.com/watch?v=VIDEO_ID"
video_id: "VIDEO_ID"
date: "YYYY-MM-DD"
channel: "Nome do canal"
duration: "46 min"
series: "Nome da série ou playlist, se houver"
passage: "Referência bíblica ou tema, se houver"
---
# Título do artigo
Introdução em prosa…
## Seção temática
Parágrafos…
## Conclusão
…
Metadata block rules:
source(URL) is mandatory when the source is a known video/URL.authoris mandatory.- Include
date,channel,video_id,duration,series,passagewhen available. - Do not include subtitle language — the article text already reveals the language.
- Do not include local paths, file names
.srt, nor a confession of “auto-subtitle” in the body. - Omit unknown fields; do not invent.
datein ISOYYYY-MM-DDwhen it comes fromupload_date.durationreadable (45 min) from the yt-dlp seconds.- Optional discreet final credit:
*Baseado na exposição de [Autor].*— without repeating the URL if it is already in the metadata.
Editorial rules for the body
- Preserve substance and order of ideas. Do not invent doctrine, examples, or applications absent from the original.
- Do not over-summarize. Cut only repetition, hesitation, and stage/live-stream filler.
- Published prose: punctuation, capitalization, short/medium paragraphs.
- Remove oral tics from the audio's language (in pt-BR: né, tá, tipo, assim, aí, beleza, olha só, ééé, etc.) — except intentional quotation.
- Illustrations: keep if they carry the argument; trim if they only warm up the audience.
- Correct obvious ASR with context. If uncertain, prudent wording or omission — don't guess.
- Correct authorship in the metadata (mixed collections exist).
- No time markings in the body.
- File name:
NN-slug-ascii-com-hifens.md.
Ready criteria
- YAML metadata with at least
title,author,source - Reads like an article, not like a caption
- Sections
##natural to the flow of the exposition - Almost zero oral tics
- Names/places reviewed
- Raw files intact in
raw/
Estimate: ~45–50 min of speech → article of ~4–6k words if the substance is preserved.
5) Quality check and index
rg -n -i --pcre2 '\b(né|tá bom|beleza|tipo assim|microfone|ééé|olha só)\b' artigos/
# metadados presentes?
rg -L -n '^source:|^author:' artigos/*.md || true
wc -w artigos/*.md
Update the README.md of the collection with sources, list of articles (title, author, ~words) and a note that the basis is captions + editorial editing.
Standards
| Situation | Standard |
|---|---|
| Folder not specified | collection in the current working directory with the structure above |
| Article language | the user's / the audio's |
| Caption | prefer pt*, otherwise best alternative language |
| Numbering | continue from the highest NN existing |
| Batch | one article per video |
| Video without captions | report; do not invent |
| Metadata | URL + author always; other fields when they exist |
Minimum input
| Field | Required? | Notes |
|---|---|---|
| URL(s) or playlist | yes | |
| Destination folder | recommended | otherwise, the current working directory |
| Author | recommended | infer from title/channel with caution |
| Numbering | optional | auto if a collection already exists |
| Raw only / article only | optional | default = full stream |
Limitations
- Auto-captions get names, references and rare terms wrong
- Merging the scrolling blocks removes echo; it does not interpret the content
- The article is an edition faithful to the meaning, not a word-for-word transcript
- For sensitive public/formal use, recommend ear-checking the critical passages
Anti-patterns
- Delivering SRT/VTT as the “final transcript”
- Article without URL/
sourcewhen the source is a known video - Including “subtitle language” in the article metadata
- Deleting
raw/after generating the article - Summarizing a long speech without the user asking for a summary
- Homogenizing authorship when there are several speakers
- Inventing bridges or applications absent from the audio
- Downloading the full video without need
- Depending on personal files or docs outside this skill
Scope
This skill covers capture + cleanup + editorial editing of an existing exposition.
It does not replace the skill for creation of a sermon (teo-sermao)、debate (teo-debate) or book (teo-livro).