ASCII 视频生产流水线
何时使用
当用户请求以下内容时使用:ASCII 视频、文本艺术视频、终端风格视频、字符艺术动画、复古文本可视化、ASCII 音频可视化器、将视频转换为 ASCII 艺术、矩阵风格效果,或任何动画 ASCII 输出。
内部内容
ASCII 艺术视频的生产流水线——支持任何格式。将视频/音频/图像/生成式输入转换为彩色 ASCII 字符视频输出(MP4、GIF、图像序列)。涵盖:视频转 ASCII 转换、音频响应音乐可视化器、生成式 ASCII 艺术动画、混合视频+音频响应、文本/歌词叠加、实时终端渲染。
创意标准
这是视觉艺术。ASCII 字符是媒介;电影是标准。
在编写一行代码之前,阐明创意概念。氛围是什么?它讲述了什么视觉故事?是什么让这个项目区别于其他所有 ASCII 视频?用户的提示是起点——用创意雄心去诠释,而不是逐字转录。
首次渲染的卓越性不容妥协。 输出必须视觉上引人注目,无需修改轮次。如果某些内容看起来普通、平淡,或像“AI 生成的 ASCII 艺术”,那就是错误的——在交付之前重新思考创意概念。
超越参考词汇表。 参考资料中的效果目录、着色器预设和调色板库是起点词汇。对于每个项目,组合、修改并发明新模式。目录是一套颜料——你创作画作。
主动发挥创意。 当项目需要时扩展技能的词汇表。如果参考资料没有所需的内容,就构建它。至少包含一个用户没有要求但会欣赏的视觉时刻——一个过渡、一个效果、一个提升整体作品的颜色选择。
凝聚的美学胜过技术正确性。 视频中的所有场景必须通过统一的视觉语言相互连接——共享的色温、相关的字符调色板、一致的运动词汇。一个技术上正确但每个场景使用随机不同效果的视频是美学上的失败。
密集、分层、深思熟虑。 每一帧都应值得观看。绝不要纯黑色背景。始终采用多网格构图。始终进行每场景变化。始终有意使用颜色。
模式
| 模式 | 输入 | 输出 | 参考 |
|---|---|---|---|
| 视频转 ASCII | 视频文件 | 源素材的 ASCII 再现 | references/inputs.md § 视频采样 |
| 音频响应 | 音频文件 | 由音频特征驱动的生成式视觉 | references/inputs.md § 音频分析 |
| 生成式 | 无(或种子参数) | 程序化 ASCII 动画 | references/effects.md |
| 混合 | 视频 + 音频 | 带有音频响应叠加的 ASCII 视频 | 两个输入参考 |
| 歌词/文本 | 音频 + 文本/SRT | 带有视觉效果的定时文本 | references/inputs.md § 文本/歌词 |
| TTS 旁白 | 文本引用 + TTS API | 带有打字文本的叙述性推荐/引用视频 | references/inputs.md § TTS 集成 |
技术栈
每个项目一个独立的 Python 脚本。无需 GPU。
| 层 | 工具 | 用途 |
|---|---|---|
| 核心 | Python 3.10+, NumPy | 数学计算、数组操作、向量化效果 |
| 信号 | SciPy | FFT、峰值检测(音频模式) |
| 图像 | Pillow (PIL) | 字体光栅化、帧解码、图像 I/O |
| 视频 I/O | ffmpeg (CLI) | 解码输入、编码输出、混流音频 |
| 并行 | concurrent.futures | 用于批处理/片段渲染的 N 个工作进程 |
| TTS | ElevenLabs API(可选) | 生成旁白片段 |
| 可选 | OpenCV | 视频帧采样、边缘检测 |
流水线架构
每种模式都遵循相同的 6 阶段流水线:
输入 → 分析 → 场景函数 → 色调映射 → 着色 → 编码
- 输入 — 加载/解码源素材(视频帧、音频样本、图像或无)
- 分析 — 提取每帧特征(音频频段、视频亮度/边缘、运动向量)
- 场景函数 — 场景函数渲染到像素画布 (
uint8 H,W,3)。通过_render_vf()和像素混合模式组合多个字符网格。参见references/composition.md - 色调映射 — 基于百分位数的自适应亮度归一化。参见
references/composition.md§ 自适应色调映射 - 着色 — 通过
ShaderChain+FeedbackBuffer进行后处理。参见references/shaders.md - 编码 — 将原始 RGB 帧通过管道传输给 ffmpeg 进行 H.264/GIF 编码
创意指导
美学维度
| 维度 | 选项 | 参考 |
|---|---|---|
| 字符调色板 | 密度渐变、方块元素、符号、脚本(片假名、希腊、符文、盲文)、项目特定 | architecture.md § 调色板 |
| 颜色策略 | HSV、OKLAB/OKLCH、离散 RGB 调色板、自动生成和谐色、单色、色温 | architecture.md § 颜色系统 |
| 背景纹理 | 正弦场、fBM 噪声、域扭曲、Voronoi、反应扩散、细胞自动机、视频 | effects.md |
| 主要效果 | 环、螺旋、隧道、漩涡、波、干涉、极光、火焰、SDF、奇异吸引子 | effects.md |
| 粒子 | 火花、雪、雨、泡泡、符文、轨道、群体行为、流场跟随者、轨迹 | effects.md § 粒子 |
| 着色器情绪 | 复古 CRT、干净现代、故障艺术、电影感、梦幻、工业、迷幻 | shaders.md |
| 网格密度 | xs(8px) 到 xxl(40px)、每层混合 | architecture.md § 网格系统 |
| 坐标空间 | 笛卡尔、极坐标、平铺、旋转、鱼眼、Möbius、域扭曲 | effects.md § 变换 |
| 反馈 | 缩放隧道、彩虹轨迹、幽灵回声、旋转曼陀罗、颜色演化 | composition.md § 反馈 |
| 遮罩 | 圆形、环形、渐变、文本模版、动画虹膜/擦除/溶解 | composition.md § 遮罩 |
| 过渡 | 交叉淡入淡出、擦除、溶解、故障切、虹膜、基于遮罩的揭示 | shaders.md § 过渡 |
每段变化
绝不要在整个视频中使用相同的配置。对于每个部分/场景:
- 不同的背景效果(或组合 2-3 个)
- 不同的字符调色板(匹配氛围)
- 不同的颜色策略(或至少不同的色调)
- 变化着色器强度(在峰值时更多泛光,在安静时更多颗粒)
- 不同的粒子类型(如果粒子处于活动状态)
项目特定发明
对于每个项目,至少发明以下之一:
- 匹配主题的自定义字符调色板
- 自定义背景效果(组合/修改现有构建块)
- 自定义颜色调色板(匹配品牌/氛围的离散 RGB 集)
- 自定义粒子字符集
- 新颖的场景过渡或视觉时刻
不要只从目录中挑选。目录是词汇——你写诗。
工作流程
步骤 1:创意构想
在任何代码之前,阐明创意概念:
- 氛围/气氛:观众应感受到什么?充满活力、冥想、混乱、优雅、不祥?
- 视觉故事:随着时间的推移会发生什么?建立张力?转变?溶解?
- 色彩世界:暖色/冷色?单色?霓虹色?大地色?主色调是什么?
- 字符纹理:密集数据?稀疏星星?有机点?几何块?
- 什么让这个不同:是什么让这个项目独特?
- 情感弧线:场景如何推进?以能量开场,推向高潮,解决?
将用户的提示映射到美学选择。"放松 lo-fi 可视化器" 与 "故障赛博朋克数据流" 所需的一切都不同。
步骤 2:技术设计
- 模式 — 上述 6 种模式之一
- 分辨率 — 横向 1920x1080(默认)、纵向 1080x1920、方形 1080x1080 @ 24fps
- 硬件检测 — 自动检测核心数/内存,设置质量配置。参见
references/optimization.md - 章节 — 将时间戳映射到场景函数,每个函数有自己的效果/调色板/颜色/着色器配置
- 输出格式 — MP4(默认)、GIF(640x360 @ 15fps)、PNG 序列
步骤 3:构建脚本
单个 Python 文件。组件(附参考):
- 硬件检测 + 质量配置 —
references/optimization.md - 输入加载器 — 依赖模式;
references/inputs.md - 特征分析器 — 音频 FFT、视频亮度或合成
- 网格 + 渲染器 — 带位图缓存的多密度网格;
references/architecture.md - 字符调色板 — 每个项目多个;
references/architecture.md§ 调色板 - 颜色系统 — HSV + 离散 RGB + 和谐生成;
references/architecture.md§ 颜色 - 场景函数 — 每个返回
canvas (uint8 H,W,3);references/scenes.md - 色调映射 — 自适应亮度归一化;
references/composition.md - 着色器流水线 —
ShaderChain+FeedbackBuffer;references/shaders.md - 场景表 + 调度器 — 时间 → 场景函数 + 配置;
references/scenes.md - 并行编码器 — 使用 ffmpeg 管道的 N 工作进程片段渲染
- 主函数 — 编排完整流水线
步骤 4:质量验证
- 先测试帧:在完整渲染之前,在关键时间戳渲染单帧
- 亮度检查:所有 ASCII 内容的
canvas.mean() > 8。如果暗,降低 gamma - 视觉连贯性:所有场景是否感觉属于同一视频?
- 创意构想检查:输出是否匹配步骤 1 中的概念?如果看起来普通,返回重做
关键实现注意事项
亮度 — 使用 tonemap(),而非线性乘法器
这是视觉上的头号问题。黑色上的 ASCII 本质上是暗的。绝不要使用 canvas * N 乘法器——它们会裁剪高光。使用自适应色调映射:
def tonemap(canvas, gamma=0.75):
f = canvas.astype(np.float32)
lo, hi = np.percentile(f[::4, ::4], [1, 99.5])
if hi - lo < 10: hi = lo + 10
f = np.clip((f - lo) / (hi - lo), 0, 1) ** gamma
return (f * 255).astype(np.uint8)
流水线:scene_fn() → tonemap() → FeedbackBuffer → ShaderChain → ffmpeg
每场景 gamma:默认 0.75,曝光过度 0.55,海报化 0.50,亮场景 0.85。对暗层使用 screen 混合(而非 overlay)。
字体单元格高度
macOS Pillow:textbbox() 返回错误高度。使用 font.getmetrics():cell_height = ascent + descent。参见 references/troubleshooting.md。
ffmpeg 管道死锁
长时间运行的 ffmpeg 绝不要使用 stderr=subprocess.PIPE——缓冲区在 64KB 时填满并死锁。重定向到文件。参见 references/troubleshooting.md。
字体兼容性
并非所有 Unicode 字符在所有字体中都能渲染。在初始化时验证调色板——渲染每个字符,检查是否有空白输出。参见 references/troubleshooting.md。
每片段架构
对于分段视频(引用、场景、章节),将每个渲染为单独的片段文件,以便并行渲染和选择性重新渲染。参见 references/scenes.md。
性能目标
| 组件 | 预算 |
|---|---|
| 特征提取 | 1-5ms |
| 效果函数 | 2-15ms |
| 字符渲染 | 80-150ms(瓶颈) |
| 着色器流水线 | 5-25ms |
| 总计 | ~100-200ms/帧 |
参考资料
| 文件 | 内容 |
|---|---|
references/architecture.md | 网格系统、分辨率预设、字体选择、字符调色板(20+)、颜色系统(HSV + OKLAB + 离散 RGB + 和谐生成)、_render_vf() 辅助函数、GridLayer 类 |
references/composition.md | 像素混合模式(20 种)、blend_canvas()、多网格合成、自适应 tonemap()、FeedbackBuffer、PixelBlendStack、遮罩/模版系统 |
references/effects.md | 效果构建块:值场生成器、色相场、噪声/fBM/域扭曲、Voronoi、反应扩散、细胞自动机、SDF、奇异吸引子、粒子系统、坐标变换、时间连贯性 |
references/shaders.md | ShaderChain、_apply_shader_step() 分发、38 种着色器目录、音频响应缩放、过渡、色调预设、输出格式编码、终端渲染 |
references/scenes.md | 场景协议、Renderer 类、SCENES 表、render_clip()、节拍同步剪辑、并行渲染、设计模式(层层次、方向弧、视觉隐喻、构图技巧)、各复杂度级别的完整场景示例、场景设计检查列表 |
references/inputs.md | 音频分析(FFT、频段、节拍)、视频采样、图像转换、文本/歌词、TTS 集成(ElevenLabs、语音分配、音频混音) |
references/optimization.md | 硬件检测、质量配置、向量化模式、并行渲染、内存管理、性能预算 |
references/troubleshooting.md | NumPy 广播陷阱、混合模式陷阱、多进程/序列化、亮度诊断、ffmpeg 问题、字体问题、常见错误 |
创意发散(仅当用户请求实验性/创意性/独特输出时使用)
如果用户请求创意、实验性、令人惊讶或非传统的输出,选择最适合的策略,并在生成代码之前推理其步骤。
- 强制连接 — 当用户想要跨领域灵感时("让它看起来有机","工业美学")
- 概念混合 — 当用户命名两个要组合的事物时("海洋遇见音乐","太空 + 书法")
- 迂回策略 — 当用户最大程度开放时("给我惊喜","我从未见过的东西")
强制连接
- 选择一个与视觉目标不相关的领域(天气系统、微生物学、建筑、流体动力学、纺织编织)
- 列出其核心视觉/结构元素(侵蚀 → 逐渐揭示;有丝分裂 → 分裂复制;编织 → 互锁模式)
- 将这些元素映射到 ASCII 字符和动画模式
- 综合——"侵蚀"或"结晶"在字符网格中看起来像什么?
概念混合
- 命名两个不同的视觉