# Task02:封装 WebCodecs 判定模块(utils/codecs) ## 目标 - 在 `src/utils/codecs` 封装 WebCodecs 判定逻辑 - 提供统一接口:`detectAll`、`checkAVC`、`checkHEVC` - 返回结构包含环境、检查细节、错误与时间戳,便于 UI 展示 - 增强输出:分别判定 H.264(AVC) 与 H.265(HEVC) 的“硬解/软解”支持情况 - 可靠性校验:在 `isConfigSupported` 为真后,实际执行 `VideoDecoder.configure(config)`,若抛错或触发 `error` 回调,则视为“不支持” ## 目录结构(计划) - `src/utils/codecs/types.ts`(类型定义) - `src/utils/codecs/detect.ts`(具体判定逻辑) - `src/utils/codecs/index.ts`(导出聚合) ## 类型与接口(拟定) ```ts export type CodecStatus = 'supported' | 'unsupported' | 'unknown'; export interface CodecDetail { hardware: CodecStatus; // 硬件解码支持 software: CodecStatus; // 软件解码支持 overall: CodecStatus; // hardware 或 software 任一为 supported 则为 supported } export interface CodecSupport { webCodecs: boolean; avc: CodecDetail; hevc: CodecDetail; details: { env: { userAgent: string; isSecureContext: boolean; hasVideoDecoder: boolean; }; checks: Array<{ codec: string; hardwareAcceleration?: | 'require-hardware' | 'require-software' | 'prefer-hardware' | 'prefer-software' | 'no-preference'; phase: 'isConfigSupported' | 'configure'; ok: boolean; result?: unknown; // isConfigSupported 返回或 configure 成功标记 error?: string; // 异常或 VideoDecoder error 回调信息 }>; errors?: string[]; timestamp: number; }; } export async function detectAll(): Promise; export async function checkAVCDetail(): Promise; export async function checkHEVCDetail(): Promise; // 可选:保留聚合态接口(返回 overall) export async function checkAVC(): Promise; export async function checkHEVC(): Promise; ``` ## 判定逻辑(思路) 1) WebCodecs 可用性: - `const hasVideoDecoder = typeof window.VideoDecoder !== 'undefined'` - `const secure = isSecureContext` - 若 `!secure || !hasVideoDecoder`:返回 `webCodecs=false`,`avc='unknown'`,`hevc='unknown'` 2) AVC 检查(代表性配置 + 硬解/软解): - 代表性 `codec`:`avc1.42E01E`(Baseline)、`avc1.640028`(High L4.0) - 对每个 `codec` 分别尝试: - `hardwareAcceleration: 'require-hardware'`(硬解) - `hardwareAcceleration: 'require-software'`(软解) - 先调用 `await VideoDecoder.isConfigSupported(config)`;若 `supported: true`,继续创建 `new VideoDecoder({ output, error })` 并执行 `decoder.configure(configWithDims)`: - 为避免不完整配置导致误判,`configWithDims` 需包含最小维度:`codedWidth: 16, codedHeight: 16`,`optimizeForLatency: false` - 若 `configure` 抛错或随后触发 `error` 回调(建议等待 ~300ms),则该路径判定为 `unsupported` - 成功则记录为 `supported` - 若某实现忽略 `hardwareAcceleration`(常见): - 回退策略:尝试 `prefer-hardware`/`prefer-software` 并记录结果为“弱证据”,UI 仍以严格 `require-*` 结果为准;弱证据仅进入 `details` 3) HEVC 检查(代表性配置 + 硬解/软解): - 代表性 `codec`:`hvc1`、`hev1`,以及带 profile-level 的示例:`hvc1.1.6.L93.B0`、`hev1.1.6.L93.B0` - 检查流程同 AVC:分别对硬解/软解进行 `isConfigSupported` 与 `configure` 双重校验,维度与等待策略一致 - 注意:不同平台对 `description` 要求不一;本版默认不提供 `description`,如遇特定浏览器需补充,可在 `details` 记录并作为特例处理 4) 记录详情: - `env`:UA、`isSecureContext`、`hasVideoDecoder` - `checks`:每次调用的 `codec`、`hardwareAcceleration`、阶段(`isConfigSupported`/`configure`)、结果/错误 - `timestamp`:毫秒时间戳 ## 错误处理与未知态 - `isConfigSupported` 可能抛错或返回不明确信息,统一捕获并记录 - 条件不足(如非安全上下文、缺少 API)时标记为 `unknown` - 在 `isConfigSupported` 为真后仍需 `configure`:若抛错或 `error` 回调被触发(在约定时间窗内),则视为“不支持” - 统一在完成检查后 `decoder.close()`,避免资源泄漏 ## 测试计划(开发机验证) - Chrome(Windows/macOS): - WebCodecs 可用;AVC 软件解码支持,硬解由平台驱动与浏览器策略决定;HEVC 通常不支持(硬/软均可能失败) - Safari(macOS/iOS 16+): - WebCodecs 与 HEVC 可能支持;对 HEVC 硬解/软解的结果依平台版本而异;AVC 支持 - Firefox: - WebCodecs 可能不可用;AVC/HEVC 显示未知 ## 验收标准 - `detectAll()` 返回结构符合最新类型定义(含 `CodecDetail` 的硬解/软解与 `overall`) - `details.checks` 对 AVC/HEVC 均包含:硬解(`require-hardware`)与软解(`require-software`)的 `isConfigSupported` 和 `configure` 两阶段记录 - 在上述浏览器场景下,页面能分别展示 H.264/H.265 的“硬解/软解/总体”状态;Safari 的 HEVC 正确反映平台支持;Chrome/Windows 的 HEVC 显示不支持或未知