Easy4K Logo

Easy4K

一键视频超分补帧工具

把低清卡顿的视频,一次跑成高清高帧
转场检测 · 拆帧 · 帧去重 · AI 超分 · AI 补帧 · 音频超分 · 合并(HDR / 音频 / 元数据封面)· 帧数审查
Stars开源许可证

v2.1.2 · 基于 WinUI 3 (Windows App SDK 2.4) / .NET 10 的 Windows 桌面应用,工具与模型随程序自包含分发, 无需配置环境变量;版本号随微软商店上架版本自动更新,可从 Microsoft Store 一键安装。

一条处理链路跑通全流程

#流水线

一条流水线跑完全部处理

Easy4K 不把参数丢给用户自己拼命令,而是把转场检测(启用补帧与转场保护时)→ 拆帧 → 帧去重判决与平滑 → 超分 → 补帧 → 音频超分 → 合并(含 SDR→HDR、音频嵌入、元数据/封面)→ 帧数审查串成处理链路: 各阶段产物落在临时目录,可按已完成的产物续跑;去重回填与转场保护在合并前完成。

转场检测PySceneDetect · 可选
拆帧ffmpeg -q:v 2
帧去重SFDP SiameseNET · 可选
超分Real-ESRGAN / CUGAN / RealSR / SRMD / waifu2x
补帧rife-ncnn-vulkan / PyTorch
音频超分AudioSR 48 kHz · 可选
合并libx265 -crf 18
HDRNVEncC TrueHDR / HDRTVNet++ · 可选
音频PCM 24bit 48k / 96k
审查ffprobe 帧数比对
元数据/封面-map_metadata · -c copy

#主界面

主界面:一次配齐参数

选择视频后自动探测分辨率、帧率、时长与总帧数,勾选要执行的流程,选好超分与补帧模型, 输出分辨率与目标帧率实时算给你看。

#实时反馈

进行中:全程可见

处理过程不是黑盒:阶段进度、最新产出帧、子进程的近期日志、CPU/GPU 占用都在同一个页面里滚动更新。

阶段进度

转场检测 / 拆帧 / 帧去重 / 超分 / 补帧 / 音频超分 / 合并 / HDR / 音频 / 审查 / 元数据封面 各自独立进度,逐帧计数的同时保留百分比。

实时预览

跟随最新产出的帧刷新;新帧解码完成前保留旧画面,避免闪烁。

三联对比

帧去重时同步显示「判决帧 / 对比帧 / 筛选帧」,一眼看清这一帧在和谁比、比出了什么。

命令日志

收集子进程输出与标准错误;界面显示最近 200 行,内部日志另有容量上限,并支持复制。

占用监控

CPU 与 GPU 使用率实时采样,环形指示器直接反映当前压力。

同一帧的效果对比

#对比

720P → 4K:同一帧的细节差多少

把鼠标移到任意一张图上,两张图会以光标所在位置为中心同步放大——左右对照的永远是画面里的同一处细节。 移开鼠标即复位。

原帧 720P
原帧 · 1280 × 720
超分后 4K
超分后 · 4K(3840 × 2160,示例图为等比压缩)
悬停放大 2.6×两张图始终锁定画面中的同一处;手机上按住拖动也能放大。

v2.0 / v2.1 新增能力

#帧去重

帧去重:减少重复帧的计算量

动画与录屏里有大量画面是「定格」的:相邻帧几乎一模一样。Easy4K 默认用 SFDP 孪生网络(SiameseNET) 把它们挑出来,模型缺失或加载、预热失败时回退到四阶级联判决。勾选补帧时超分仍处理全部源帧, 只把保留帧交给补帧;未勾选补帧时才把重复帧移出输入目录,让超分只算保留帧。 合并前按索引表把结果展开回目标帧数,保持目标时间轴与音频对齐。

四阶级联判决(AI 模型缺失或预热失败时的回退路径;性能档在 dHash 后即判,完美档补上后两阶)

当前帧 vs 对比帧
 ├─ 第 1 阶 分块像素差          细块 / 粗块两级局部判定,检测到超阈值差异则保留
 ├─ 第 2 阶 dHash 汉明距离      整体结构是否一致
 ├─ 第 3 阶 QR 分解距离         归一化阈值 1.0 灰阶
 └─ 第 4 阶 Farnebäck 稠密光流   平均残差与方差双阈值终判

判为重复 → 勾选补帧:帧留在原地(超分要算全部源帧),只把保留帧挑出来喂补帧
         → 未勾选补帧:把可安全移走的重复帧移出输入目录(超分只算保留帧)
         → 合并前按 dedup_map.json 展开回目标帧数

#SFDP

SFDP(SuperFrameDedup):帧去重子系统的四件事

SFDP 是 Easy4K 里负责「判重」的那一层:判决、时序平滑、回填与 GPU 阶段并行, 四件事都围绕同一套索引表;回填不完整时会停止任务,而不是继续产出一支错片。

判决  →  时序平滑  →  回填
 │            │             │
 │            │             └─ 按 dedup_map.json 展开回目标帧数(expandPos / keptIndices)
 │            └─ 连续判为重复的标记不足 3 个则全部撤销,避免吃掉动画刻意的短暂顿帧
 └─ 判决:SFDP 孪生网络(SiameseNET / ONNX)
               (模型缺失或预热失败时回退四阶:像素差 → dHash → QR → Farnebäck 光流)

