最近写了个基于Qt 6.12.0 + FFmpeg 9.0.2的4k视频播放器,功能已经做的比较完善了。
如果你厌倦了各种视频播放器的广告,那就做一个属于自己的播放器吧!
源码下载链接:基于qt6.12+ffmpeg的4k视频播放器,沉浸式极简无边框界面,自适应硬解+软解,源码有详细注释,适合小白,可以作为课程设计或者毕业设计的参考资源-CSDN下载
开发环境: win11,qt6.12 ,qtcreator20.0.2
源码有详细注释,适合小白 压缩包里面有详细的软件功能说明书和软件设计方案。还有已经编译好的ffmpeg库,直接用就行
一、文档说明
1.1 编写目的
本说明书面向 QMoviePlayer 的使用者与验收者,逐项说明软件界面上每一个可见元素、每一项操作的含义与效果。文中所有截图均来自同一份片源《Zootopia.2.2025.1080p.AMZN.WEB-DL.English.DDP5.1.H.265.简中&英文.mkv》,以便对照"同一画面下的不同状态"。
1.2 阅读约定
- 文中"窗口宽度"均指逻辑像素(与系统缩放无关)。本机为 125% 缩放,截图是 1600×900 物理像素,对应 1280×720 逻辑像素。
- 「控制栏」指窗口底部那条半透明的悬浮工具栏;「进度条」指控制栏中间的蓝色横条。
- 「气泡」指悬浮在画面上方的深色圆角提示块,分为缩略图气泡 与**提示气泡(OSD)**两种。
说明书中的全部截图由脚本 tools/shoot_manual.py 自动抓取,窗口尺寸、跳转位置、鼠标动作、等待时间全部固定,可重复复现。
二、软件概述
2.1 产品定位
QMoviePlayer 是一款对标 QQ 影音操作习惯的 Windows 本地视频播放器。界面极简:没有菜单栏、没有系统边框,所有操作集中在一条会自动隐藏的悬浮控制栏上,画面本身占据整个窗口。
2.2 技术构成
| 层次 | 实现方式 |
|---|---|
| 解封装 | FFmpeg 9.0.2 libavformat,支持 mp4 / mkv / mov / avi / flv / wmv / rmvb / ts 等容器 |
| 解码 | 视频:D3D11VA → DXVA2 → 软件解码自动回退;音频:FFmpeg libavcodec |
| 渲染 | QOpenGLWidget + GLSL 3.3,双纹理做 YUV→RGB,支持 8bit / 10bit |
| 音频输出 | QAudioSink 推流(Float32 / 48kHz / 立体声),音频主时钟驱动同步 |
| 字幕 | 自研解析器,支持外挂 SRT / ASS / SSA |
| 界面 | Qt Widgets,无边框窗口手工实现拖动、缩放、最大化、全屏 |
2.3 主要能力一览
- 播放 / 暂停、进度拖动、±5 秒 / ±30 秒跳转、0%~90% 一键定位
- 进度条悬停显示该位置的真实画面缩略图
- 音量滑块、滚轮调节、一键静音
- 0.5x ~ 4.0x 倍速(保持音调不变)
- 外挂字幕:同名自动加载、字号缩放、0.5 秒步进延时校正、一键关闭
- 原始分辨率截图、播放列表、循环模式、音轨切换、画面比例与旋转、窗口置顶
- 窗口最小可缩至 100×50,宽度小于 650 时自动隐藏控制栏
三、启动与打开文件
3.1 启动界面
程序启动后若没有指定文件,显示空状态页:画面区为纯黑,中央一枚蓝色「打开文件」按钮,下方一行灰色提示"或将视频文件拖入窗口"。右上角的三个窗口按钮(最小化 / 最大化 / 关闭)在空状态下同样可见,不必先打开文件才能关窗口。

图 1 启动界面(空状态)
3.2 打开文件
三种方式都可以打开视频:
- 点击空状态页的「打开文件」按钮;
- 按
Ctrl+O,或右键菜单选择「打开文件...」; - 直接把视频文件拖进窗口。
文件对话框的过滤器为「视频文件」,只列出常见视频后缀,避免误选其它文件。

图 2 打开文件对话框,仅列出视频文件
3.3 命令行与关联打开
也支持把文件路径作为第一个参数传入,便于做文件关联或从其它程序调起:
QMoviePlayer.exe "D:\movies\sample.mkv"
路径含中文时同样可用(程序内部按本地 8 位编码解析参数,不依赖控制台代码页)。
四、主界面构成
4.1 整体布局
打开视频后,窗口只由三部分构成:
- 画面区:占满整个窗口,按"适应窗口"方式保持原始比例,多余部分留黑边;
- 控制栏:悬浮在窗口底部、居中显示的一条圆角深色栏,包含播放、进度、时间、音量、倍速、字幕、截图、循环、播放列表、全屏等全部控件;
- 窗口按钮:右上角的最小化 / 最大化 / 关闭,鼠标移入时会有浅色底。

