▶EMU / VIDEO LAB
Behind the frames / 项目工作原理

一部视频,
如何被画出来?

这个项目用 Python 为 NES 模拟器教程逐帧绘制画面。旁白决定节奏,Pillow 负责像素,FFmpeg 把一张张画面变成最终视频。

23教学场景
98旁白段落
30 FPS1920 × 1080
build.py / RENDER PIPELINE● READY
INPUT → PROCESS → OUTPUT
EMU 101 // SCENE 19
把一切连起来
CPU 执行一步,PPU 走 3 倍周期
const cycles = cpu.step()
RGB FRAME → H.264STATUS RENDERED
01 / Pipeline

从脚本到 MP4 的五步

点击任一步查看具体做法。整个过程由代码生成画面,再把画面与语音合成。

STEP 01 · INPUT

每个场景都有自己的绘图函数

场景文件定义画什么、讲什么,以及每句话对应的动画节点。scenes.py 将 23 个场景按播放顺序组合起来。

对应代码 / 产物scenes_a.py … scenes_j.py
scenes.py → SCENES
02 / Frame by frame

拖动时间,看看一帧如何变化

同一绘图函数接收不同时间,就会画出不同画面。左侧是根据项目机制制作的简化示意。

动手构建 / 主循环STEP 09/10
把一切连起来CPU · PPU · APU
CPU 执行一步,PPU 走 3 倍周期
SCENE 19 / DEMOFRAME 000 / 1801920 × 1080 · 30 FPS
场景时间轴0.00s / 6.00s
0s / 开始1.5s / 标题3s / 代码6s / 结束

演示时间轴经过简化;实际场景时长由配音文件决定。

01
定位当前时刻

第 k 帧的时间是 t = k / 30 秒。

02
计算动画进度

旁白开始时间是标记点;缓动函数将经过的时间转成 0 到 1 的显示进度。

03
绘制完整画面

Pillow 画图形、文字、代码和像素示意,再叠加字幕与进度条。

04
送入视频编码器

这一帧的 RGB 数据直接写入 FFmpeg;下一帧重复同样的过程。

03 / Deliverables

最终得到什么?

FFmpeg 编码所有场景并合入配音。中间结果和语音缓存保存在 out/,方便重复构建。

MP4out/nes_emulator.mp4

H.264 画面与 AAC 配音合成的完整视频。

SRTout/nes_emulator.srt

按旁白开始和结束时间生成的独立字幕。

PNGout/stills/

预览模式输出的场景静帧,用于检查画面。

在 macOS 项目目录中运行python3 build.py
查看依赖和静帧命令 →