普通模式:整段判决与平滑完成后再进入超分 / 补帧
块流水:携带上一块末帧,一块前瞻后定稿,与 GPU 超分 / 补帧阶段重叠
分段涡轮:各段独立判重,跨段边界不比较;去重判决由全局锁串行执行
校验:判决表与磁盘实际帧数、产物数量核对,不匹配时回退串行重跑
两档判决
性能档:FP16 模型,阈值 0.60;完美档:FP32 模型,阈值 0.50(模型不可用时回退四阶)
时序平滑
连续判重标记不足 3 个则全部撤销,孤立的单帧或双帧判重不会生效
回填
按索引表展开到目标帧数,保持时间轴与音频对齐
按块流式
块流水模式与 GPU 阶段重叠,块间携带状态 + 一块前瞻

#可观测

三联对比:这一帧在和谁比

去重不是黑盒。进行中页会把三张帧并排显示:左侧是最近被判为重复的「判决帧」, 中间是「对比帧」,右侧是当前正在判决的「筛选帧」——一眼看出这一帧是和谁比、比出了什么。

判定、磁盘与产物保持一致

只有被判为重复的帧才会进入剔除流程;挑保留帧时逐个文件带退避重试,个别帧被占用会重试或改用备用目录。 重复帧搬移失败时按保留处理,块流水异常或产物数量不足时回退串行,回填不完整则停止任务。

#性能 / 完美

两档模式,按素材挑

两档用的是同一套孪生网络结构,差别在权重精度与判定阈值:性能档跑 FP16 模型、阈值 0.60; 完美档跑 FP32 模型、阈值 0.50。哪一档更适合,需要对代表性片段实际比对。

性能档 · FP16
阈值 0.60,权重与显存占用更低
完美档 · FP32
阈值 0.50,单精度权重,适合需要更保守判定的素材

#AudioSR

音频超分:把声音也一起提上来

基于 AudioSR 扩散模型重建高频,把音轨升采样到 48 kHz 直出;勾选「将原音频合并进新视频」时直接嵌入视频, 不勾选则单独输出一个 48 kHz 的 wav 文件。未开启音频超分时,音频由 FFmpeg 重采样到 96 kHz 后封装。

FP16 性能档 / FP32 完美档

FP16 权重约 1.3GB、推理更快;FP32 权重约 2.5GB、精度更高。FP16 需要在显卡上运行, 因此与「使用 CPU 处理所有模型」互斥——勾选时会弹窗拦截并给出说明。

#界面

高级模式与个性化

标准 / 高级一键切换:需要斟酌的进阶功能(帧去重、音频超分、转场优化、涡轮模式)集中在高级页,日常使用保持简洁。 界面当前固定简体中文(多语言词表与切换逻辑保留,入口暂时隐藏)。

主题
浅色 / 深色 / 跟随系统 / 亚克力 / 图片背景(可调亚克力浓度)
最大化界面缩放
100% / 110% / 125% / 150%,仅在窗口最大化时生效
报告
HTML 报告写到 ReportDir(默认 Reports,可关可自动打开);流水线失败另写一份完整 txt 到桌面
启动与电源
可选「启动时禁止系统自动休眠」,长时间处理不被睡眠打断

首次使用向导

向导一次配好默认流程、主题与报告选项;之后所有设置都能在设置页里改。

#加速

加速版 AudioSR:把扩散模型搬到 ONNX Runtime 上

官方 AudioSR 是 PyTorch + CUDA 的实现。这里把整条扩散链路导出成 ONNX,交给 ONNX Runtime 在显卡上跑: NVIDIA 优先尝试 CUDA,其它显卡尝试 DirectML,逐级不可用时回退 CPU。CUDA 运行库(cuBLAS / cuDNN / ORT CUDA EP) 与便携 Python 随包分发,用户无需自行配置 Python 环境;显卡驱动仍需满足所选后端要求。

读音频 → 重采样 48 kHz → 归一化 → 官方低通(滤掉伪高频,同时作为模型的低频条件)
  → log-mel → VAE 条件编码 → DDIM 50 步(eta = 1,CFG 3.5)→ VAE 解码 → vocoder 重建
  → mel / 波形低频段回填(回填源音频低频,减少低频内容偏移)→ 写 48 kHz WAV

加速要点
 ├─ 后端  NVIDIA:CUDA → DirectML → CPU;其它显卡:DirectML → CPU,逐级尝试
 ├─ 图优化 ORT_ENABLE_ALL 全图优化;DirectML 下关闭内存复用(enable_mem_pattern = false)
 ├─ 自检  启动先各跑一次最小推理,权重与图精度不匹配(fp16 图配 fp32 数据)立刻报错
 ├─ 分窗  5.12 秒窗、50% 重叠,长音频按窗推进;按单窗推理,不做并批
 └─ 约束  fp16 权重包禁止在 CPU 上跑(CPU 的 fp16 算子又少又慢),宁可报错也不悄悄退化
推理后端
NVIDIA:CUDA → DirectML → CPU;其它:DirectML → CPU;fp16 仅 GPU
权重包
FP16 / FP32 两套权重;体积以当前安装包为准
采样参数
DDIM 50 步 · CFG 3.5,与官方实现一致
失败处理
提取失败 / 模型缺失 / 推理失败都会明确报错终止,并在日志写明原因,不会静默用原音轨顶替

#音质

AudioSR 后期:官方低通 + 高频整形

