采用Class继承重构音视频解码器,定义BaseDecoder基类声明抽象方法、封装公共字段并提供默认实现;各格式子类(FFmpegDecoder、ExoDecoder等)专注自身逻辑;工厂类统一实例化并收口错误处理、资源管理和线程安全。

直接用现代 Class 继承语法重构音视频播放器的多格式解码器,核心是把不同解码逻辑抽象成统一接口,再让各格式实现类继承并覆盖关键方法。不追求“一次性全换”,而是从解码流程的共性切入,逐步替换旧式工厂或条件分支代码。
定义统一解码器基类
基类不处理具体格式,只声明必须实现的行为和共享状态:
- 声明抽象方法:
init()、decodeFrame()、seekTo()、close() - 封装公共字段:如
url、isPrepared、durationMs、onError回调 - 提供默认实现:
getVideoSize()返回{ width: 0, height: 0 },getProgress()基于已解帧数与总帧数估算
为每种格式创建继承类
每个子类只专注自身格式的细节,不感知其他格式存在:
-
FFmpegDecoder:调用avcodec_open2和avcodec_send_packet,支持MP4/AVI/MKV等容器内H.264、HEVC、AV1 -
ExoDecoder:包装MediaCodecRenderer,适配DASH/HLS流,利用MediaSource和LoadControl管理缓冲 -
IJKDecoder:继承自FFmpegDecoder,复用底层解码,仅重写init()加载定制版libijkffmpeg.so -
WebAudioDecoder(纯音频):基于AudioContext.decodeAudioData,处理MP3/WAV/AAC,跳过视频渲染链路
用工厂类统一实例化
避免在业务层写if (ext === 'mp4') new FFmpegDecoder()这类硬编码:
- 工厂接收文件路径或MIME类型,通过
probe(如读取前8字节或调用ffprobe轻量分析)识别格式 - 返回对应子类实例,类型为
BaseDecoder,上层只调用start()和pause()等基类方法 - 可配合依赖注入容器(如
inversify)注册不同策略,便于测试时替换MockDecoder
关键重构点提醒
真正影响长期维护的是这三处设计选择:
- 错误处理统一收口:所有子类抛出
DecoderError子类(如FormatNotSupportedError、HardwareDecodeFailedError),上层只监听一个onError事件 - 生命周期与资源绑定:基类
close()自动释放AVCodecContext或MediaCodec,子类在super.close()前后清理私有资源 - 线程安全边界清晰:基类不假设调用线程,所有
decodeFrame()执行在子类自己管理的解码线程中,主线程只负责控制指令下发



















