使用 Sink Writer 编码音频

Posted

技术标签:

【中文标题】使用 Sink Writer 编码音频【英文标题】:Encode Audio using Sink Writer 【发布时间】:2016-11-05 15:19:51 【问题描述】:

我发现 this 文章解释了如何使用 Media Foundation 对视频进行编码。

我正在尝试使用上述链接中使用的原理对音频进行编码。

我一直在为接收器编写器设置正确的输入媒体类型。

这是那部分:

if (SUCCEEDED(hr))
    hr = MFCreateMediaType(&pMediaTypeIn);

if (SUCCEEDED(hr))
    hr = pMediaTypeIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);

if (SUCCEEDED(hr))
    hr = pMediaTypeIn->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_Float);

if (SUCCEEDED(hr))
    hr = pMediaTypeIn->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, cChannels);

if (SUCCEEDED(hr))
    hr = pMediaTypeIn->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, sampleRate);

if (SUCCEEDED(hr))
    hr = pSinkWriter->SetInputMediaType(streamIndex, pMediaTypeIn, NULL);

我的代码在设置输入媒体类型时在最后一行失败。

任何帮助,如何处理?

谢谢。

【问题讨论】:

您是如何创建 SinkWriter 的?您是否尝试过使用 MFAudioFormat_PCM? MFCreateSinkWriterFromURL(L"output.m4a", NULL, NULL, &pSinkWriter);是的,我尝试过 PCM 和 Float。无法设置 我认为您还需要在媒体类型中提供 MF_MT_AUDIO_BITS_PER_SAMPLE。它必须设置为 16。在此处检查输入类型要求:msdn.microsoft.com/en-us/library/windows/desktop/… 采样率必须是 44100 或 48000。子类型必须是 MFAudioFormat_PCM。 MFCreateSinkWriterFromURL 可能无法猜测您需要从 m4a 扩展编码到 mp4 容器。在调用 MFCreateSinkWriterFromURL 时,您可能需要使用 MF_TRANSCODE_CONTAINERTYPE 属性提供 MFTranscodeContainerType_MPEG4 包含类型。另一种选择是改用 MFCreateMPEG4MediaSink 和 MFCreateSinkWriterFromMediaSink。 最重要的是,如果您需要编码,您需要在调用 SetMediaType 之前调用 Sink Writer 上的 AddStream,并使用通过调用 MFTranscodeGetAudioOutputAvailableTypes 函数枚举的输出音频类型和 MFAudioFormat_AAC 子类型音频为 AAC。 【参考方案1】:

您还需要在媒体类型中提供 MF_MT_AUDIO_BITS_PER_SAMPLE。它必须设置为 16。在此处检查输入类型要求:https://msdn.microsoft.com/en-us/library/windows/desktop/dd742785(v=vs.85).aspx。采样率必须是 44100 或 48000。子类型必须是 MFAudioFormat_PCM。

最重要的是,如果您需要将音频编码为 AAC,则需要在调用 SetMediaType 之前调用 Sink Writer 上的 AddStream,并使用通过调用具有 MFAudioFormat_AAC 子类型的 MFTranscodeGetAudioOutputAvailableTypes 函数枚举的输出音频类型。

MFCreateSinkWriterFromURL 可能无法猜测您需要从 m4a 扩展编码到 mp4 容器。在调用 MFCreateSinkWriterFromURL 时,您可能需要使用 MF_TRANSCODE_CONTAINERTYPE 属性提供 MFTranscodeContainerType_MPEG4 包含类型。另一种选择是改用 MFCreateMPEG4MediaSink 和 MFCreateSinkWriterFromMediaSink。

【讨论】:

只有一条评论。 MFCreateSinkWriterFromURL 能够从输出名称中猜出正确的容器。

以上是关于使用 Sink Writer 编码音频的主要内容,如果未能解决你的问题,请参考以下文章

MF Sink Writer 的内存泄漏

flinkflink写入clickhouse Error while starting CH writer AccessDeninedExcepton

Java IO_003.Reader与Writer--字符流以及编码对数据的操作(读取与写入)

如何将 Reader 转换为 InputStream 并将 Writer 转换为 OutputStream?

Go编程技巧--io.Reader/Writer

JavaXML编码