准备素材
本环节在装有 ffmpeg 的 Mac 或 Linux 电脑上运行,而非 iPad。它将一个视频转换为一组片段,外加一份描述它们的 manifest.json。
击球帧目前需手工标记。自动检测流程已有规范但尚未实现 —— 见当前限制。
1. 找到击球帧
Section titled “1. 找到击球帧”播放视频,并将帧号叠加在画面上:
ffplay -vf "drawtext=text='%{n}':fontsize=48:fontcolor=yellow:x=20:y=20" VIDEO.MOV逐帧步进,记录每次球拍击球的帧号。
若已知时间戳,可转换为帧号:
python -m zhanyan_pipeline.handmake VIDEO.MOV --probe 34.52. 编写击球清单
Section titled “2. 编写击球清单”CSV 文件,每行一个击球 —— contact_frame,zone[,shot_type]:
# 羽毛球单打,2026-08-10 俱乐部训练4127,BL,clear5200,FR6890,FC,drop8144,BR,smash规则:
- 区域代码必须与项目匹配。羽毛球单打:
FL FC FR BL BC BR - 球种为可选项,不参与分析 —— 仅供您后续自行筛选
- 帧号必须为正、位于视频范围内,且不得重复
- 以
#开头的行会被忽略
3. 切分片段
Section titled “3. 切分片段”python -m zhanyan_pipeline.handmake VIDEO.MOV shots.csv \ --sport badminton_singles \ --out ./out/2026-08-10-club-a/ \ --viewpoint receiver输出文件夹包含:
out/2026-08-10-club-a/├── manifest.json└── clips/ ├── s_0001.mp4 ├── s_0002.mp4 └── ...脚本所保证的不变量
Section titled “脚本所保证的不变量”每个片段都精确终止于其击球帧。 这是整套系统赖以成立的不变量。遮蔽通过提前停止播放实现,绝不通过裁剪文件 —— 若改用裁剪,每一个阈值都会被裁剪误差整体偏移。
片段采用重新编码而非流复制。流复制只能在关键帧处切割,这会使片段末端偏移最多一个完整 GOP —— 而片段末端正是击球帧,是唯一必须精确的位置。
脚本还会拒绝任何应用在导入时会拒绝的内容:无效区域代码、重复帧号、超出视频范围的帧号。
4. 传输到 iPad
Section titled “4. 传输到 iPad”通过隔空投送、iCloud 云盘或数据线,将整个输出文件夹复制到 iPad 的「文件」App。