扩散模型补出来的 8 kHz 以上高频是「凭空生成」的,容易过量成一片嘶声,安静段还会被填满宽带底噪。 现在的做法是:先按官方实现做低通滤波(0.985 分位求截止、8 阶零相位、硬降采样再升回 48 kHz), 再把生成的高频整形成「由源频谱自然外推」的包络——限制过量生成的高频,同时参考源频谱设置包络下限;实际听感仍需试听。

整形规则
源带宽 edge 以上才处理;目标 = 本帧中频能量 × 源在 edge 处的 HF/中频比,再按源斜率滚降
高频增益不超过 1
用平滑后的源频谱 ×1.05 作为目标包络下限,降低对源高频的过度抑制
安静段抑制
逐帧中频动态门控,抑制安静片段中过量的生成高频
响度对齐
按 0–8 kHz 的 RMS 对齐源音频,再 0.9 软限幅,低频不被高频尖峰拖低

#SceneGuard

转场优化:镜头切换处不插值

补帧会在相邻两帧之间「插」出一帧。碰上镜头硬切,插出来的就是两个镜头各混一半的鬼影帧。 开启转场优化后先用 PySceneDetect 扫出剪切点,合并前把切点处的插值帧换回上一镜头的末帧—— 帧数、帧率、时长都不变,只是不再有跨镜头混合。

检测
ContentDetector(阈值 27),结果写入临时目录,续跑直接复用;拆帧重跑时自动作废重扫
替换方式
切点处的插值帧换成上一镜头末帧;优先同卷硬链接,失败时复制,帧数 / 帧率 / 时长不变
适用素材
实拍、番剧这类硬切多的素材收益最大;叠化 / 白闪等渐变转场检测不到
代价与关闭建议
处理前多解码一遍源视频;图片式 / 静止片段多的素材建议保持关闭

#封装

元数据与封面:原片带什么就继承什么

成片是从帧序列重建的,原文件的标题、注释、封面不会自己跟过来。Easy4K 只在检测到源文件确实有元数据/封面时 才允许勾选;写回时用 -map_metadata + -c copy 只重封装不重编码, 封面按容器写成 mkv 附件或 mp4 attached_pic。

不覆盖原有 comment

原文件自带 comment(例如来源链接)时用「 | 」追加音频来源标记,而不是整段替换; 标记里同时写明 AudioSR 是否介入、精度档位、推理后端与输出格式。

SFDP:孪生网络判重

#AI 判决

SiameseNET:两帧一起看,只回答一个相似度

帧去重的默认判决器是一个孪生网络(Siamese Net,导出为 ONNX):左右两支共享权重, 把相邻两帧在同一坐标上的两张 128×128 灰度块一起送进去,输出 0~1 的分数,分数越高越倾向判为相似/重复。 整帧按 128×128 铺满分块、逐块推理后取「最低分」作为这一对帧的结论:只要有一块明显不同,两帧就不算重复。 该取法偏向保守,但仍需注意:模型输出只是相似度估计,不保证两帧像素完全相同。

相邻两帧 A / B(同一坐标分块,覆盖整帧)
   ↓ 每对 128×128 灰度块 → (N, 1, 128, 128),取值 [0,1]
SiameseNET(左右分支权重共享)
   ↓ score ∈ [0,1]:越高越倾向相似 / 重复
取所有块的最低分 → 与阈值比较(性能档 0.60 / 完美档 0.50)
   ↓
判为重复 → 按去重策略处理;合并前按索引表展开回目标帧数

为什么必须分块:1080p 里占画面 0.05% 的元素在动,全局平均差几乎察觉不到,
缩成小图更是彻底抹平;只有按块逐一看,才抓得住这种局部运动。
模型文件
Tools\SFDP\model.onnx(FP32 完美档)/ model_fp16.onnx(FP16 性能档)
判决阈值
整帧分块后取最低相似度:性能档 ≥ 0.60、完美档 ≥ 0.50 判为重复
分块推理
128×128 铺满整帧,每批最多 64 对推理;整帧取最低分
推理后端
DirectML 优先,建会话失败时可尝试 CPU;不同后端的数值结果可能存在细微差异
预热
进 AI 阶段先建会话并跑一次哑推理,避免第一帧判决卡住几秒
时序平滑
连续判重标记不足 3 个则全部撤销,孤立的单帧或双帧判重不会生效
回填
按 ExpandMap 展开回目标帧数,保持时间轴与音频对齐;不保证还原被移走帧的原始像素
失败回退
模型缺失、加载或预热失败 → 本次回退四阶判决(像素差 → dHash → QR → 光流)

参数与性能

#Real-ESRGAN

超分:按倍率筛模型

模型列表来自 realesrgan-ncnn-vulkan 的 models 目录,按当前倍率过滤: x2 / x3 对应 realesr-animevideov3-x2|-x3,x4 还提供 realesrgan-x4plus 与其动漫版。

倍率与模型联动

切换倍率会重新扫描模型目录并优先恢复上次选择,再回落到 realesr-animevideov3-x{倍率}, 避免出现"选了模型却不可用"。

低显存保护

显存不足时可勾选降低部分画质(补帧的 -u UHD 模式),与安全帧率可同时启用; 自动降级重试时也会一并打开省显存模式,避免只降线程仍然爆显存。

#补帧后端

补帧:NCNN 与 PyTorch 路径

NCNN 路径使用 rife-ncnn-vulkan,依赖可用的 Vulkan 驱动,本身不依赖 CUDA; PyTorch 补帧使用随包的便携环境。不同模型的硬件要求不同,不能仅凭显卡品牌判断是否可用。

