package transcode import "context" // Request 是一次转码请求(design/25 §2.1)。 type Request struct { // Data 是源字节。 Data []byte // Source 是源格式;可留空,留空时按魔数嗅探,嗅不出即 ErrUnsupportedFormat // (deny-by-default)。 Source Format // Target 是目标格式;留空即 ErrUnsupportedFormat。 Target Format } // Result 是转码结果(design/25 §2.1)。 type Result struct { // Data 是目标字节。 Data []byte // Format 是目标格式(= Request.Target)。 Format Format // Source 是实际识别到的源格式(回给调用方,便于日志与 DTO)。 Source Format // SampleRate 是采样率(Hz);能确定时给出,否则 0。 SampleRate int // Channels 是声道数;能确定时给出,否则 0。 Channels int // DurationMs 是时长;能从容器/帧数**确证**时给出,否则 0(绝不估算, // 与 design/24 §10.4 的 durationMs 纪律同源)。 DurationMs int64 // Frames 是已解码帧数(AMR-NB 一帧 20ms = 160 样本);不适用时 0。 Frames int } // Transcoder 是转码能力对外的唯一接口:**进程内、同步、纯本地** // (不触网、不落盘、不查库)。实例由组合根构造并经依赖注入交给调用方, // 绝不设包级全局变量(design/25 §1.3.2 / AGENTS §10 红线)。 type Transcoder interface { // Transcode 把 req.Data 从 req.Source 转成 req.Target。失败一律返回 // errors.go 的哨兵之一(或包裹它),绝不返回部分结果假装成功。 Transcode(ctx context.Context, req Request) (Result, error) // Supports 报告这条路是否可用(能力门;调用方据此决定走原生路径还是诚实拒绝)。 Supports(src, dst Format) bool // Formats 报告当前注册的所有格式(发现;顺序无保证)。 Formats() []Format } // Codec 是一条「源→目标」转换路(design/25 §2.2)。实现必须是**纯函数**: // 给定相同输入产出相同输出,不读写外部状态、不发网络请求、不做缓存 // (缓存若需要,由调用方按内容寻址去做)。 type Codec interface { // From 返回源格式。 From() Format // To 返回目标格式。 To() Format // Transcode 转换 in 并返回结果。它必须自己执行「本格式可确证」的上限 // (时长、产物字节),并在循环内遵守 ctx;engine 负责的是与格式无关的 // 那一层(输入字节上限、并发槽、超时闸、日志)。 Transcode(ctx context.Context, in []byte, limits Limits) (Result, error) }