【问题标题】:can't add audio stream to MP4 file using sinkwriter from Media Foundation无法使用 Media Foundation 的 sinkwriter 将音频流添加到 MP4 文件
【发布时间】:2014-08-04 23:53:18
【问题描述】:

我已经一个星期没有尝试让我的编码器工作了......

所以事情是这样的:

  1. 我使用 MF 的 Sink Writer 创建了一个文件。

  2. 我写了我所有的视频样本。

    -->(如果我停在那里并调用 Finish 方法,我可以使用 VLC 读取文件,但如果我执行以下操作,文件将被“损坏”)

  3. 我写了我所有的音频样本。

  4. 我调用了完成函数,我得到一个 HRESULT 代码:“接收器无法创建有效的输出文件,因为没有向接收器提供所需的标头”。我完全理解这个错误,只是我不知道如何解决它......

如果你们需要任何代码,我很乐意把它放在这里。

【问题讨论】:

    标签: c++ audio mp4 h.264 ms-media-foundation


    【解决方案1】:

    我第一次开始使用 MP4 容器时遇到了这个确切的错误(在完成接收器时)。

    错误 0xC00D4A45:接收器无法创建有效的输出文件,因为 未向接收器提供所需的标头。

    您没有提及您为接收器提供的音频样本的子类型,也没有提及添加的音频流的子类型(用于输出),但我相信您的问题与后者有关。

    使用媒体基础开发,MP4 容器最容易使用MFAudioFormat_AACMFAudioFormat_MP3 进行配置。如果您在此link 查看MP4 File Sink 的详细信息,您将看到接收器可以生成以下格式的示例描述框(stsd):

    - H.264/AVC video
    - AAC audio
    - MP3 audio
    

    可以使用其他一些格式,但是在创建接收器之前配置属性时,您必须使用MF_MT_MPEG4_SAMPLE_DESCRIPTION GUID 手动提供示例描述框 (stsd) 描述。这是使用以下函数完成的:

    // IMFAttributes::SetBlob
    attributes->SetBlob(MF_MT_MPEG4_SAMPLE_DESCRIPTION, buffer, buffer_size);
    

    但是,如MP4 File Source here 所述,可以使用的其他类型很少。在媒体类型下,有一个包含各种允许类型的表格。除了前面提到的 AAC/MP3 之外,剩下的音频类型很少,没有一个是非常有吸引力的选择。你会发现坚持MFAudioFormat_AACMFAudioFormat_MP3 对你有好处。

    希望这会有所帮助。

    编辑:

    如果您选择使用AACMP3 以外的音频子类型,并使用IMFAttributes::SetBlob 提供MF_MT_MPEG4_SAMPLE_DESCRIPTION 配置,则示例描述框 (stsd) 为在this answer 中描述。正如该答案所述,这些框是嵌套的。

    关于音频,例如,如果您选择MFAudioFormat_PCMMP4 File Source媒体类型部分列出 5 个条目。因此,在构建示例描述框时,请使用适当的示例条目代码('raw'、'sowt'、'twos'、'NONE'、0x00)。请注意“原始”中的空格。高层总结如下:

    //  'raw '  Audio   MFAudioFormat_PCM   8-bit PCM audio
    //  'sowt'  Audio   MFAudioFormat_PCM   16-bit little-endian PCM audio
    //  'twos'  Audio   MFAudioFormat_PCM   16-bit big-endian PCM audio
    //  'NONE'  Audio   MFAudioFormat_PCM   8-bit or 16-bit big-endian PCM audio
    //   0x00   Audio   MFAudioFormat_PCM   8-bit or 16-bit big-endian PCM audio
    

    您还可以找到these registered codecs interesting

    【讨论】:

    • 谢谢你,我现在没有我的项目,但我以后一定会尝试的。只是一个询问,你能解释一下你是如何初始化和设置“缓冲区”的吗? attributes->SetBlob(MF_MT_MPEG4_SAMPLE_DESCRIPTION, buffer, buffer_size);
    • 当然可以。您打算使用什么类型的音频?我将使用您的音频子类型格式化示例。
    • 我会选择 MFAudioFormat_AAC,我发现它总体上质量更好。我现在有 PCM 格式的音频,但我认为它很容易转换
    • 如果您使用 MFAudioFormat_AAC,则不需要 IMFAttributes::SetBlob,因为接收器可以自动生成描述(如上所述)。对于基本配置,选择采样率为 44100、16 bps 和 2 个通道的子类型。但任何 AAC 选择都将顺利完成,无需 IMFAttributes::SetBlob。
    • 嗯,好的,如果我想直接使用 WAV PCM 怎么办?这可能吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多