v4 之前只支持 2 倍

只有 rife-v4 及以后支持 -n 目标帧数,命中 v2 / v3 老模型时会自动锁定倍率为 x2。

设备丢失就换策略

出现 VK_ERROR_DEVICE_LOST 或显存溢出:开启安全帧率则立即停止保护显卡, 未开启则自动降级为单线程 -j 1:1:1 并同时打开 -u 省显存模式重试一次。

#性能

高级性能选项与输出命名

超分与补帧各有一组「解码 / 编码」线程滑块(1~32);调整编码线程时,解码线程按约一半自动跟随(至少 1)。 NCNN 工具最终收到的是 -j 解码:编码:编码 三段参数,超过 1:8:8 会提示设备丢失风险。 CPU 处理模式下相关 GPU 开关会一并关闭。

线程数
超分 / 补帧各 1~32,解码 ≈ 编码 ÷ 2
安全帧率
致命 GPU 错误 → 停止
降低画质
补帧 -u(NCNN UHD 模式,降低显存占用)
FFmpeg GPU 加速
自动甄别 d3d11va / dxva2 / cuda / vulkan · NVENC·AMF·QSV
流水线 GPU
多显卡时指定用哪一块(自动 = 设备 0)
CPU 处理
-g -1 / run.py -cpu(超分无 CPU 后端则升级 GPU)
编码质量
CPU CRF 0~51(默认 18)· 硬件 CQ / QP 二选一
涡轮分段
1 = 不分段;2~5 段还要求走拆帧、无外部帧目录且总帧数足够
跳过开跑前测试
默认先用 1 秒测试视频验证勾选流程,可关
输出命名
{原名}[_分辨率_{fps}fps]_{SDR|HDR}[_音频嵌入].mkv(仅在超分 / 补帧时带分辨率与帧率)
降级重试
安全帧率开启则停止;否则 -j 1:1:1 + -u 重试一次
临时目录
块级流水 / 涡轮模式建议固态盘,机械盘会提示

内置的模型与引擎

#Real-ESRGAN

超分:五个引擎覆盖不同取向

各超分引擎使用各自的模型目录,Real-ESRGAN 的模型位于 Tools/realesrgan-ncnn/models。 启动与切换倍率时按已部署的模型文件过滤,下拉框只显示当前引擎与倍率可用的组合。

realesr-animevideov3
x2 / x3 / x4 · 面向动漫视频,效果与速度需结合片源判断
realesrgan-x4plus
x4 · 面向通用图像与实拍素材,可先对代表性片段试跑
realesrgan-x4plus-anime
x4 · 动漫线条专用,适合二次元素材
Real-CUGAN / RealSR / SRMD / waifu2x
另外四套引擎:Real-CUGAN、RealSR、SRMD 与 waifu2x;模型及倍率由各自目录表限制,waifu2x 当前界面固定 ×2

#选型

720P → 4K:按片源挑模型

720p 到 2160p 正好是 ×3。模型与倍率是绑定的,倍率选错下拉框里就没有对应模型,所以这里直接给结论:

动漫 / 番剧
realesr-animevideov3-x3 · 正好 720p→2160p,速度快、线条稳,首选
老番 / 脏源
可比较 CUGAN 的 ×3 降噪与保守模型;降噪强度和细节保留需用实际片段确认
实拍
srmd-x3 得到精确 2160p;要纹理细节可用 realesrgan-x4plus(×4 → 2880p)
不推荐
当前程序的 waifu2x 路径固定 ×2:720p 单次输出为 1440p,不直接得到 2160p

#rife-ncnn-vulkan

补帧:NCNN 引擎

rife-ncnn-vulkan 走纯 Vulkan 推理,本身不需要 CUDA。模型目录下带 flownet.param 的子目录都会被识别。

模型随安装包提供

rife-v2 / v2.3 / v2.4 / v3.x / v4.x 及 -lite / -HD / -UHD / -anime / -large / -heavy 变体; 常用模型(v4.6、v4.18、v4.22-lite、v4.25、v4.26)会排在最前。

8GB 显存门槛

v4.25 / v4.26 这类大模型建议 8GB 以上显存;显存偏小时仍可选中,但显卡状态区会给出明确告警。

#补帧

补帧:只吃目录,按帧数打命令

补帧只需要一个输入帧目录和一个输出目录。NCNN 路径把倍率写成 -n 输出总帧数; 开了帧去重时按「保留帧 × 倍率」传,合并前再展开到目标帧数,保持目标时间轴与音频对齐。

运行库随包,驱动仍需匹配

NCNN 路径可使用支持 Vulkan 的 NVIDIA / AMD / Intel 显卡,实际可用性取决于驱动、模型与显存。 安装包包含 CUDA 运行库(cuBLAS / cuDNN / ONNX Runtime CUDA EP)与便携 PyTorch,供相应推理路径使用; 只有 NCNN / Vulkan 补帧路径本身不依赖 CUDA。转场检测使用随包 Python 与 PySceneDetect。

块级流水(涡轮模式)

帧序列按块切分,超分与补帧两条 GPU 流水同时推进,去重判决也放在 CPU 侧与 GPU 重叠; 临时目录在机械盘时程序会给出提示,建议改用固态盘。

旗舰的软件性能

#性能

把机器压满,把界面留给你

外部工具会把 CPU 与显卡吃满,所以"不卡"靠的不是少用资源,而是把资源分配和界面更新彻底分开: 重量级工作全在子进程与后台线程里,UI 线程只负责渲染和绑定。

