一、软件定位
传统培训视频是单向播放的:学员看完了,却无法在关键决策点上做出选择,也无法验证自己是否真正掌握了操作要领。MVStudy 是一套面向情景化视频教学与模拟考核的桌面级解决方案,由交互脚本编辑器(MVStudy)与交互播放器(MVPlaer)组成,可以在视频的任意时间点埋设"决策点",让学员通过点击画面上的按钮、热点来驱动剧情走向------跳转、回退、结束模拟,全程与视频内容深度耦合。
典型应用场景包括:设备操作规范培训、应急处置流程演练、安全生产情景考核、医疗护理操作模拟、服务流程话术训练等一切"需要在正确时机做出正确选择"的教学场景。
二、系统架构
解决方案由三个工程组成,职责清晰、层层复用:
|--------------------|---------|---------------------------------------------|
| 模块 | 角色 | 说明 |
| MVStudy | 交互脚本编辑器 | 加载视频、标注交互点、绘制画面元素、提取关键帧、实时预览、保存脚本 |
| MVPlaer | 交互播放器 | 按脚本运行视频,响应交互点与学员操作,支持多种播放模式 |
| VideoEngineLib | 核心引擎库 | 视频解码、交互脚本模型、脚本执行器、SQLite 存储等公共能力,供编辑器与播放器共享 |
三个模块基于同一套引擎库构建,从根源上保证了**"编辑器里预览的"和"播放器里运行的"是同一套行为**------这是交互内容制作工具最容易被忽视、也最影响生产效率的一环。
三、核心功能
3.1 双后端视频引擎
视频引擎采用 Qt Multimedia 与 FFmpeg 双解码后端设计:
- 内置后端覆盖 MP4、AVI、MKV、MOV、WMV、M4V、MPEG 等常见格式;
- 编入 FFmpeg(avcodec / avformat / swscale / swresample)后,进一步支持 WebM、FLV、TS 等更多封装格式;
- 提供
play / pause / stop / seek / seekToFrame完整播放控制,并支持按帧号精确定位,满足逐帧级交互的需求;
- 内置关键帧提取能力,可将视频任意时刻画面导出为图片,供关键帧标注与预览使用。
3.2 交互点体系:视频的"决策点"
交互点是整个系统的核心概念------在视频时间轴上的某个毫秒级时间戳处定义一个"停下来等用户操作"的位置:
- 毫秒级时间戳 + 帧号双重定位:保存脚本时同步换算写入目标帧号,跳转执行同时依据时间戳与帧号,避免不同帧率换算带来的定位漂移;
- 自动暂停:播放到达交互点时自动暂停,等待用户响应;
- 超时机制:可为每个交互点配置等待秒数与超时行为(如超时自动继续、超时跳转),模拟真实场景中的时间压力;
- 序号自动管理:交互点序号采用"现有最大序号 + 1"规则自动递增,删除中间点后新增点不会复用旧序号,保证脚本数据稳定可追溯;
- 关键帧标记:交互点可绑定关键帧截图,播放器侧仅在播放位置接近对应时间戳时显示标记、离开后自动隐藏,界面干净不干扰。
3.3 画面交互元素:所见即所得的覆盖层
编辑器内可在视频画面上直接拖拽绘制五类元素:
|-----------|-----------------|
| 元素 | 用途 |
| Button | 触发命令的按钮,交互的主力 |
| Hotspot | 透明热区,点击画面某处即触发 |
| Rectangle | 高亮边框矩形,用于圈注重点区域 |
| TextLabel | 纯文字说明,不触发行为 |
| Image | 图片素材叠加 |
所有元素几何位置均采用 0~1 归一化相对坐标(左上角为原点),存储的是相对视频画面的比例而非像素值------无论窗口缩放还是更换分辨率,元素位置都不会发生位移,脚本跨设备复用零成本。编辑时元素显示高亮闪烁边框,便于精确定位。
3.4 交互命令:六种行为驱动剧情
每个元素可绑定一种交互命令,构成脚本的"剧情分支"能力:
|-----------------|-------------------------|
| 命令 | 效果 |
| Continue | 继续播放 |
| JumpToTimestamp | 跳转到指定毫秒位置 |
| JumpToFrame | 按帧号跳转(保存时自动按帧率换算) |
| Rewind | 从当前位置回退指定秒数,用于"答错了再看一遍" |
| OpenUrl | 打开外部链接 |
| Exit | 结束本次模拟(不关闭程序),用于考核收尾 |
配合超时行为,一个交互点即可表达"点击正确选项 → 进入下一环节;点击错误选项 → 回退重学;超时未操作 → 自动继续"的完整教学闭环。
3.5 脚本执行器:编辑与播放行为完全一致
InteractionScriptRunner 是独立的脚本执行组件,被编辑器与播放器共同复用:
- 按时间戳精确触发交互点,处理元素动作、跳转、超时;
- 编辑器内通过内存脚本挂载机制实现实时预览:脚本修改后无需重启播放即可同步生效,并自动重新武装已过的交互点,支持拖动跳转后交互状态正确恢复;
- 这意味着制作人员"边改边验"的所见即所得,最终交付给学员的播放行为与预览严格一致。
3.6 关键帧系统
- 一键提取当前帧为图片,自动存入视频旁的
.keyframes目录,缩略图存入.thumbnails;
- 关键帧与交互点绑定,文件名自动编码序号与时间(如
kf_001_00m15s.jpg);
- 播放器提供关键帧浏览模式:不播放视频,仅用左右方向键翻看关键帧图片,适合快速复习与考前速览;
- 播放过程中右侧关键帧列表按时间顺序高亮已过节点,鼠标悬停可查看说明与图片。
3.7 数据存储:单文件、可恢复、向后兼容
- 交互脚本以 SQLite 单文件数据库(
.mvdb) 存储,与视频同目录、同名,便于分发管理;内部以事务保证写入一致性,按排序恢复交互点顺序与关键帧索引;
- 兼容早期 UTF-8 JSON(
.interaction.json)格式:旧文件可直接打开,保存时自动升级为数据库;
- 支持项目打包 :一键将视频与脚本收拢为
.mvproject单文件,交付、归档一步到位;
- 编辑器具备崩溃恢复能力:编辑过程持续写入恢复文件,异常退出后可找回工作现场;同时记忆窗口状态,重启后自动询问是否恢复上次视频。
3.8 编辑器体验细节
- 时间轴可视化标注所有交互点,快捷键 M 快速添加;
- 属性面板集中编辑元素文字、图片与行为,列表悬停即可预览效果;
- 完整的撤销 / 重做(Ctrl+Z / Ctrl+Y);
- 空格播放暂停、左右键 ±1 秒、Home/End 跳转首尾、F11 全屏,输入文字时快捷键自动让路。
四、技术栈
|------|--------------------------------------------------------------------------------------------------------------|
| 类别 | 选型 |
| 开发语言 | C++(MSVC,x64) |
| 应用框架 | Qt 5(Widgets / Multimedia / Sql / Svg / Network) |
| 视频解码 | FFmpeg(libavcodec / libavformat / libavutil / libswscale / libswresample / libavfilter / libavdevice),双后端可切换 |
| 数据存储 | SQLite(Qt SQL 驱动),脚本单文件 .mvdb,项目打包 .mvproject |
| 目标平台 | Windows 桌面 |
五、设计亮点小结
- 一套引擎、两个前端:编辑器预览与播放器运行共享同一脚本执行器,杜绝"做的和放的不一样"。
- 归一化坐标体系:元素位置以相对比例存储,分辨率与窗口变化零影响。
- 时间戳 + 帧号双定位:跳转命令同时携带毫秒与帧号,跨帧率精确可靠。
- 超时驱动的教学闭环:正确跳转、错误回退、超时兜底,一个交互点讲完一个完整教学逻辑。
- 单文件分发:SQLite 脚本与项目打包,视频 + 交互一键交付。
- 工程健壮性:自动恢复文件、序号稳定递增、旧格式兼容升级,面向真实生产环境打磨。