# CodecFoundry **Repository Path**: otreee/CodecFoundry ## Basic Information - **Project Name**: CodecFoundry - **Description**: No description available - **Primary Language**: Unknown - **License**: LGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-08-16 - **Last Updated**: 2026-09-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # CodecFoundry v1.2.0 · NVIDIA HEVC / AV1 批量视频压制 当前源码入口为 `CodecFoundry.pyw`,应用内部版本为 1.2.0:PySide6 界面与 FFmpeg/NVENC 调度后端均 内置在同一个源码文件中。程序读取 `gpus.json`,按每块卡的编码、解码能力和 `encoder_engines` 数量调度多个视频。 ## 图形界面 Windows 可直接双击 `CodecFoundry.pyw`,或运行: ```powershell pythonw .\CodecFoundry.pyw ``` PySide6 界面采用深灰背景、蓝色操作按钮、橙色进度条和紫色状态栏,提供菜单栏、 最小化、最大化/还原和带确认保护的退出按钮,以及多文件/目录选择、HEVC 与 AV1、CQ、 可选 maxrate、分辨率、帧率及高级质量参数;视频、文件夹和 FlashCut HLM v2 也可直接拖入输入列表。点击 “停止全部”或在任务运行时关闭窗口, 都会取消队列并终止所有活动 FFmpeg 进程,而不是只停止当前视频。 在 Windows 上拖动自定义标题栏时优先交由系统窗口管理器处理,因此拖到屏幕顶部松开会 像普通窗口一样触发最大化;其他平台也提供顶部松开最大化的兼容路径。 每个编码槽(E0、E1……)都有当前文件进度/ETA 和整条队列进度/ETA。窗口较宽时最多按 两列排布,较窄时改为单列;高度不足时引擎区域显示纵向滚动条。点击“设置”会打开独立 子窗口,可启用“调试模式:显示 E0-E3”,在没有四个真实槽时预览四张进度卡。底部紫色状态栏按显示器 分辨率缩放并固定在窗口底部,编码启动后 会立即从“探测视频”切换为实际运行中的引擎和文件。 布局每秒检查一次窗口尺寸,避免持续响应造成额外占用: - 宽高比小于 1 时,所有 E 槽纵向排列; - 宽高比大于等于 1.7 且高度大于 800 时,原界面占左侧三分之二,E 槽改为纵向排列; - 超宽布局右侧显示按计划编码顺序排列的任务卡;任务栏宽度约从 1080p 下的 300 px 平滑增至 4K 下的 600 px。卡片包含文件名、源路径、容器、分辨率、帧率、编码格式和原体积; 等待中可单独取消,进行中可停止,已停止/失败可重新开始,已完成可直接打开输出; - 完成卡会额外显示输出体积、增减量箭头和压缩率,任务较多时右栏可滚动。 总进度按 1080p 等效帧计算:`等效帧 = 帧数 × 输出像素数 / 1920 / 1080`。因此 100 秒、4K、30 fps 会折算为 `100 × 30 × 4 = 12000` 个 1080p 等效帧。总 ETA 使用 每个 E 槽最近 10 秒的 1080p 等效平均速度分别计算队列 ETA,再取其中最大值;已经完成的 槽不会错误地“帮助”仍在运行的槽缩短 ETA。FFmpeg 每 0.5 秒更新一次进度。 ## 快速使用 要求 Python 3.10+、PySide6、FFmpeg/ffprobe,以及可正常运行的 NVIDIA 驱动和 `nvidia-smi`。 ```powershell # 检查环境与 JSON python .\CodecFoundry.pyw --cli --doctor # 两个视频并行压成默认的 HEVC,保持原帧率和分辨率 python .\CodecFoundry.pyw --cli a.mp4 b.mkv # 递归扫描目录,压成 AV1、CQ 19、限制 4K/60 帧,输出到 compressed python .\CodecFoundry.pyw --cli D:\videos --recursive --codec av1 ` --cq 19 --maxrate 27M --fps 60 --resolution 3840x2160 ` --output-dir D:\videos\compressed # 只查看调度和完整 FFmpeg 命令,不执行 python .\CodecFoundry.pyw --cli a.mp4 b.mp4 --dry-run # 查看完整参数帮助、默认行为与示例 python .\CodecFoundry.pyw --cli --help # 从 FlashCut HLM 直接读取原片并处理全部 HL;不需要 FC 预导出任何视频 python .\CodecFoundry.pyw --cli --hlm D:\Exports\source_highlights.HLM ``` ## FlashCut HLM v2 联动 FlashCut 以 GUI 方式联动时运行 `CodecFoundry.exe --hlm <清单.HLM>`。CF 启动后会把 `processing.jobs` 中的每个 HL 直接显示为待处理项,并从 HLM 的 `source.path` 打开同一份 原片。每个 FFmpeg 任务在原片输入上应用自己的精确 `-ss/-t` 时间窗,然后完成解码、裁切、 NVENC 编码、输出校验和报告;链路中不存在 FC 临时片段或二次输入视频。 HLM 中的 codec、容器、字幕、覆盖和输出目录会初始化 CF 控件;CQ、preset、lookahead 等 未固定参数使用 CF 当前偏好,开始前仍可调整。CF 会验证 HLM v2、最低 CF 版本、原片路径与 尺寸、完整 HL 引用、任务时间窗和安全输出名。完整字段定义见 [HLM_V2.md](HLM_V2.md)。 应用支持 `--version`,供 FC 在启动联动前验证已注册程序是否达到最低版本。当前联动协议要求 CF `>= 1.2.0`。 输出保留输入文件名,不再附加 `_hevc` 或 `_av1`;扩展名由输出容器决定。例如 `movie.mkv` 默认输出为 `movie.mp4`。若源本身就是 MP4 且未指定其他输出目录,为防止原地 覆盖,输出会自动写入源目录下的 `compressed\movie.mp4`。 压制成功后会把源视频的文件修改时间复制到输出;在 Windows 上还会一并恢复文件创建时间。 发现同名输出时不会只凭文件名跳过:程序先用 FFprobe 比较编码、分辨率、帧率和时长, 再让 FFmpeg 使用已选 NVIDIA GPU 的 CUDA/NVDEC 完整解码视频流。校验解码不会回退到 CPU;GPU 路径失败即判定校验失败。只有完整解码成功且时长差在容差内才跳过;空文件、 损坏、无法硬件解码或时长不一致的输出会自动覆盖重做。每次编码完成后也会对最终输出执行 同样的 GPU 完整解码校验,未通过的文件会删除并报告失败。显式使用 `--overwrite` 只跳过 已有输出预检,不会跳过编码后的最终校验。跳过项会单独写入日志和报告,不计为失败。 全部任务结束后还会在统一输出目录(或共同的 输出父目录)生成 `nvtranscode_report_时间.txt`,列出每个文件压制前后的尺寸、变化量与 百分比,以及总计压缩/增加了多少 GB。用户停止、Ctrl+C 或窗口关闭引发的取消也会生成 报告,并分别列出成功、失败、取消和未执行数量。 同容器且未要求转换分辨率/帧率时,如果编码结果反而比源文件大,程序会原子地用源文件副本 替换较大的编码结果;后续运行会识别该副本并直接跳过,不会重复压制。 点击窗口关闭按钮时,程序会先请求确认;确认后主界面立即隐藏,不继续干扰桌面工作。 若仍在编码,后台会终止全部 FFmpeg、等待调度线程退出并写完压缩报告,随后关闭窗口。 个性化参数保存在 `%APPDATA%\CodecFoundry\settings.json`;软件主日志默认关闭,开启后实时写入 `%APPDATA%\CodecFoundry\logs\CodecFoundry.log`。设置窗口可开关日志、调整历史日志条目 数(默认 8)和单文件最大尺寸(默认 8 MB),也可直接打开日志文件夹。 MP4 的确更通用,所以现在改为默认值。早先选择 MKV 主要不是为了边编码边看,而是因为 复制任意源音频和字幕时兼容性更宽松。普通 MP4 通常要等写完索引后才能可靠播放;本工具 使用 `+faststart` 在压制完成后把索引移到文件前部,并不把输出变成可边写边播的分片 MP4。 若源视频包含 MP4 不支持的音频或位图字幕,可选择 MKV,或取消复制字幕。 ## CQ-VBR 与画面内容分析 默认质量参数组合为: - `-rc vbr -cq 23 -b:v 0`:使用类似 CRF 的目标质量模式,不设置目标平均码率; - `-rc-lookahead 20`:查看后续帧复杂度和场景切换,改善跨帧码率分配; - `-temporal-aq 1`:按时间维度的纹理和运动特征调整量化; - `-bf 4 -b_ref_mode middle`:利用前后帧参考; - `-multipass fullres`:NVENC 对每帧做全分辨率两遍分析;这不是把整个文件编码两次; - 不传 `-minrate`,也不设置非零的 `-b:v` 目标码率。 CQ 越低质量越高、文件通常越大。它属于内容自适应 VBR,能根据画面复杂度和前后帧关系 分配码率,但不等同于 视频平台的私有感知模型、逐镜头码率梯度或离线多轮优化。可用 `--cq`、`--lookahead`、 `--multipass` 和 `--preset` 调整质量/速度。 只有显式传入 `--maxrate` 才会设置峰值限制。省略时不会把 `-maxrate` 或 `-bufsize` 传给 FFmpeg,即真正不限制峰值。脚本仍会显示 FFprobe 探测到的源平均码率作为参考,但 绝不会拿 VBR 输入的平均码率限制复杂场景的瞬时峰值。显式设置上限时,默认 `bufsize = maxrate`,对应约一秒 VBV 窗口。 ## 立即停止全部任务 命令行按一次 `Ctrl+C` 会设置全局取消状态、停止所有正在运行的 FFmpeg 进程组,并且 不会继续队列中的下一个视频。Windows 会在短暂的正常退出等待后使用进程树强制终止; Linux/macOS 则终止 FFmpeg 进程组。退出码为 130。 ## GPU 字典 每块 GPU 在 `gpus.json` 中配置: ```json { "index": 13, "name": "NVIDIA GeForce RTX 4080", "encoder_engines": 2, "encode": { "hevc": true, "av1": true }, "decode": { "h264": true, "hevc": true, "av1": true } } ``` - `encode` 只决定这块卡能否承担所选输出编码; - `decode` 按输入视频编码独立判断,绝不会用“不能编码 AV1”推导“不能解码 AV1”; - 输入编码不能硬解时会明确警告并使用 CPU 解码,输出仍由 GPU NVENC 编码; - `encoder_engines` 是并发槽数量。RTX 4080 示例设为 2,因此两个视频可同时编码; - 完整型号目录允许 `encoder_engines: 0`,表示该型号没有 NVENC; - 字典里的 `index` 是目录条目编号。脚本按显卡名称/可选 UUID 匹配,并使用 `nvidia-smi` 返回的实际设备 index 调用 FFmpeg; - 多 GPU 时可用多个 `--gpu 0 --gpu 1` 限定实际设备 index。 脚本以 JSON 为调度依据,同时核对 `nvidia-smi` 的名称/可选 UUID。JSON 应按 NVIDIA 官方支持矩阵和实际驱动环境维护。编码引擎数并不保证吞吐量线性翻倍:显存带宽、 CUDA 缩放、NVDEC、编码预设和驱动的分帧策略都可能成为瓶颈。 ## CPU 并行 任务先按输出分辨率、输出帧率和时长计算 1080p 等效工作量,再采用“最大任务优先”的 负载均衡分配,而不是按文件个数轮流分配。这样一个长视频和许多短视频同时出现时,长视频 会优先独占一个合适的槽,短视频被放到其他较轻的队列,减少某个槽早早空闲的概率。 每个正在工作的 NVENC 槽对应一个独立 FFmpeg 进程。脚本把可用逻辑核心划分成互不重叠 的核心组,并设置进程亲和性;这样两个并发任务不会被固定到同一组核心。软件解码、封装、 音频处理和驱动提交线程仍有各自的 CPU 空间。可用 `--no-cpu-affinity` 关闭。 Windows 超过 64 个逻辑处理器时,原生进程掩码只覆盖一个处理器组;脚本会只使用第一个 可寻址组。此类工作站建议按 NUMA/处理器组定制调度。 ## 进度和时间预估 FFmpeg 每 0.5 秒提供已编码帧数、实际编码 fps、输出时间和 speed。当前文件 ETA 直接按 剩余帧数除以该任务实际编码 fps 计算;每个槽的队列 ETA 使用最近 10 秒实际完成的等效帧 除以这段时间,批处理总 ETA 取所有未完成槽的队列 ETA 最大值。这仍是动态估算: 画面复杂度、硬解/软解切换、缩放及多路并发都可能令后续速度变化。 ## 注意事项 - 默认复制音频;MP4 中的文本字幕会转换为 `mov_text`。PGS 等位图字幕不能直接写入 MP4, 可加 `--no-subtitles`,或使用 `--container mkv` 保留原字幕流。 - GPU 支持某种编码不代表本机 FFmpeg 一定编译了对应编码器;脚本会同时检查。 - 即使 JSON 声明可硬解,特殊色度、位深或分辨率也可能超出硬件限制;硬解执行失败时 默认自动用 CPU 解码重试。可用 `--no-software-fallback` 禁止。 - `--resolution` 当前按给定宽高直接缩放,不保持宽高比;请传入目标画幅的正确尺寸。