2025-11-12 14:49:07 +08:00

103 lines
5.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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<CodecSupport>;
export async function checkAVCDetail(): Promise<CodecDetail>;
export async function checkHEVCDetail(): Promise<CodecDetail>;
// 可选:保留聚合态接口(返回 overall
export async function checkAVC(): Promise<CodecStatus>;
export async function checkHEVC(): Promise<CodecStatus>;
```
## 判定逻辑(思路)
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()`,避免资源泄漏
## 测试计划(开发机验证)
- ChromeWindows/macOS
- WebCodecs 可用AVC 软件解码支持硬解由平台驱动与浏览器策略决定HEVC 通常不支持(硬/软均可能失败)
- SafarimacOS/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 显示不支持或未知