线程可控

线程滑块映射到 NCNN 的 -j 解码:编码:编码(各 1~32);超过 1:8:8 会明确告警设备丢失风险。

GPU 全链路

拆帧时自动甄别可用的硬件解码后端(d3d11va / dxva2 / cuda / vulkan),合并优先 NVENC → AMF → QSV;HDR 在支持 TrueHDR 且 NVEncC 可用时优先 NVEncC,否则尝试 HDRTVNet++(DirectML)。

低显存自适应

遇到显存不足或设备丢失时,开启安全帧率会停止任务,否则降为单线程并打开省显存模式重试一次;也可手动勾选补帧 UHD 模式降低显存占用。

界面不冻结

删除几万个中间文件放后台线程执行,CPU/GPU 采样也是独立线程,主线程只做绑定更新。

预览不闪烁

新帧解码完成前保留旧画面,并用序号丢弃过期的异步解码结果,避免旧帧覆盖新帧。

日志不拖垮 UI

界面侧只保留最近 200 行、按 250 ms 批量刷新;内部另有约 64 MB 上限的日志缓冲供导出与失败报告,不受界面 200 行限制,但不是无限保存。

更好的自动化流程

#自动化

从选择视频到交付,中间不用你管

能自动判断的都让它自己判断:该先验证的先验证,该跳过的跳过,该退让的退让,跑完自己把产物交出来。 你只需要决定"要做什么",不用盯着"现在到哪一步、要不要重来"。

#流程

一条链路自己往下走

选择视频
 ├─ 自动探测分辨率 / 帧率 / 时长 / 总帧数
 ├─ 临时目录指纹校验 ── 不符 → 引导更换或清理
 ├─ 处理前测试:1 秒测试视频 × 当前勾选流程
 │    └─ 没跑通 → 直接取消正式处理,不浪费几个小时
 └─ 正式处理:转场检测(启用时)→ 拆帧 → 去重判决与平滑
                → 超分 → 补帧 → 音频超分
                → 合并(含 HDR / 音频 / 元数据封面)→ 帧数审查
      ├─ 帧去重:勾选补帧时超分算全部源帧、只省补帧的计算量
      ├─ 每阶段:帧数够就跳过,残留就清理后重跑
      ├─ 出错时:按实际条件降级 / 回退 / 重试,无退路则停止
      └─ 完成后:审查帧数 → 自动命名输出 + 生成 HTML 报告

启动前先验证一遍

先用 1 秒测试视频按当前勾选的流程完整跑通,再开始处理正式视频,测试残留自动清理;也可以选择跳过。

失败自动换策略

启用旧版重试且旧版已部署时,FFmpeg 新版失败后尝试旧版,再转 CPU 处理档;硬件编码失败退 libx265、模型不被支持换 rife-v4.6、设备丢失按安全帧率设置停止或降单线程;没有可用退路时停止并生成失败报告。

断点自动续跑

按输出帧数判断阶段是否已完成,够数就整段跳过;中断留下的半截帧序列会被清理后从该阶段重跑。

产物自动交付

按规则自动命名输出文件,成功后生成内嵌选项、命令与抽帧图的自包含 HTML 报告,并可自动打开。

缓存自动校验

临时目录写 cache.json 指纹,换了视频会在启动前提示更换目录或清理,避免旧帧被当成新素材。

配置自动记忆

主题、模型、倍率、线程、各开关与目录改动即时落盘;首次运行由向导一次配齐,之后开箱即用。

单文件与定时任务

#单文件

单文件超分:图片、音频、视频 HDR 单独跑

不走完整流水线(不拆帧 / 不补帧 / 不合并):选一个文件,按类型直接处理并给出结果,适合封面、BGM 与单支视频的快速处理。

图片
png / jpg / webp,选超分模型与倍率(2 / 3 / 4),与主管线设置互不影响
音频
wav / mp3 / flac 等直接跑 AudioSR,精度 FP16 / FP32 二选一
视频音频超分
只替换视频里的音轨为 AudioSR 48 kHz 版本,画面不重编码
视频 HDR
优先 NVEncC TrueHDR;不可用时改用 HDRTVNet++(AI 强度 50%~150%)

孤儿模式:到点自动跑,跑完自动关

主页的「将此任务添加为孤儿执行任务」会按当前选项把任务排队;到设定时间自动启动 Easy4K 处理这支视频, 完成后自动退出,可一次排队多个任务、随时删除。适合挂机批量。

架构分层

#分层

单一职责的三层结构

没有引入依赖注入容器,启动时在 App.OnLaunched 里手工装配服务链并交给 MainViewModel,界面通过静态入口 App.Services 取用状态中枢。

#Views

表现层

XAML 窗口与页面负责交互:主界面收集参数,进行中页展示进度、预览与日志,欢迎向导负责首次运行配置。

#ViewModels

状态与编排层

MainViewModel 维护勾选联动、模型过滤、输出预览与启动前校验,并驱动 ProcessingOrchestrator 执行流水线。

#Services

基础设施层

进程执行、命令拼装、显卡与环境探测、工具路径解析、配置持久化、报告生成都被拆成可单独测试的小服务。

App 与窗口

App.xaml.cs 装配服务并决定进入欢迎向导还是主窗口;MainWindow 负责标题栏、菜单、导航与关闭拦截。

Views

MainPage 收集参数与启动校验,ProgressPage 展示进度/预览/日志/占用,WelcomeWindow 完成首次配置。

