Communitygithub.com

ZJU-REAL/Easel

Automatic Speech-to-Text / Captioning: Recognize speech from audio or video files and generate subtitle files (SRT/ASS/TXT/JSON), with optional hardcoding into video. Use when the user mentions automatic captions, speech-to-text, adding subtitles to video, transcription, dictation, subtitle files, generating subtitles, or burning subtitles.

What is Easel?

Easel is an AI agent skill designed to automate speech-to-text transcription and subtitle generation for developers and content creators. It converts speech from audio or video files into common subtitle formats (SRT, ASS, TXT, or JSON) using a wrapped version of faster-whisper, with Chinese-friendly sentence segmentation for accurate breaks. The skill also supports optionally burning subtitles directly into videos using FFmpeg's subtitle filters, creating hardcoded subtitles ideal for distribution. It supports multiple platforms like Claude Code, Cursor, and Codex, and operates via shared Python scripts (`asr.py` and `video_ops.py`). Key features include automatic language detection, adjustable model size for speed/accuracy trade-offs, and ASS subtitle style auto-adaptation to video dimensions (portrait/landscape). This skill is particularly useful for streamlining video captioning workflows, improving accessibility, and avoiding complex manual subtitle toolchains.

Works with~Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/ZJU-REAL/Easel/tree/HEAD/skills/openclaw/auto-subtitle

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

Automatic Subtitles (Speech-to-Text)

Recognizes human speech in audio/video and generates subtitles. Based on the shared script skills/shared/scripts/asr.py (faster-whisper wrapper), with deterministic parameters and reproducible results, featuring Chinese-friendly sentence segmentation. Optionally burn subtitles into video (reuses skills/shared/scripts/video_ops.py / FFmpeg subtitles filter).

This skill handles only "speech → subtitle files (+ optional burning)". For general video editing, see video-editing; for pure noise reduction, see audio-denoise; for smart clipping of long videos with burned subtitles, see clipify.

Input

FieldRequiredDescription
input_fileYesPath to audio or video file (video will auto-extract audio track)
formatNosrt (default) / ass / txt / json
languageNoauto (default) or zh/en etc. ISO 639-1 code
modelNotiny/base (default)/small/medium/large-v3; larger = more accurate but slower
burnNoWhether to burn subtitles into the video (requires video input)

Supports: audio formats mp3/wav/m4a/aac/flac; video formats mp4/mkv/mov/webm.

Output

  • Subtitle files placed in outputs/topic-name/ (SRT/ASS/TXT/JSON)
  • If burning subtitles: video with hardcoded subtitles (*-sub.mp4)
  • Report: detected language, number of subtitle segments, model used, output paths

Prerequisites

  • On first run, models are downloaded from HuggingFace; requires an external network proxy. The script reads EASEL_PROXY or http(s)_proxy environment variables as the proxy; if neither is set, it connects directly. You can also pre-set with export https_proxy=... http_proxy=....
  • For CPU environments, use the defaults --device cpu --compute-type int8.

Execution Steps

Script paths (relative to project root): skills/shared/scripts/asr.py, skills/shared/scripts/video_ops.py.

1. Generate subtitle file

# Video → SRT (auto-extract audio track + auto-detect language)
python skills/shared/scripts/asr.py transcribe \
  -i input.mp4 -o outputs/topic-name/input.srt --language zh

# Video → ASS (with styling, **font size and margins auto-adapt to video portrait/landscape**): video input auto-detects dimensions
python skills/shared/scripts/asr.py transcribe \
  -i input.mp4 -o outputs/topic-name/input.ass --format ass --model small
# Audio only → ASS: cannot detect dimensions, defaults to portrait 1080x1920; for landscape add --res 1920x1080
python skills/shared/scripts/asr.py transcribe \
  -i voice.mp3 -o outputs/topic-name/voice.ass --format ass --res 1920x1080
  • ASS styles auto-adapt to target video dimensions: font size based on the short side (min(w,h)*0.05, suitable for both portrait and landscape, no longer oversized on landscape), bottom margin based on height, left/right margins based on width, PlayRes = actual width/height. Video input auto-detects; for audio only, specify with --res widthxheight. For hardcoded subtitles with styling, prefer burning this ASS file (next section) — more reliable and auto-adaptive than bare SRT with manual force_style.
  • Chinese defaults to ~18 characters per line; long lines auto-break/split; adjust with --max-line-chars.
  • If -o is omitted, a project directory is created from the input filename, e.g., talk.mp4 outputs to outputs/talk/talk.srt; for existing projects, explicitly use -o outputs/topic-name/<filename>.<format>.
  • View available models/languages: python skills/shared/scripts/asr.py info.

2. (Optional) Burn subtitles into video

When the user wants "hardcoded subtitles / burn into video", use FFmpeg's subtitles (for SRT) or ass (for ASS) filter:

# Burn SRT (customizable style)
ffmpeg -y -i input.mp4 \
  -vf "subtitles=outputs/topic-name/input.srt:force_style='FontName=Noto Sans CJK SC,FontSize=20,PrimaryColour=&H00FFFFFF,OutlineColour=&H80000000,BorderStyle=1,Outline=2'" \
  -c:a copy outputs/topic-name/input-sub.mp4

# Burn ASS (styles already in ASS file, faithful reproduction)
ffmpeg -y -i input.mp4 \
  -vf "ass=outputs/topic-name/input.ass" \
  -c:a copy outputs/topic-name/input-sub.mp4
  • If paths contain special characters, wrap the subtitles= value in single quotes and escape colons.
  • For soft subtitles (toggleable) instead of burning: ffmpeg -i in.mp4 -i sub.srt -c copy -c:s mov_text out.mp4.