图 3 播放主界面:画面 + 底部悬浮控制栏 + 右上角窗口按钮
控制栏内部从左到右依次为:播放/暂停、上一集、下一集、进度条、时间(当前/总长)、静音按钮、音量滑块、倍速、字幕、截图、循环模式、播放列表、全屏。
4.2 控制栏的自动隐藏
控制栏是"按需出现"的:鼠标在画面区域移动时出现;鼠标停住不动 5 秒后淡出隐藏,让画面完全干净。鼠标停在控制栏内部时不会隐藏 ------ 否则会出现"鼠标还没点到按钮,工具栏就消失了"。

图 4 鼠标静止 5 秒后控制栏淡出,画面无遮挡
控制栏隐藏后,右上角的三个窗口按钮依然可见。窗口按钮属于"窗口的一部分",不随控制栏一起淡出,否则用户想关窗口还得先晃一下鼠标。
五、播放控制
5.1 播放与暂停
三种方式等价:单击画面任意位置、按 Space、点击控制栏最左侧的播放按钮。按钮图标会随状态切换(播放中显示"暂停"两条竖线,暂停时显示"播放"三角),不会出现"画面在动但按钮显示播放"的不一致。
5.2 进度条与缩略图预览
把鼠标移到进度条上,会在鼠标上方弹出缩略图气泡:气泡里是该位置的真实画面,下方一行加粗时间,表示"松手后会跳到这里"。气泡水平跟随鼠标,靠近窗口边缘时自动夹在窗口内。

图 5 鼠标悬停在进度条 50% 处,气泡显示 53:56 的真实画面
气泡由"占位图 → 真图"两段式显示:气泡立即出现并显示灰色的"预览"占位块,后台线程解出画面后自动替换。因此手感是"气泡秒出、图稍后浮现",不会出现点击后毫无反馈。

图 6 缩略图气泡特写:真实画面 + 时间标签
5.3 拖动跳转
按住进度条拖动时,气泡跟随鼠标实时更新目标时间,但画面不会跟着跳动;松开鼠标才真正跳转。这样避免拖动过程中反复解码造成的卡顿与闪烁。

图 7 拖动中:气泡显示 1:06:45,右下角时间仍是原来的 32:24,松手后才跳转
除了拖动,还可以用键盘快速定位:←/→ 前后 5 秒,Ctrl+←/Ctrl+→ 前后 30 秒,数字键 0~9 直接跳到 0%~90%。
5.4 上一集 / 下一集
控制栏的上一集 / 下一集按钮(或 PageUp/PageDown)在播放列表中切换文件,列表为空时按钮无效果。
六、音量控制
三种调节方式,效果一致:
- 拖动控制栏上的音量滑块(0~100%);
- 在画面上滚动鼠标滚轮,每次 5%;
- 按
↑/↓,每次 5%。
调节时窗口底部中央会弹出提示气泡,显示当前音量百分比;音量为 0 时显示"静音"。点击喇叭图标或按 M 可一键静音,图标会变成带斜线的喇叭。把音量从 0 调大时会自动解除静音,不需要先按一次 M。

图 8 滚轮调节音量,底部弹出提示气泡

图 9 提示气泡特写:音量 64%
七、播放速度
倍速共 8 档:0.5x、0.75x、1.0x、1.25x、1.5x、2.0x、3.0x、4.0x。调节方式:按 [ 降一档、] 升一档,或右键菜单 →「倍速」直接选档。

图 10 按 ] 升档,底部提示当前倍速

图 11 提示气泡特写:倍速 1.25x
变速采用 FFmpeg 的 atempo 滤镜处理音频,人声不会变尖或变闷(保持音调),只改变语速。倍速会随配置保存,下次启动沿用。
八、字幕
8.1 加载方式
字幕只支持外挂文件(SRT / ASS / SSA),不支持读取视频内嵌字幕轨。两种加载方式:
- 自动加载 :字幕文件与视频同名、放在同一目录即可。程序会依次尝试
影片名.srt、.ass、.ssa,再尝试影片名.zh.srt、.chs、.chi、.zh-CN、.zh-Hans、.sc等中文变体; - 手动加载:右键菜单 →「字幕」→「加载字幕文件...」,选择任意 srt/ass 文件。