ViewModels

MainViewModel 是状态中枢:勾选联动、模型按倍率过滤、显存告警、输出命名预览、缓存校验。

ProcessingOrchestrator

编排全链路(转场检测 / 拆帧 / 帧去重 / 超分 / 补帧 / 音频超分 / 合并 / HDR / 音频 / 审查 / 元数据封面),处理断点续传、进度推送、条件化失败回退与最终输出拷贝。

ProcessRunner

统一的进程执行器:逐行读取输出、支持取消与挂起/恢复、记录退出码与标准错误摘要。

CommandBuilders

FFmpeg / Real-ESRGAN / RIFE / NVEncC 的参数拼装各自独立,路径统一加引号并规范化分隔符。

探测与解析

GpuDetector 判断型号与显存,EnvironmentDetector 校验工具与版本,VideoInfoDetector 用 ffprobe 取分辨率/帧率/总帧数。

配置与产物

SettingsService 读写 appsettings.json,ToolPathResolver 定位 Tools 目录,OutputNamer 决定最终文件名。

监控与界面

CpuGpuMonitor 采样 CPU/GPU 占用;主题支持浅色、深色、跟随系统与亚克力,选择即时落盘。

自测与批量测试

MainViewModel.AutoTest 驱动 --selftest 与 --autotest-all:按阶段掩码跑链路、遍历模型矩阵,失败用例单独保留临时目录。

本地化

LocalizationService 读取 Loc/strings.json,文案按语言键切换;当前界面固定简体中文,切换入口暂时隐藏。

报告与崩溃留痕

HtmlReportService 生成 HTML 处理报告;CrashReportService 将流水线失败现场写成桌面 TXT;应用异常处理另将堆栈写入可写数据根下的 crash.log。

LuminolCore 与 LuminolEngine

#分层

一个管算法,一个管执行

Easy4K.LuminolCore 是独立的类库(Easy4K.LuminolCore.dll),包含帧去重判决与稠密光流, 不依赖 WinUI 界面类型;它面向 Windows,帧去重实现会用到 Windows 图像接口。LuminolEngine 则是应用内的执行引擎层, 负责把 UI 收集来的参数变成命令、把命令变成进程、再把进程输出变成进度与报告。

src/├─ Easy4K/WinUI 3 应用(Views / ViewModels / 入口)│ └─ LuminolEngine/执行引擎:被 UI 层调用│ ├─ ProcessingOrchestrator全链路编排 / 断点续传 / 降级回退│ ├─ ProcessRunner进程执行(逐行读 stdout/stderr、暂停/恢复)│ ├─ CommandBuilders/FFmpeg · Real-ESRGAN · RIFE · NVEncC · AudioSR│ ├─ SiameseDedupServiceSFDP 孪生网络推理(ONNX)│ ├─ HdrAiConverterHDRTVNet++ 的 AI SDR→HDR 重建│ └─ 探测 / 设置 / 日志 / 报告 / 监控 / 任务存储└─ Easy4K.LuminolCore/算法类库(不依赖 WinUI,目标 Windows) ├─ FrameDedupService四阶级联判决 + 时序平滑 + ExpandMap └─ FarnebackFlow自实现的稠密光流(对齐 OpenCV 参数)
LuminolCore · 定位
独立 DLL,只做算法;不依赖界面类型,但目标平台为 Windows
LuminolCore · 内容
FrameDedupService(判决 / 平滑 / 回填表)与 FarnebackFlow(灰度金字塔 + 多项式展开 + 金字塔上采样)
LuminolEngine · 定位
应用内的执行引擎层:编排、进程、探测、命令拼装、报告、设置集中在这里
依赖方向
UI → LuminolEngine → LuminolCore 为单向依赖;改动算法层通常不影响界面,但仍以实际接口变更为准

#引擎

LuminolEngine 里的职责分工

引擎层承担「执行一次任务」所需的主要能力;各模块按职责拆分,可单独替换或单独测试, 但本地化服务等服务仍会操作 UI 可视树。

ProcessingOrchestrator
编排各处理阶段、断点续传、进度推送、失败回退与最终产物拷贝
ProcessRunner
所有外部工具的统一执行器:逐行读 stdout/stderr、取消、暂停/恢复、记录退出码
CommandBuilders
FFmpeg / Real-ESRGAN / RIFE / NVEncC / AudioSR 各自拼参数;SrCatalog · VfiCatalog 统一「算法 → 模型」表
探测层
GpuDetector + DxgiMemoryQuery 取显卡与真实显存;EnvironmentDetector 核对工具与模型;VideoInfoDetector 用 ffprobe 取帧数
SiameseDedupService
加载 SFDP ONNX 模型、DirectML 优先、整帧分块推理,给编排层返回判决表
HdrAiConverter
NVEncC TrueHDR 不可用时的 SDR→HDR:HDRTVNet++ 逐帧重建高光,输出 PQ / BT.2020 的 HDR10
运行支撑
AppPaths 区分只读安装目录与可写根;SettingsService 落盘;Logger 汇总日志(约 64 MB 缓冲上限);SleepGuard 防休眠;StorageMediaDetector 判 SSD
产物与诊断
OutputNamer 定名;HtmlReportService 出自包含报告;CrashReportService 失败时把完整现场写到桌面

关键实现逻辑

#进度采集

进度是怎么算出来的

