| name | douyin-scribe |
| description | Turn videos in a Douyin favorites collection (not the likes list) into one processed Markdown transcript per video through AI pre-screening, download, ASR, and post-processing. |
douyin-scribe
Prerequisites
- macOS (Apple Silicon) only.
- Ensure the
pd-helper-cli Skill, ffmpeg, and mlx-qwen3-asr are available; otherwise, install or configure them as described in this Skill's README.
State and Deduplication
~/.pd-helper/douyin-scribe/
├── transcripts/ # final transcripts
└── ledger.jsonl # append-only processing ledger
Each ledger line records a terminal outcome:
{"awemeId":"7123...","outcome":"done","title":"...","file":"....md","ts":"2026-07-10T12:00:00+08:00"}
{"awemeId":"7456...","outcome":"no_speech","title":"...","reason":"Lyrics throughout; no spoken content","ts":"..."}
outcome is one of: done (output written, with file), no_speech (no spoken content, with reason), or no_value (post-transcription re-screen rejected it, with reason).
Pre-screening
- Keep: informative content that remains useful as text. Prioritize business and skills topics, such as management, industry news, celebrity interviews, AI and software tools, professional tutorials, and personal development. When unsure, keep it.
- Skip: content whose value does not survive as text, such as pure comedy, product promotion, advertising reads, and film or TV recaps.
Workflow
Persist intermediate artifacts. On resume, skip steps whose artifacts already exist.
Entry Points
- A. Agent collection: start at step 1; the working directory is the CLI-returned
batchDir.
- B. User provides JSON + videos: a ZIP exported from the floating panel (extract it) or an existing directory; skip step 1.
- C. User provides JSON only: skip step 1; obtain videos in step 4.
For B and C, use the directory containing the user-provided materials as the working directory.
1. Collect
Call dyExportCollection from pd-helper-cli:
- Set
json=true; omit video.
- For “last N days”, set
from=<current time minus N days, in milliseconds>.
- For “all favorites”, set a sufficiently large
maxCount (the default is only 50).
- The terminal
summary frame contains batchDir.
2. Deduplicate
For each list item, check ledger.jsonl and exclude those with an existing terminal outcome.
3. Pre-screen
Classify each item using Pre-screening. Write prescreen.json to the working directory. Each item contains awemeId, title, verdict (keep or skip), and a one-sentence reason. If prescreen.json exists, reuse its existing verdicts and classify only new items in this run.
4. Download
For each keep item without an MP4, call dyDownloadVideo from pd-helper-cli:
- Pass
playUrl when the JSON contains play_addr.
- Wait a random 1–2 seconds between items.
- Record a failed item and continue; report all failures together at the end.
5. Transcribe
Ensure <working directory>/wav/ and <working directory>/txt/ exist, then extract audio and run ASR:
ffmpeg -i <id>.mp4 -vn -ac 1 -ar 16000 <working directory>/wav/<id>.wav
mlx-qwen3-asr <working directory>/wav/*.wav --model mlx-community/Qwen3-ASR-1.7B-8bit -f txt -o <working directory>/txt/
6. Post-process
Process each transcript text file: triage it first, then prepare the final copy.
Triage (append a ledger entry and skip rejected items)
- If it is clearly unrelated to its title overall, or has song-like characteristics throughout (rhyming short lines, repeated choruses, no information progression), record
no_speech with a reason. Lyrics mixed only into the intro, outro, or backing track do not qualify.
- Re-screen all other items against
Pre-screening; if rejected, record no_value with a reason.
Final copy (improve readability without adding facts)
- Correct ASR homophone errors, add punctuation, and split by meaning.
- Complete omitted or jumpy spoken phrasing.
- Do not invent missing information or logical links; do not add markers such as
[information missing].
- Remove lyric fragments and filler such as “follow for more”.
7. Output
Write ~/.pd-helper/douyin-scribe/transcripts/<title>.md: use the video title as the H1 and the final copy as the body. Strip invalid filename characters; fall back to awemeId when the title is empty or the filename collides. Append a done ledger entry with file.