MediaFoundation 如何直接从采集设备将音频编码为MP3并输出到字节流
MediaFoundation 音频PCM转MP3实现方案
适用性说明
MediaFoundation是实现该需求的最优原生WinAPI选择,Win7及以上系统原生内置MP3编码器,无需引入第三方依赖,完全支持内存级编码输出适配网络传输场景,比老旧的DirectShow接口更易维护。
推荐最简实现流程(基于SinkWriter,无需手动处理MediaSink和MFT逻辑)
你已经拿到完整PCM Wave缓冲区的场景下,用SinkWriter方案开发量最低:
- 第一步:初始化MediaFoundation环境,调用
MFStartup(MF_VERSION, 0) - 第二步:创建内存
IMFByteStream用于接收编码后的MP3数据,无需落地到磁盘:
可以通过MFCreateMFByteStreamOnStreamEx绑定系统IStream内存对象,也可以使用MFCreateDynamicBuffer创建可动态扩容的内存缓冲区后关联为字节流 - 第三步:创建SinkWriter实例,调用
MFCreateSinkWriterFromByteStream,将第一步创建的内存字节流传入,指定输出容器类型为MP3 - 第四步:配置SinkWriter的媒体类型:
- 先配置输出媒体类型:主类型设为
MFMediaType_Audio,子类型设为MFAudioFormat_MP3,按需设置采样率、声道数、编码比特率参数 - 再配置输入媒体类型:主类型设为
MFMediaType_Audio,子类型设为MFAudioFormat_PCM,参数和你拿到的PCM缓冲区参数(位深度、采样率、声道数)完全匹配 - 调用
AddStream和SetInputMediaType完成流配置
- 先配置输出媒体类型:主类型设为
- 第五步:喂入PCM数据:将你的PCM缓冲区按帧封装为
IMFSample对象,为每个Sample设置正确的时间戳和持续时间(可通过采样率计算,单位为100纳秒),调用WriteSample喂入SinkWriter - 第六步:所有PCM数据喂入完成后,调用
Finalize()方法完成编码,此时内存字节流中已存储完整的MP3二进制数据,可直接取出用于网络传输。
可选灵活实现方案(直接调用MP3编码器MFT)
如果你需要边采集边编码、实时输出的场景,可以直接操作MP3编码器MFT:
- 调用
MFTEnumEx枚举获取MP3编码器的IMFTransform接口实例 - 分别设置输入媒体类型(PCM格式)和输出媒体类型(MP3格式)
- 循环将PCM样本喂入
ProcessInput接口,再调用ProcessOutput获取编码后的MP3样本,攒齐后即为完整MP3数据
MediaSink相关疑问说明
MP3 MediaSink已经被SinkWriter封装了内部逻辑,普通场景下不需要手动创建和维护MediaSink实例,也不用处理MediaSink和SourceReader的适配逻辑,直接用SinkWriter即可覆盖绝大多数编码需求。
内容的提问来源于stack exchange,提问作者GreatestSpoil
相关产品推荐
相关产品推荐