FFmpeg 与 NVEncC 会往标准错误输出覆盖式进度,所以进程读取按 \r 与 \n 都切分,逐行实时回调;AI 工具没有进度输出,就轮询输出目录的帧数再叠加当前帧内的 tile 百分比。

// 按 \r 与 \n 都切分,否则 FFmpeg 的覆盖式进度会被缓冲到进程结束
if (c == '\r' || c == '\n') { onLine(sb.ToString()); sb.Clear(); }

// 拆帧 / 合并:解析行内帧号
frame=\s*(\d+)            →  已处理 1234 / 4823

// HDR:优先解析百分比,帧号比例仅在分母合理时采用
(\d+(?:\.\d+)?)\s*%       →  已处理 45%

// 超分 / 补帧:轮询输出目录帧数 + stderr 的 tile 百分比
进度 = min(已完成帧数 + 当前帧内百分比 / 100, 总帧数)

#容错回退

失败不是终点,是分支

能回退的环节按实际条件逐级尝试:能用 CPU 的转 CPU,能换编码器的换编码器, 模型不被支持就换模型;没有可用退路时停止任务并把错误交给日志与失败报告。

拆帧 / 合并    启用旧版重试且旧版已部署   → 新版 FFmpeg 失败后尝试旧版
拆帧 / 合并    旧版不可用或仍失败         → CPU 处理档(关闭相关硬件处理)
音轨/封面/元数据/AudioSR 转 48k            → 按同样条件尝试旧版,再转 CPU 档
HDR            NVEncC 转换失败             → 条件允许时重试旧版,仍失败则终止,不自动改走 AI
合并           硬件编码器失败              → 回退 libx265 -crf 18
超分           捆绑版无 CPU 后端           → 自动升级为 GPU 处理
补帧           "MemoryData not exists"     → 回退 rife-v4.6
补帧           v2 / v3 老模型              → 强制 x2 并锁定倍率下拉框
GPU 致命       设备丢失 / 显存溢出          → 安全帧率:停止;否则:-j 1:1:1 重试
失败           任何阶段                    → 停止任务并生成失败报告(不静默跳过)

#断点续传

断点续传靠数帧数

每个阶段开始时先数输出目录里的 PNG:够数就整段跳过;有残留但不够数,说明上次是被中断的, 先清理再从该阶段重跑,避免半截帧序列被当成有效输入。

existing = 输出目录 PNG 数量

existing >= 目标帧数      → 当前阶段已完成,直接跳过
0 < existing < 目标帧数   → 清理残留,从本阶段重新开始
existing == 0            → 正常执行

#缓存校验

临时目录的指纹

临时目录里会写一份 cache.json,记录来源视频路径、文件大小与最后修改时间。 换了视频却没清理临时目录时,启动前会提示重新选择目录或清理缓存,避免旧帧被误当成新素材。

{
  "inputVideo": "D:/video/彩条测试视频.mp4",
  "videoSize": 1089894,
  "videoModifiedTicks": 638600000000000000,
  "createdAt": "2026-09-13 13:20:41"
}

指纹不一致 → 弹窗:重新选择临时目录 / 清理缓存 / 取消

开发与自测

#--selftest

命令行自测

带参数启动即可跳过界面操作跑一遍链路,结束后把自测日志写入报告文件并退出, 适合放进批处理或 CI 做回归。

Easy4K.exe --selftest <输入视频> <报告文件> [阶段掩码]

阶段掩码(位运算):
  1  拆帧       2  超分       4  补帧
  8  合并      16  音频      15  拆帧 + 超分 + 补帧 + 合并(默认,不含音频;此入口关闭 HDR)

其它入口:
Easy4K.exe --selftest-clean <临时目录> <报告文件>   # 清理链路自测
Easy4K.exe --dedup-test                              # 只跑帧去重判决

#--autotest-all

全模型自动测试

遍历模型目录里的超分与补帧模型逐个真跑,界面全程可见可停;失败的用例会把临时目录单独保留, 方便对着中间产物复查。

Easy4K.exe --autotest-all           # 代表性模型 × 各倍率
Easy4K.exe --autotest-all full      # 全模型 × 2~5 倍率全矩阵
Easy4K.exe --autotest-api full      # API 模式逐例子进程跑全矩阵

结果写入:Res\autotest\AutoTestSummary.txt
API 模式:Res\autotest_api\ + 桌面 Easy4K流水线全组合自动测试_*.txt
失败残留:Res\autotest\fail\

#技术栈

技术栈

应用、运行时依赖、外部工具与模型组成安装包,并非所有内容都塞在单个 exe 中。随包环境无需手动配置,显卡驱动仍需满足所选后端要求。

框架
WinUI 3 / Windows App SDK 2.4
语言 / 运行时
C# · .NET 10(net10.0-windows)
MVVM
CommunityToolkit.Mvvm 8.4
分发方式
Microsoft Store 安装包 · 工具与运行时随包
外部工具
FFmpeg · Real-ESRGAN / CUGAN / RealSR / SRMD / waifu2x · RIFE · NVEncC · HDRTVNet · PySceneDetect · AudioSR
配置
appsettings.json(工具路径 / 默认模型 / 开关)
补帧引擎
NCNN / Vulkan 与 PyTorch 两类补帧路径
音频超分
ONNX Runtime · CUDA / DirectML / CPU(按精度与可用性)

上手使用

#上手

三步开始

没有快捷键要记,也没有命令行参数要背:选好输入与目录,勾选要跑的阶段,点「开始处理」。