图 12 同名 SRT 字幕自动加载,字幕居中显示在画面上
8.2 字幕调节
右键菜单 →「字幕」子菜单提供四项:
| 菜单项 | 作用 |
|---|---|
| 字号 + / 字号 - | 每档 0.1 倍,范围 0.5~2.0 倍,随配置保存 |
| 延时 +0.5s / 延时 -0.5s | 字幕整体提前或延后 0.5 秒,用于校正不同版本的时间轴偏差 |
| 关闭字幕 | 临时隐藏字幕(数据仍留在内存,重新打开立即显示) |
| 加载字幕文件... | 手动指定字幕文件 |
控制栏上的字幕按钮可一键开关字幕:有字幕且开启时图标为蓝色,无字幕或已关闭时为白色。
ASS 字幕按文件内的样式渲染(字体、颜色、描边、位置),但不支持 \k 卡拉OK、\move 移动、\fad 淡入淡出等特效标签。
九、截图
按 Ctrl+S、点击控制栏的相机图标、或右键菜单 →「截图」,即可把当前画面按原始分辨率保存为 PNG(与窗口大小无关,1080p 片源存出来就是 1920×1080)。
保存位置固定为系统图片目录下的 QMoviePlayer 子目录,文件名为「影片名_年月日_时分秒.png」,例如Zootopia.2.2025.1080p.AMZN.WEB-DL..._20261024_221701.png。保存成功后底部会弹出提示,显示完整的保存路径。

图 13 截图成功后的提示气泡,显示完整保存路径
文件名用"年月日_时分秒"而不是冒号分隔的时间,一是 Windows 文件名不允许冒号,二是按文件名排序就等价于按时间排序。
十、播放列表
按 Ctrl+L、点击控制栏最右侧的列表图标、或右键菜单 →「显示播放列表」,右侧会滑出宽 300 的播放列表面板;再次执行同样的操作即可收起。
面板标题显示当前条目数,每个条目按「序号. 文件名」显示,鼠标悬停可看到完整路径,双击条目立即播放该文件。面板底部有「清空列表」,面板头部有「添加文件」与「隐藏播放列表」。

图 14 播放列表面板从右侧滑出,控制栏自动让出右侧空间
面板展开时,控制栏会向左偏移并缩短,避免被面板遮挡 ------ 这就是为什么同一窗口宽度下,面板展开前后的控制栏位置不一样。
播放列表会随配置保存,下次启动自动恢复;关闭程序前播到哪个文件、播到哪里,下次打开同一文件时也会自动续播。
十一、右键菜单
在画面区域单击右键弹出上下文菜单,几乎所有"不常用但必须有"的功能都收在这里,避免主界面堆满按钮。

图 15 右键菜单:常用操作 + 五个子菜单
| 菜单项 | 说明 |
|---|---|
| 打开文件... | 等同于 Ctrl+O |
| 播放 / 暂停 | 文字随当前状态变化 |
| 显示播放列表 | 滑出右侧面板 |
| 字幕 ▸ | 加载、字号、延时、关闭 |
| 音轨 ▸ | 切换视频内的多条音频轨(文件只有一条时显示"(无音轨)"并置灰) |
| 倍速 ▸ | 8 档倍速,当前档带勾选 |
| 画面 ▸ | 比例:适应窗口 / 拉伸铺满 / 原始尺寸;旋转:不旋转 / 90° / 180° / 270° |
| 截图 | 保存当前画面 |
| 循环模式 ▸ | 不循环 / 单曲循环 / 列表循环 |
| 窗口置顶 | 勾选后窗口始终浮在其它窗口之上 |
| 最大化 / 还原 | 文字随状态变化 |
| 全屏 / 退出全屏 | 文字随状态变化 |
| 关于 | 版本与致谢信息 |
切换音轨、倍速、循环模式、画面比例后,底部都会弹出提示气泡,例如「单曲循环」「拉伸铺满」,让用户确认操作已生效。
十二、窗口与显示
12.1 无边框窗口的拖动与缩放
窗口没有系统标题栏与边框,因此拖动和缩放由程序自己实现:
- 拖动 :按住窗口顶部 10 像素的窄条拖动。画面区域不再拖窗口,避免"想选中画面却把窗口拖走了";
- 缩放:按住左 / 右 / 下边框的 8 像素区域,或左下 / 右下角拖动,光标会自动变成对应的双向箭头;
- 双击:双击画面切换全屏,双击顶部标题区切换最大化。
12.2 最大化与还原
点击右上角中间的方块按钮(或双击标题区)最大化,再次点击还原。最大化采用自实现几何切换,并刻意比屏幕少 1 像素以避开 Windows 的全屏优化,因此切换过程不黑屏、不闪烁,也不会触发系统把窗口当成"全屏独占"。

