Audio To Subtitles
Use this skill to:
- turn local audio/video files or public media URLs into subtitle files through AI MediaKit;
- turn text into MiniMax TTS audio;
- optionally generate subtitles from the TTS audio in the same run.
Workflow
For media inputs:
- If the input is a local file, upload it to Cloudflare R2 first.
- Submit the public
audio_url or video_url to AI MediaKit ASR subtitles.
- Poll the async task until it is completed or failed.
- Save
.json, .srt, and .vtt outputs.
For local video-engine projects:
- If the media belongs to a
talking-head-remotion project under <VIDEO_WORKSPACE>, save subtitles under that project's work/captions/.
- Use
captions.srt and captions.vtt as the main cleaned files, keep raw ASR backups as captions.raw.srt and captions.raw.vtt, and keep the MediaKit payload as asr-result.json.
- Also write
captions_aligned.json parsed from the cleaned SRT so Remotion work can sync src/demoData.ts.
- Current project default for 《两个提示词让 AI 少返工》:
<VIDEO_WORKSPACE>/your-talking-head-project/work/captions
For text inputs:
- Generate audio through MiniMax TTS.
- Save the audio file.
- If
--subtitles is set, upload the audio to R2 and run the same AI MediaKit subtitle workflow.
CLI
SKILL_DIR="./skills/audio-to-subtitles"
# Local audio/video: upload to R2, then transcribe
npx -y bun "$SKILL_DIR/scripts/main.ts" audio.mp3 --language zh-CN --out-dir subtitles
# Existing public URL: skip R2 upload
npx -y bun "$SKILL_DIR/scripts/main.ts" "https://example.com/audio.mp3" --out-dir subtitles
# Batch files/URLs
npx -y bun "$SKILL_DIR/scripts/main.ts" a.mp3 b.m4a "https://example.com/video.mp4" --out-dir subtitles
# Batch from manifest
npx -y bun "$SKILL_DIR/scripts/main.ts" --manifest inputs.txt --out-dir subtitles
# Speaker diarization
npx -y bun "$SKILL_DIR/scripts/main.ts" interview.mp3 --speaker --language zh-CN
# Text to audio only
npx -y bun "$SKILL_DIR/scripts/main.ts" --text "你好,欢迎收听。" --voice-id female-shaonv --out-dir audio
# Text file to audio + subtitles
npx -y bun "$SKILL_DIR/scripts/main.ts" --text-file script.md --subtitles --language zh-CN --out-dir audio
Options
| Option |
Description |
--text <text> |
Generate MiniMax TTS audio from inline text. Can be repeated. |
--text-file <path> |
Generate MiniMax TTS audio from a text file. Can be repeated. |
--subtitles |
With text input, also generate subtitles from the generated audio. |
--manifest <path> |
Batch input manifest. Text files use one input per line; JSON supports an array of strings or objects. |
--out-dir <path> |
Output directory. Default: subtitles. |
| `--format <all |
srt |
| `--language <cmn-Hans-CN |
zh-CN |
--speaker |
Enable speaker info and prefix subtitles with speaker labels when returned. |
--voice-id <id> |
MiniMax voice ID. Default: MINIMAX_VOICE_ID, then MINIMAX_TTS_VOICE_ID, then female-shaonv. |
--tts-model <model> |
MiniMax TTS model. Default: MINIMAX_TTS_MODEL, then speech-02-hd. |
--tts-speed <n> |
TTS speed. Default: MINIMAX_TTS_SPEED, then 1.0. |
--tts-vol <n> |
TTS volume. Default: MINIMAX_TTS_VOL, then 1.0. |
--tts-pitch <n> |
TTS pitch. Default: MINIMAX_TTS_PITCH, then 0. |
--tts-emotion <emotion> |
TTS emotion. Default: MINIMAX_TTS_EMOTION, then happy. |
| `--tts-format <mp3 |
wav |
--tts-sample-rate <n> |
TTS sample rate. Default: MINIMAX_TTS_SAMPLE_RATE, then 32000. |
--tts-bitrate <n> |
TTS bitrate. Default: MINIMAX_TTS_BITRATE, then 128000. |
| `--media-kind <auto |
audio |
--r2-prefix <prefix> |
R2 object key prefix for uploaded local audio/video. Default: R2_AUDIO_KEY_PREFIX, then audio/YYYY-MM-DD. |
--concurrency <n> |
Batch concurrency. Default: 1. |
--poll-interval <seconds> |
Poll interval. Default: 5. |
--timeout <seconds> |
Per-task timeout. Default: 7200. |
--json |
Print machine-readable run summary to stdout. |
Manifest
Text manifests (.txt) are one media input per line.
JSON manifests can mix media and text jobs:
[
"local-audio.mp3",
{ "url": "https://example.com/video.mp4", "mediaKind": "video" },
{ "text": "你好,欢迎收听。", "outputName": "intro", "subtitles": true, "voiceId": "female-shaonv" },
{ "textFile": "script.md", "outputName": "script-audio", "subtitles": true }
]
Environment
The script loads environment files in this order. The nearest .env.r2 is loaded last and overrides global R2 defaults for this vault.
~/.skills/.env
~/.baoyu-skills/.env
- nearest
.env.r2 from current directory upward
- nearest
.skills/.env from current directory upward
- nearest
.baoyu-skills/.env from current directory upward
Required for MiniMax TTS text input:
| Variable |
Description |
MINIMAX_API_KEY |
MiniMax API key. |
MINIMAX_TTS_API_KEY |
Also accepted. |
MINIMAX_API_HOST |
Optional. Default: https://api.minimax.io. |
MINIMAX_VOICE_ID |
Optional default voice ID. |
MINIMAX_TTS_MODEL |
Optional default model. |
Required for MediaKit subtitle generation:
| Variable |
Description |
MEDIAKIT_API_KEY |
AI MediaKit API key. |
AI_MEDIAKIT_API_KEY |
Also accepted. |
VOLCENGINE_MEDIAKIT_API_KEY |
Also accepted. |
Required for local-file uploads:
| Variable |
Description |
R2_ACCESS_KEY_ID |
Cloudflare R2 access key. |
R2_SECRET_ACCESS_KEY |
Cloudflare R2 secret key. |
R2_ACCOUNT_ID |
Cloudflare account ID. |
R2_BUCKET |
R2 bucket name. |
R2_PUBLIC_BASE_URL |
Public base URL. R2_PUBLIC_URL is also accepted. |
R2_AUDIO_KEY_PREFIX |
Optional R2 prefix for uploaded audio/video. Default: audio/YYYY-MM-DD. |
Notes
- AI MediaKit only accepts public HTTP/HTTPS media URLs. Local files must be uploaded first.
- TTS audio only needs MiniMax API credentials.
- TTS + subtitles also needs MediaKit and R2 credentials.
- Supported API languages are currently Simplified Chinese and English.
- Single media duration should not exceed the AI MediaKit limit of 3 hours.
- Do not print API keys or commit real
.env.r2 values.
- Do not leave finished video subtitles only in
<NOTES_VAULT>; for Remotion video work, copy or write them into the matching <VIDEO_WORKSPACE>/<project>/work/captions/ directory.
1---2name: audio-to-subtitles3description: Convert local audio/video files or public media URLs into subtitle files by uploading local files to Cloudflare R2 and calling Volcengine AI MediaKit ASR subtitles API. Also supports MiniMax text-to-speech generation from text or text files, with optional subtitle generation from the produced audio. Supports batch processing, SRT/VTT/JSON output, language selection, speaker labels, configurable MiniMax voice ID and model. Use when the user asks to turn audio/video into subtitles, generate ASR subtitles, create SRT/VTT, batch transcription, or generate TTS audio with optional subtitles.4---56# Audio To Subtitles78Use this skill to:910- turn local audio/video files or public media URLs into subtitle files through AI MediaKit;11- turn text into MiniMax TTS audio;12- optionally generate subtitles from the TTS audio in the same run.1314## Workflow1516For media inputs:17181. If the input is a local file, upload it to Cloudflare R2 first.192. Submit the public `audio_url` or `video_url` to AI MediaKit ASR subtitles.203. Poll the async task until it is completed or failed.214. Save `.json`, `.srt`, and `.vtt` outputs.2223For local video-engine projects:24251. If the media belongs to a `talking-head-remotion` project under `<VIDEO_WORKSPACE>`, save subtitles under that project's `work/captions/`.262. Use `captions.srt` and `captions.vtt` as the main cleaned files, keep raw ASR backups as `captions.raw.srt` and `captions.raw.vtt`, and keep the MediaKit payload as `asr-result.json`.273. Also write `captions_aligned.json` parsed from the cleaned SRT so Remotion work can sync `src/demoData.ts`.284. Current project default for 《两个提示词让 AI 少返工》:2930```text31<VIDEO_WORKSPACE>/your-talking-head-project/work/captions32```3334For text inputs:35361. Generate audio through MiniMax TTS.372. Save the audio file.383. If `--subtitles` is set, upload the audio to R2 and run the same AI MediaKit subtitle workflow.3940## CLI4142```bash43SKILL_DIR="./skills/audio-to-subtitles"4445# Local audio/video: upload to R2, then transcribe46npx -y bun "$SKILL_DIR/scripts/main.ts" audio.mp3 --language zh-CN --out-dir subtitles4748# Existing public URL: skip R2 upload49npx -y bun "$SKILL_DIR/scripts/main.ts" "https://example.com/audio.mp3" --out-dir subtitles5051# Batch files/URLs52npx -y bun "$SKILL_DIR/scripts/main.ts" a.mp3 b.m4a "https://example.com/video.mp4" --out-dir subtitles5354# Batch from manifest55npx -y bun "$SKILL_DIR/scripts/main.ts" --manifest inputs.txt --out-dir subtitles5657# Speaker diarization58npx -y bun "$SKILL_DIR/scripts/main.ts" interview.mp3 --speaker --language zh-CN5960# Text to audio only61npx -y bun "$SKILL_DIR/scripts/main.ts" --text "你好,欢迎收听。" --voice-id female-shaonv --out-dir audio6263# Text file to audio + subtitles64npx -y bun "$SKILL_DIR/scripts/main.ts" --text-file script.md --subtitles --language zh-CN --out-dir audio65```6667## Options6869| Option | Description |70|--------|-------------|71| `--text <text>` | Generate MiniMax TTS audio from inline text. Can be repeated. |72| `--text-file <path>` | Generate MiniMax TTS audio from a text file. Can be repeated. |73| `--subtitles` | With text input, also generate subtitles from the generated audio. |74| `--manifest <path>` | Batch input manifest. Text files use one input per line; JSON supports an array of strings or objects. |75| `--out-dir <path>` | Output directory. Default: `subtitles`. |76| `--format <all|srt|vtt|json>` | Output format. Comma-separated values are allowed. Default: `all`. |77| `--language <cmn-Hans-CN|zh-CN|eng-US>` | Optional recognition language. `zh-CN` is accepted as an alias for `cmn-Hans-CN`. Omit to let API choose defaults. |78| `--speaker` | Enable speaker info and prefix subtitles with speaker labels when returned. |79| `--voice-id <id>` | MiniMax voice ID. Default: `MINIMAX_VOICE_ID`, then `MINIMAX_TTS_VOICE_ID`, then `female-shaonv`. |80| `--tts-model <model>` | MiniMax TTS model. Default: `MINIMAX_TTS_MODEL`, then `speech-02-hd`. |81| `--tts-speed <n>` | TTS speed. Default: `MINIMAX_TTS_SPEED`, then `1.0`. |82| `--tts-vol <n>` | TTS volume. Default: `MINIMAX_TTS_VOL`, then `1.0`. |83| `--tts-pitch <n>` | TTS pitch. Default: `MINIMAX_TTS_PITCH`, then `0`. |84| `--tts-emotion <emotion>` | TTS emotion. Default: `MINIMAX_TTS_EMOTION`, then `happy`. |85| `--tts-format <mp3|wav|flac|pcm>` | TTS audio format. Default: `MINIMAX_TTS_FORMAT`, then `mp3`. |86| `--tts-sample-rate <n>` | TTS sample rate. Default: `MINIMAX_TTS_SAMPLE_RATE`, then `32000`. |87| `--tts-bitrate <n>` | TTS bitrate. Default: `MINIMAX_TTS_BITRATE`, then `128000`. |88| `--media-kind <auto|audio|video>` | Force API request field. Default: `auto` from extension. |89| `--r2-prefix <prefix>` | R2 object key prefix for uploaded local audio/video. Default: `R2_AUDIO_KEY_PREFIX`, then `audio/YYYY-MM-DD`. |90| `--concurrency <n>` | Batch concurrency. Default: `1`. |91| `--poll-interval <seconds>` | Poll interval. Default: `5`. |92| `--timeout <seconds>` | Per-task timeout. Default: `7200`. |93| `--json` | Print machine-readable run summary to stdout. |9495## Manifest9697Text manifests (`.txt`) are one media input per line.9899JSON manifests can mix media and text jobs:100101```json102[103 "local-audio.mp3",104 { "url": "https://example.com/video.mp4", "mediaKind": "video" },105 { "text": "你好,欢迎收听。", "outputName": "intro", "subtitles": true, "voiceId": "female-shaonv" },106 { "textFile": "script.md", "outputName": "script-audio", "subtitles": true }107]108```109110## Environment111112The script loads environment files in this order. The nearest `.env.r2` is loaded last and overrides global R2 defaults for this vault.1131141. `~/.skills/.env`1152. `~/.baoyu-skills/.env`1163. nearest `.env.r2` from current directory upward1174. nearest `.skills/.env` from current directory upward1185. nearest `.baoyu-skills/.env` from current directory upward119120Required for MiniMax TTS text input:121122| Variable | Description |123|----------|-------------|124| `MINIMAX_API_KEY` | MiniMax API key. |125| `MINIMAX_TTS_API_KEY` | Also accepted. |126| `MINIMAX_API_HOST` | Optional. Default: `https://api.minimax.io`. |127| `MINIMAX_VOICE_ID` | Optional default voice ID. |128| `MINIMAX_TTS_MODEL` | Optional default model. |129130Required for MediaKit subtitle generation:131132| Variable | Description |133|----------|-------------|134| `MEDIAKIT_API_KEY` | AI MediaKit API key. |135| `AI_MEDIAKIT_API_KEY` | Also accepted. |136| `VOLCENGINE_MEDIAKIT_API_KEY` | Also accepted. |137138Required for local-file uploads:139140| Variable | Description |141|----------|-------------|142| `R2_ACCESS_KEY_ID` | Cloudflare R2 access key. |143| `R2_SECRET_ACCESS_KEY` | Cloudflare R2 secret key. |144| `R2_ACCOUNT_ID` | Cloudflare account ID. |145| `R2_BUCKET` | R2 bucket name. |146| `R2_PUBLIC_BASE_URL` | Public base URL. `R2_PUBLIC_URL` is also accepted. |147| `R2_AUDIO_KEY_PREFIX` | Optional R2 prefix for uploaded audio/video. Default: `audio/YYYY-MM-DD`. |148149## Notes150151- AI MediaKit only accepts public HTTP/HTTPS media URLs. Local files must be uploaded first.152- TTS audio only needs MiniMax API credentials.153- TTS + subtitles also needs MediaKit and R2 credentials.154- Supported API languages are currently Simplified Chinese and English.155- Single media duration should not exceed the AI MediaKit limit of 3 hours.156- Do not print API keys or commit real `.env.r2` values.157- Do not leave finished video subtitles only in `<NOTES_VAULT>`; for Remotion video work, copy or write them into the matching `<VIDEO_WORKSPACE>/<project>/work/captions/` directory.