1  选择输入        视频文件;或「导入」已有 PNG 帧文件夹直接跳过拆帧
2  勾选流程与模型    拆帧 / 超分 / 补帧 / 合并 / SDR→HDR
                   保留内嵌字幕 / 嵌入元数据 / 嵌入封面
                   补帧可直接填「目标帧率」(0 = 按倍率)
3  开始处理        主页实时显示最终文件名;进度、预览与日志在「进行中」页
                  处理中可以停止;「清理临时文件」回收中间产物

#目录

发布后的目录结构

程序把只读资源(exe、Assets、Tools)和可写数据分开放:商店版的安装目录在 WindowsApps 下且只读,配置、报告、临时与输出统一落到 %LOCALAPPDATA%\Easy4K;便携版在 exe 目录可写时直接使用 exe 同级目录。

安装目录(商店版只读 / 便携版为 exe 所在目录)├─ Easy4K.exe├─ appsettings.json首次启动使用的配置模板├─ Assets/图标与字体资源└─ Tools/默认工具根(相对路径,可在设置里改) ├─ FFmpeg-Lei/bin/新版 ffmpeg.exe · ffprobe.exe ├─ FFmpeg-Old/bin/旧版 FFmpeg(按条件兜底重试) ├─ realesrgan-ncnn/超分:Real-ESRGAN ├─ realcugan-ncnn/超分:Real-CUGAN ├─ realsr-ncnn/超分:RealSR ├─ srmd-ncnn/超分:SRMD ├─ waifu2x-ncnn/超分:waifu2x ├─ rife/补帧:rife-ncnn-vulkan ├─ FrameInterp/PyTorch 补帧驱动 vfi_driver.py + 各模型目录 ├─ NVEncC_9.32_x64/NVEncC64.exe(HDR / 硬件编码) ├─ NVEncC-Old/旧版 NVEncC(按条件兜底) ├─ HDRTVNet/AI SDR→HDR 模型(hdr_ensemble.onnx) ├─ SceneDetect/转场检测(PySceneDetect) ├─ SFDP/帧去重孪生网络(model.onnx / model_fp16.onnx) ├─ AudioSR/audiosr_onnx.py + models-fp16/ + models-fp32/ + ort-cuda/ ├─ python/便携版 Python(AudioSR 脚本用) └─ python-torch/带 PyTorch 的 Python(PyTorch 补帧用)可写数据根(商店版 %LOCALAPPDATA%\Easy4K / 便携版 exe 同级)├─ appsettings.json实际读写的配置├─ Res/自测与自动测试产物(autotest、autotest_api)├─ Reports/HTML 处理报告├─ Temp/中间产物(帧序列等)├─ Output/最终输出└─ crash.log应用异常日志

运行环境要求

操作系统
Windows 10 1809+ / Windows 11 · 64 位
显卡
超分与 NCNN 补帧需支持 Vulkan;其它功能按所选后端(DirectML / CUDA / CPU)
SDR→HDR
支持 TrueHDR 且 NVEncC 可用时优先 NVEncC;否则尝试 HDRTVNet++
内存
建议 8GB 以上
显存
4K 超分建议 6GB 以上
超分引擎
Real-ESRGAN / Real-CUGAN / RealSR / SRMD / waifu2x(NCNN · Vulkan)
补帧引擎
NCNN / Vulkan 或 PyTorch,硬件要求随模型而异
音频超分
CUDA / DirectML;CPU 处理请选择 FP32
帧去重
SFDP 孪生网络(ONNX · DirectML 优先,可回退 CPU)
转场检测
PySceneDetect 0.7.2(随包 Python,可选功能)
磁盘空间
安装体积以商店当前版本为准;另留足中间帧与输出空间
磁盘格式
推荐同卷 NTFS 以利用硬链接;链接失败则复制

#环境

跑起来需要什么

Windows 10 1809 及以上 / Windows 11;超分与 NCNN 补帧需要可用的 Vulkan 驱动, 其它功能按所选后端要求 DirectML / CUDA 或 CPU。 SDR→HDR 在支持 TrueHDR 且 NVEncC 可用时交给 NGX TrueHDR;否则尝试 AI 模型 HDRTVNet++ 按画面重建高光(DirectML,输出 HDR10 的 MKV)。两条路都不可用时该选项才不可用。

建议 8GB 以上内存;4K 超分建议 6GB 以上显存。出现显存不足或设备丢失时, 开启安全帧率会停止任务,否则降为单线程并打开省显存模式重试。

超分走 NCNN / Vulkan;补帧可选 NCNN / Vulkan 或 PyTorch 路径,硬件要求随模型而异; 帧去重优先 DirectML(不可用时回退 CPU),音频超分按 CUDA → DirectML → CPU 逐级尝试(FP16 仅 GPU)。 转场检测依赖随包 Python 与 PySceneDetect,属于可选功能;临时目录建议放在固态盘,同卷 NTFS 有利于使用硬链接。

常见问题

点了「开始处理」没反应,或提示「请先选择有效的输入视频」?
为什么提示临时目录里有旧文件?
处理到某个阶段卡住不动?
开了「CPU 处理」,为什么超分还在用 GPU?
HDR 选项是灰的,点不动?
输出文件名是 _SDR 而不是 _HDR?
日志太多看不过来?
处理中关闭窗口会怎样?
帧去重会不会让视频变短、音画不同步?
音频超分的 FP16 档为什么不能和 CPU 处理模式一起开?
软件会上传我的视频或文件名吗?
更多细节留给您自行探索!