图 16 最大化后画面铺满屏幕,控制栏仍在底部悬浮
12.3 全屏
三种方式进入全屏:双击画面、按 F11 / F / Enter、点击控制栏最右侧的全屏按钮。全屏时隐藏窗口按钮与标题区,只保留画面与(鼠标活动时的)控制栏;按 Esc 退出全屏。

图 17 全屏播放:画面按比例居中,上下留黑边
12.4 响应式:窄窗口与最小尺寸
窗口最小可缩到 100×50,相当于一个迷你播放器。窗口变窄时界面会分级适配:
| 窗口宽度 | 表现 |
|---|---|
| ≥ 650 | 正常显示控制栏,控制栏宽度自适应(520~1100),居中 |
| < 650 | 整个底部控制栏不显示,避免控件被挤压重叠;拉宽回 650 以上、鼠标一动即恢复 |
| 任意宽度 | 右上角三个按钮按可用宽度三等分缩小(36px → 最小 16px),始终可点 |
| 空状态 | 「打开文件」按钮按窗口等比缩小;窗口过小时隐藏下方提示文字 |

图 18 窗口宽度 600 时控制栏不显示,仅保留画面与窗口按钮

图 19 最小尺寸 100×50(图为放大 5 倍),三个窗口按钮仍可点击
窄窗口下虽然看不到控制栏,快捷键依然有效:Space 播放暂停、←/→ 跳转、↑/↓ 调音量、F 全屏等。
12.5 启动尺寸
程序会记住上次关闭时的窗口位置与大小(含是否最大化),下次启动原样恢复;首次启动时居中显示,宽高为桌面的一半。
十三、快捷键一览
| 按键 | 功能 |
|---|---|
Space |
播放 / 暂停 |
F / F11 / Enter / 双击画面 |
进入 / 退出全屏 |
Esc |
退出全屏 |
← / → |
后退 / 前进 5 秒 |
Ctrl+← / Ctrl+→ |
后退 / 前进 30 秒 |
↑ / ↓ |
音量 +5% / −5% |
M |
静音开关 |
[ / ] |
倍速降一档 / 升一档 |
0~9 |
跳转到 0%~90% |
PageUp / PageDown |
上一集 / 下一集 |
Ctrl+O |
打开文件 |
Ctrl+S |
截图 |
Ctrl+L |
显示 / 隐藏播放列表 |
鼠标操作:单击画面播放/暂停,双击画面全屏,滚轮调音量,右键出菜单,悬停进度条看缩略图。
十四、配置持久化
下列状态保存在系统用户配置中(Windows 注册表 HKCU\Software\QMoviePlayer),关闭程序后不会丢失:
| 项目 | 说明 |
|---|---|
| 窗口位置与大小 | 含是否最大化,下次启动原样恢复 |
| 音量 / 静音状态 | 下次启动沿用 |
| 播放倍速 | 下次启动沿用 |
| 字幕字号 / 延时 | 对所有字幕文件生效 |
| 画面比例 / 旋转 | 下次启动沿用 |
| 播放列表 | 含当前播放到第几项 |
| 续播位置 | 按文件路径分别记录,重新打开同一文件时从上次位置继续 |
运行日志写入 %APPDATA%\QMoviePlayer\QMoviePlayer\logs\app.log,按 5MB × 3 个文件滚动,便于排查播放异常。
十五、性能说明与已知限制
15.1 缩略图预览的耗时
进度条缩略图由独立线程 + 独立解码上下文生成,不占用播放线程,因此预览再慢也不会让播放卡顿。实测:
- 1080p 素材(本例):通常在 150 毫秒内出图,悬停时几乎无等待感;
- 2K / 10bit / 60fps 重素材:单张约 0.3~0.8 秒,气泡先显示占位图,图好后自动替换。
15.2 已知限制
- 硬解帧需要从 GPU 回读到内存(非零拷贝),4K/60fps HEVC 在低端集显上可能掉帧;
- 不支持读取视频内嵌字幕轨,只支持外挂字幕文件;
- ASS 字幕只渲染基本文本与样式,不支持
\k、\move、\fad等特效; - 不做 HDR → SDR 色调映射,HDR 片源会按原始数值显示;
- 仅支持本地文件,不含 HLS / DASH 等流媒体协议。