by aligh98
Agent skill that directs scripts for TTS (ElevenLabs v3/v4 tags): rewrite for the ear, tag budget, free linter, A/B tester. | اسکیلی برای کارگردانی متن قبل از TTS: بازنویسی برای گوش، تگگذاری بدون زیادهروی، لینتر رایگان و تست A/B. فارسیمحور.
# Add to your Claude Code skills
git clone https://github.com/aligh98/tts-directorGuides for using ai agents skills like tts-director.
See how tts-director compares with popular alternatives.
tts-director is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by aligh98. Agent skill that directs scripts for TTS (ElevenLabs v3/v4 tags): rewrite for the ear, tag budget, free linter, A/B tester. | اسکیلی برای کارگردانی متن قبل از TTS: بازنویسی برای گوش، تگگذاری بدون زیادهروی، لینتر رایگان و تست A/B. فارسیمحور. It has 66 GitHub stars.
tts-director's catalog security scan is still queued. You can run an instant dependency and prompt-injection check now with the "Scan for vulnerabilities" button above.
Clone the repository with "git clone https://github.com/aligh98/tts-director" and add it to your Claude Code skills directory (see the Installation section above). tts-director ships a SKILL.md manifest, so compatible agents can discover and load it automatically.
tts-director is primarily written in Python. It is open-source under aligh98 on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh tts-director against similar tools.
No comments yet. Be the first to share your thoughts!
Available after the catalog security scan passes.
⚠️ Third-Party Software Notice
This skill is third-party open-source software developed and hosted independently on GitHub. SkillsLLM is an informational directory and does not control or maintain the underlying repository.
Any security checks, ratings, or warnings displayed by SkillsLLM are automated and limited in scope. They do not constitute a security certification or guarantee that the software is safe, error-free, or free from malicious code, vulnerabilities, compromised dependencies, or prompt-injection risks.
Review the source code, permissions, dependencies, and configuration before installing or running any third-party skill. Use is at your own risk. To the maximum extent permitted by applicable law, SkillsLLM is not liable for losses arising from third-party software.
The deep catalog scan for this skill is still queued. Run an instant dependency check now instead.
A great voiceover is about 80% text and 20% tags. The text sets the rhythm, the register and where the energy goes. Tags only push a delivery the text has already set up. A script with a tag on every line sounds like an over-acted ad and loses the viewer. A script with none often sounds read.
This skill does not replace your TTS pipeline. It prepares the text that goes into it. Scripts are stdlib Python 3.9+; ffmpeg/ffprobe are optional and give durations.
Beat map. Label every line with its role and a target energy from 1 to 5. The roles are:
Plan the arc before touching words. See Viral arc.
Rewrite for the ear. For Persian use references/persian-delivery.md; for English, references/english-delivery.md. Keep the meaning and every fact. Rewriting means:
Show the text to the person before generating anything. Generating audio costs them credits, and the wording is theirs to approve.
Tag pass. Tag only the beats the text alone cannot carry, within the Tag budget. For tag names and what each one is for, see references/audio-tags.md.
Lint (free):
python scripts/tag_lint.py SCRIPT --model eleven_v4 --tempo 1.15
It prints a beat map with estimated times. It flags:
Fix every ERROR. Keep a WARN only when you can say why.
A/B the risky lines. These are the hook, every laugh, any whisper or sarcasm, and the CTA. Check the cost first; --dry-run sends nothing:
python scripts/ab.py "VARIANT A" "VARIANT B" --voice VOICE_ID --stability 0.35 --stability 0.5 --prev "line before" --next "line after" --out probe/ab --dry-run
Remove --dry-run to generate. Every clip uses the same --seed, so the differences come from the text and the settings, not from chance. Each clip is transcribed:
LEAK means a tag was read aloud as a word. Drop or rephrase that tag.[laughter] or [خنده] means the sound was performed.Speech-to-text cannot judge excitement, so let a human ear pick the winner.
Generate the full script with the chosen variants and settings. Then:
ffmpeg -af atempo=1.1 (1.10–1.20 keeps pitch), not with a speed setting. If you have word timings, divide them by the same factor.previous_text/next_text and splice it in.Never over-tag. Every tag must help retention or make the voice more human. A tag that repeats what the text already says is noise.
Density: about 1 tag per 3–4 sentences, which is 4–8 tags in a 60–90 s reel. The linter errors above 0.5 tags per sentence and warns above 0.34.
Baseline energy is not a tag. The voice, a stability of 0.3–0.4 and punchy text set the overall energy. Do not put [excited] on every line. Save it for 2–3 peaks: the hook, the big reveal and the CTA push.
Laughs: 0 to 2 per reel, and never forced. Laugh only where a person would:
Never laugh on numbers, dates, prices, the offer itself or the CTA keyword. Keep laughs 20 s or more apart. Pick the tag by size: [chuckles] is the safe, light one; [laughs] is a clear laugh; use [laughs harder] for one big moment at most.
Contrast beats intensity. Attention comes from change. Use one change of delivery every 8–12 s; this is the pattern interrupt. For example:
One or two tags at a spot, never three. Put the tag right before the words it colours. Its effect runs to about the end of that sentence.
Bring the energy back after [whispers] or [sighs]. Do it on the next line with the text (a «!», a short punch) or with a delivery tag. Check it by ear.
Keep clarity lines clean. Numbers, dates, prices, product names and the CTA keyword are said plainly. A warm tag may come before the CTA sentence, never inside the keyword.
Never tag staging or music ([music], [standing]), and never tag sensitive topics such as grief, illness or tragedy.
For a 60–90 s vertical video:
| Time | Beat | Energy | Typical device |
|---|---|---|---|
| 0–3 s | HOOK | 5 | Urgency or curiosity in the first words: an interjection, a bold claim, a question, [gasps] or [excited]. No greeting. |
| 3–10 s | SETUP | 4 | Why it matters now: a deadline, or what they lose if they skip it. Short and fast. |
| every 8–12 s | INTERRUPT | ± | A change of delivery: a whisper, a sigh, a chuckle, a «...» pause, a rhetorical question. |
| list | ITEM | 4 | A punchy numbered title, then one line of reason. Don't tag every item, and vary the openers. |
| ~70% | TIP | 3, intimate | [whispers] plus "here's the trick...", then back up. Lower energy here reads as a secret and lifts retention. |
| end | CTA | 4, warm | Clear and friendly, with the keyword said unhurried. A smile in the voice; one light tag at most. |
For long-form narration (an audiobook, an explainer), halve the tag budget and drop the pattern-interrupt rule. Let the text carry it.
stability and similarity_boost; its help page says Style and Speed are not available. A test on 2026-11-03 confirmed this: speed 0.8 and 1.2 gave clips of 6.32 s and 6.40 s. Set the pace with short sentences and fewer commas, then atempo.<break> is not supported. Use «...» or «—» for pauses, «،»/«,» for a breath, and [short pause] when punctuation is not enough.[tags] aloud, so strip every tag. Steer with style (0–1), speed (0.7–1.2) and <break time="0.5s"/> (3 s at most, and only a few).previous_text/next_text so the energy and intonation join up. That context is not spoken.seed makes sampling close to repeatable, though not guaranteed. Fix it for A/B tests.Convert the directed script into whatever the engine accepts:
gpt-4o-mini-tts: no inline tags, so remove them. Put the delivery into the instructions field, for example: "energetic young narrator, fast, smiling, one short laugh after the joke".<break>, <prosody rate pitch> and <emphasis>. Use Azure's <mstts:express-as style> only on voices that list that style; check the voice's style list first.Whatever the engine, the step 2 rewrite does most of the work.
Tag behaviour and speaking rate depend on the voice. Once per voice:
tag_lint.py SCRIPT --calibrate AUDIO.mp3. It measures the voice's real characters per second from one finished take, for free. Pass that number as --cps from then on.ab.py. Record what works in the tested-voices table in references/audio-tags.md.| Path | What |
|---|---|
references/persian-delivery.md |
Persian for the ear: colloquial register, interjections, punctuation as a score, emphasis without capitals, before/after examples |
references/english-delivery.md |
The same for English |
references/audio-tags.md |
Tag catalogue by job, tested-voices table, what never to tag |
scripts/tag_lint.py |
Free checker: beat map, length estimate, over-tagging and model errors, --calibrate |
scripts/ab.py |
Variants × stability on the real voice with a fixed seed, STT leak and event detection, --dry-run, --lexicon |
examples/ |
A directed Persian and English reel script |
English · فارسی
یه اسکیل برای ایجنتهای هوش مصنوعی که متن رو قبل از تبدیل به صدا کارگردانی میکنه. نتیجهاش صدای یه آدم واقعی و پرانرژیه، نه کسی که از رو کاغذ میخونه.
اول برای فارسی ساخته شده و انگلیسی رو هم پشتیبانی میکنه. روی تگهای صوتی ElevenLabs v3/v4 تمرکز داره و برای سرویسهای دیگهی TTS هم راهنما داره.
بیشتر متنهایی که به TTS داده میشن به یکی از این دو دلیل خراب میشن:
[excited] باشه، صدا شبیه یه تبلیغ اغراقآمیز میشه و بیننده رد میکنه.۱. نقشهی ضربآهنگ ویدیو رو میکشه. نقش هر خط رو مشخص میکنه: هوک، مقدمه، آیتمهای لیست، نکتهی طلایی، شوخی، دعوت به اقدام.
۲. متن رو برای گوش بازنویسی میکنه. متن محاورهای میشه، جملهها کوتاه میشن، کلمهی اصلی میره آخر جمله، و صوتهای واقعی مثل «وای»، «ببین» و «دیگه» اضافه میشن. هیچ واقعیتی از متن عوض نمیشه.
۳. تگها رو با بودجهی سفتوسخت میذاره:
۴. یه لینتر رایگان داره که بدون مصرف اعتبار اینها رو پیدا میکنه:
۵. قبل از ساخت کل ویس، جملههای حساس رو A/B تست میکنه و با صدای خودت چند نسخه میسازه:
--dry-run هزینه رو قبل از ارسال نشون میده؛با Claude Code و هر ایجنتی که اسکیلهای SKILL.md رو بخونه کار میکنه. اسکریپتها با Python 3.9+ نوشته شدن و هیچ وابستگیای ندارن؛ ffmpeg اختیاریه.
برای Claude Code بهعنوان اسکیل شخصی:
git clone https://github.com/aligh98/tts-director ~/.claude/skills/tts-director
یا داخل .claude/skills/ یه پروژه کلونش کن. هر وقت متنی قراره به TTS بره، یا ازش بخوای صدا انسانیتر و پرهیجانتر بشه، خودش فعال میشه.
# Free: beat map, length estimate, over-tagging and model errors
python scripts/tag_lint.py examples/reel-fa.txt --model eleven_v4 --tempo 1.15
# Free: measure your voice's real speaking rate from one finished take
python scripts/tag_lint.py script.txt --calibrate voice.mp3
# Check the cost first (sends nothing)
python scripts/ab.py "[excited] وای! فقط تا جمعه وقت داری!" "وای... فقط تا جمعه وقت داری!" --stability 0.35 --stability 0.5 --out probe --dry-run
# Generate and transcribe each variant (uses ElevenLabs credits)
export ELEVENLABS_API_KEY=...
python scripts/ab.py "[excited] وای! فقط تا جمعه وقت داری!" --voice YOUR_VOICE_ID --lang fa --en-check --out probe
گزینههای ab.py:
--prev و --next: خط قبل و بعد رو بهعنوان زمینه به مدل میدن تا لحن جملهها به هم بچسبه.--lexicon words.tsv: یه فایل نوشتار<TAB>گفتار برای درست کردن تلفظ اسمها و کلمههای خارجی، مثل کلش ← کِلَشْ.--en-check: کلیپ رو بهصورت انگلیسی هم به متن تبدیل میکنه تا اگه یه تگ انگلیسی بلند خونده شده باشه، معلوم بشه.تستهای آفلاین: python -m unittest discover tests
eleven_v4 تنظیم سرعت و style رو نادیده میگیره. یه جمله رو با سرعت ۰.۸ و ۱.۲ ساختیم و طولش تقریباً یکی شد (۶.۳۲ و ۶.۴۰ ثانیه). روی v4 فقط stability اثر داره. سرعت رو بعد از ساخت با ffmpeg -af atempo=1.1 تنظیم کن؛ زیر و بمی صدا عوض نمیشه.multilingual_v2، flash و turbo تگها رو بلند میخونن. v3 و v4 هم <break> رو نمیشناسن؛ به جاش از «...» استفاده کن.[laughs] یا [chuckles] بذار.مفیدترین کمک، اضافه کردن یه ردیف به جدول صداهای تستشده توی references/audio-tags.md است: صدا، مدل و زبان؛ کدوم تگها اجرا شدن و کدوم نه؛ و سرعت حرف زدن اون صدا. راهنمای زبانهای دیگه هم با نام references/<زبان>-delivery.md خوشاومده.
MIT. این پروژه هیچ ارتباطی با ElevenLabs نداره و «ElevenLabs» علامت تجاری صاحبش است.