3. Output and Report

  • Subtitle files and burned video are written to outputs/topic-name/.
  • Report to user: detected language, number of subtitle segments, model, file paths; suggest rerunning with --model/--max-line-chars if needed.

Rules

  1. Video: extract audio track first — the script automatically uses FFmpeg to extract a 16kHz mono WAV, leaving the original video unchanged.
  2. Chinese-friendly sentence segmentation — break lines by punctuation/length, avoid overly long lines.
  3. Never delete original files — only produce new files in outputs/.
  4. Model selection — use base for speed, small/medium for accuracy; CPU use int8.
  5. Burning requires video input — audio-only input produces subtitle files only.
  6. No profile dependency — transcription does not require user profiling.

References

  • SYSTRAN/faster-whisper — CTranslate2-accelerated Whisper inference
  • openai/whisper — Original Whisper model and ASR method
  • FFmpeg subtitles / ass filter documentation (subtitle burning)

Individual skills in this repo

This repo contains 9 individual skills — each has its own dedicated page.

ZJU-REAL/Easel

AI 视频生成:文生视频 / 图生视频 / 数字人首帧驱动。通过可插拔 provider(通义万相 Wan / 火山 Seedance / 快手可灵 / OpenAI 兼容)异步生成视频,用户自备 API key。当用户说 AI 视频生成、文生视频、图生视频、AI 生成视频、AI 短视频、让图片动起来、数字人视频、生成一段视频 时使用。与 video-strategy(选型/策略)、video-editing(剪辑处理)、clipify(切片)区别:本 SKILL 是从 0 用 AI 生成新视频。

ZJU-REAL/Easel

通用音频处理:音频剪辑/裁剪、格式转码(mp3/wav/m4a/aac)、音量归一化、从视频提取音轨、多段拼接、淡入淡出、变速(保音高)。当用户说“剪音频”“裁一段”“转成 mp3”“调音量/响度”“提取音轨/扒音频”“拼接音频”“淡入淡出”“加速/减速音频”“变速不变调”时使用。与 audio-denoise 的区别:audio-denoise 专做降噪,audio-editing 做除降噪外的通用音频操作(也内置 denoise 作为兜底)。

ZJU-REAL/Easel

一句话主题 → 成品短视频:自动串联 文案→配图/AI视频→配音→字幕→BGM→合成,把 Easel 制作层零件编排成一条'一键出片'流水线。**单条视频、口播/资讯向,画面默认逐句配图 + Ken Burns 缓动,需要动态时才逐段图生视频**。当用户说 一键生成视频、自动做短视频、主题生成视频、帮我做条视频、口播视频一条龙、自动出片、短视频一键生成 时使用。**有剧情/角色/对白/反转/多集的短剧改用 short-drama(每镜强制图生视频、不用静态图冒充);只写脚本用 video-script;只生成单个片段用 ai-video-gen。**

ZJU-REAL/Easel

音乐卡点视频 / 踩点视频:检测背景音乐的节拍,让图片或片段在节拍点上切换,配推进/白闪特效,做出燃系'卡点'短视频。当用户说 卡点视频、踩点视频、音乐卡点、节奏卡点、按音乐切换、鼓点视频、踩节奏、beat 卡点、图片卡点、卡点混剪 时使用。基于 shared/scripts/beatsync.py(librosa 节拍检测)。与 slideshow-video 区别:slideshow 每图固定时长、柔和转场,本 SKILL 切换点由音乐节拍决定、硬切踩点带特效。

ZJU-REAL/Easel

Easel clipify: long English talk → punchline cuts → optional 16:9→9:16 face-pan/split → opus word-by-word ASS burn. Ships scripts + assets/preview.png. Part of 1.6k★ Easel suite.

ZJU-REAL/Easel

>- 通用图像处理加工:改尺寸/缩放、裁剪、补边适配平台尺寸、格式转换(png/jpg/webp)、 压缩到目标大小、加文字或图片水印、圆角、多图拼接、生成缩略图、读图片信息。 基于 image_ops.py 确定性处理。 使用时机:用户说"改尺寸"、"缩放图片"、"裁剪"、"压缩图片"、"加水印"、"转格式"、 "圆角"、"拼图/多图联排"、"缩略图"、"适配小红书/朋友圈尺寸"、"把图 pad 成 1:1"。 和 card-*(卡片类)的区别:card-* 是"HTML 设计→渲染出图", image-editing 只加工已有图片,不负责视觉设计。

ZJU-REAL/Easel

多角色对话配音:按 cast 和逐行对白为不同角色分配音色与情绪,合成多声线音轨和带角色名字幕。 当用户说“多角色/双人/剧本/对话配音、多人对白、不同角色不同声音、有声剧配音”时使用。 单一公共音色用 tts-voiceover;克隆本人音色用 voice-clone;整部短剧制作由 short-drama 编排。

ZJU-REAL/Easel

Easel video-highlights: CN/livestream highlight extract + stable static vertical reframe (sibling to clipify).

ZJU-REAL/Easel

>- 视频制作策略与工具选型:AI 视频生成模型对比、视频脚本结构设计、制作流程规划,覆盖产品演示/解说/社媒短视频场景。 当用户说"视频怎么做""视频选型""用什么工具做视频""视频制作流程""视频策略""视频系列规划"时使用。 和 video-script 的区别:video-strategy 做内容规划与工具选型,video-script 写具体某条视频的脚本。

Related Skills