在Windows

时间:2017-12-30 18:29:41

标签: c++ windows audio windows-10 ms-media-foundation

我正在尝试用C ++修改某些音频文件的元数据,我遇到了[我认为]使用Windows Media Foundation的可能方式。所以我试着整理一个简单的解决方案:

#include <atlbase.h>
#include <mfapi.h>
#include <mfidl.h>
#include <Windows.h>

#pragma comment(lib, "Mf.lib")
#pragma comment(lib, "Mfplat.lib")


int main() {
    HRESULT hr;

    CComPtr<IMFSourceResolver> source_resolver(nullptr);
    if (FAILED(hr = MFCreateSourceResolver(&source_resolver))) {
        // Handle errors...
    }

    MF_OBJECT_TYPE object_type = MF_OBJECT_INVALID;
    CComPtr<IUnknown> source_object(nullptr);
    if (FAILED(hr = source_resolver->CreateObjectFromURL(L"audio_file_here", MF_RESOLUTION_MEDIASOURCE | MF_RESOLUTION_READ | MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE, NULL, &object_type, &source_object))) {
        // Handle errors...
    }

    CComPtr<IMFMediaSource> source(nullptr);
    if (FAILED(hr = source_object->QueryInterface(IID_PPV_ARGS(&source)))) {
        // Handle errors...
    }

    CComPtr<IMFPresentationDescriptor> presentation_descriptor(nullptr);
    if (FAILED(hr = source->CreatePresentationDescriptor(&presentation_descriptor))) {
        // Handle errors...
    }

    CComPtr<IMFMetadataProvider> metadata_prov(nullptr);
    if (FAILED(hr = MFGetService(source, MF_METADATA_PROVIDER_SERVICE, IID_PPV_ARGS(&metadata_prov)))) {
        // Handle errors...
    }

    CComPtr<IMFMetadata> metadata(nullptr);
    if (FAILED(hr = metadata_prov->GetMFMetadata(presentation_descriptor, 0, NULL, &metadata))) {
        // Handle errors...
    }

    /* Use metadata, etc etc */
}

它适用于标准MP3(.mp3)文件,但它总是在AAC(来自iTunes的.m4a)音频文件上失败。具体来说,MFGetService()函数失败,返回值由Visual Studio提供为"The object does not support the specified service."

我不明白为什么会这样。正确here它说媒体基金会支持AAC,Windows肯定支持某种程度,因为我可以通过内置的Groove音乐播放器完美地播放我的AAC文件。
此外,文件元数据也可以通过Windows 以某种方式读取,因为我可以在资源管理器中查看文件的属性,它可以很好地列出标题,艺术家,专辑等。

那么如何从MP3 AAC音频文件中读取和写入元数据?是否可以通过Media Foundation,或者我是否需要Windows API中的其他工具?(我已经看到参考here参与了一个涉及&#34; Windows Shell界面的方法&#34; ,这是要走的路吗?)

1 个答案:

答案 0 :(得分:1)

首先,您的问题实际上与AAC无关。您不在此处执行AAC文件,并且您的文件是MPEG-4文件(通常为.MP4​​,但您的.M4A只是.MP4的变体/别名)。

所以问题是你是否可以使用MF_METADATA_PROVIDER_SERVICE或其他方式使用Media Foundation访问MPEG-4文件的元数据。

请注意,“对AAC或MPEG-4的支持”并不一定意味着元数据管理,因为元数据管理毕竟是辅助功能。

似乎Microsoft已弃用元数据提供程序服务,并且不再为新媒体源提供服务。即使对{。1}}的支持仍然可用于.MP3文件,它也不再适用于.MP4。相反,Microsoft建议使用shell属性处理程序,对于MP4文件,它们可以在内部使用Media Foundation。

请参阅MF_METADATA_PROVIDER_SERVICE for MP4 file

  

要从MP4源获取元数据,您实际上应该从MF_METADATA_PROVIDER_SERVICE服务获取IPropertyStore接口。正在更新MSDN以记录检索元数据的新方法 ...

     

有关信息,请在此处记录标准的Shell属性键:Windows Properties

Shell和资源管理器正好使用此方法来检索元数据。

您还可以使用FilePropertyStore中的there工具快速列出通过shell属性处理程序API提供的属性:

enter image description here