把一道乘法题做成十五秒视频

从99乘36的解法开始,把公式变成分镜,再用程序画帧、编码成片。

程序化视频数学Python

把 99 × 36 算出来不难。要把它讲成一条短视频,还得让读者看见:为什么先算 100 × 36,以及多算的那一份去了哪里。

这次我用 Python 绘制画面,再用 Swift 编码成视频。先看结果,然后沿着解法、分镜和画帧过程拆开。

15 秒,1080 × 1920,24 FPS。当前成片只有画面和字幕,没有配音或背景音乐。

先把解法变成一个看得见的动作

这道题适合凑整:99 距离 100 只差 1。先算一百份,再减掉多算的一份。

99 × 36
= (100 - 1) × 36
= 100 × 36 - 1 × 36
= 3600 - 36
= 3564

公式表达的是分配律。画面可以把它表现为一块面积:大矩形表示 100 × 36,右边的一条表示多算的 1 × 36,剩下的部分对应 99 × 36。

宽为100、高为36的矩形,右侧宽为1的窄条代表多算的36;去掉窄条后,剩余面积为99乘36等于3564。
运算对应到面积:整块是 3600,右侧窄条是 36,剩下 3564。

视频里为了让红条和文字看得清,红条被刻意加宽。它表达拆分关系,不是按 1∶100 绘制的几何比例。

每段画面只推进一个意思

如果一开始就把五行公式全部放出来,答案虽然完整,观看过程却没有重点。我把讲解拆成了几个动作:提出问题、找到 100、画出整块、指出多算的一份,再落到答案。

实际脚本中的时间安排如下。相邻画面留有短暂交叠,公式也逐行出现,让过渡保持连续。

时间 画面 推进的意思
0–1.8 秒 99 × 36 = ? 先明确要解的题
1.4–4.2 秒 99 = 100 - 1 找到凑整的入口
3.8–7.4 秒 矩形与红条 看见整块和多算的一份
6.8–11 秒 公式逐行出现 把画面对应回计算
10.6–13.4 秒 答案 3564 给出结果
13.2–15 秒 方法提示 留下可以迁移的思路
成片中的三个关键帧,点击可查看原图。每个画面承担不同的解释任务。

用时间决定每一帧画什么

画帧程序的核心很直接:第 i 帧对应时间 i / FPS。知道时间,就能判断当前应该出现哪个公式、矩形画到哪里、字幕写什么。

FPS = 24
DURATION = 15
TOTAL_FRAMES = FPS * DURATION

# 第 144 帧,对应视频第 6 秒
t = 144 / FPS

这份脚本按同一套路生成 360 张 PNG。题目、公式和分镜时间目前写在代码里;解法是事先选定的,并没有自动识别题型或自动挑选策略。

为了让元素进入画面时慢慢停下来,脚本使用了一个简单的缓动函数:

def ease(x):
    x = max(0, min(1, x))
    return 1 - (1 - x) ** 3

把一段时间映射到 0 到 1,再交给这个函数,就能逐渐改变位置或宽度。例如面积矩形从左向右展开;公式出现时,也从稍低的位置移动到最终位置。

同一个时间会得到同一套画面安排。这让排查比较方便:想看第六秒发生了什么,直接检查第 144 帧即可。

把画面接成视频

PNG 序列交给 Swift 的 AVFoundation 编码。每一帧写入时,附上 index / fps 对应的时间戳;最终输出 H.264 MP4。

制作过程:选定解法并安排分镜,Python与Pillow按照时间渲染360张PNG,Swift与AVFoundation按24FPS编码,得到15秒H.264视频。
讲解、画面和编码分开处理。先把一个题目跑通,再考虑通用输入。

这次成片的参数与目标一致:15 秒、1080 × 1920、24 FPS,并且只有视频轨道。参数之外,还需要看画面本身:公式是否正确、字幕是否越界,以及读者能否跟上每一步。

从单题脚本走向更多题目

现在最值得继续做的,是把题目、公式步骤和分镜时间从代码里拿出来。比如 98 × 36 仍然可以先凑到 100,但应减去两份 36;直接替换标题并不能得到正确讲解。

一个可复用的模板,需要一起管理解法、图形关系和字幕。等这些部分稳定之后,再加入旁白、更多题型和自动检查,才有机会形成批量生成流程。

这条视频验证了从解释到成片的路径。接下来要解决的,是怎样让同一种讲法覆盖更多题目,同时保持每一帧都在帮助理解。

继续阅读 · 给博客人物加动作:一次转头效果的试错