Reading/writing Windows 中的各种音频文件元数据

Reading/writing various audio file metadata in Windows

我正在尝试用 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 给出的 return 值为 "The object does not support the specified service."

我不明白为什么会这样。对 here 它说 Media Foundation 支持 AAC,并且 Windows 肯定支持它 不知何故 ,因为我可以通过 in-built 完美播放我的 AAC 文件Groove 音乐播放器。
此外,文件元数据也可以通过 Windows 以某种方式 读取,因为我可以在资源管理器中查看文件的属性,其中列出了标题、艺术家、专辑等美好的。

那么如何从 MP3 AAC 音频文件读取和写入元数据?是否可以通过 Media Foundation 实现,或者我是否需要 Windows API 中的其他工具?(我已经看到 here 对涉及 "Windows Shell interface" 的方法的引用,是这条路要走吗?)

首先,您的问题实际上与AAC无关。您不在此处处理 AAC 文件,您的文件是 MPEG-4 文件(通常是 .MP4,但您的 .M4A 只是 .MP4 的 variant/alias)。

  • What is the difference between M4A and AAC Audio Files?

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

请注意,"support for AAC or MPEG-4"并不一定意味着元数据管理,因为元数据管理毕竟是一种辅助功能。

Microsoft 似乎弃用了元数据提供程序服务,并且不再为新媒体源提供它。尽管对 MF_METADATA_PROVIDER_SERVICE 的支持仍可用于 .MP3 文件,但不再为 .MP4 提供。相反,Microsoft 建议使用 shell 属性 处理程序,对于 MP4 文件,内部求助于 Media Foundation。

MF_METADATA_PROVIDER_SERVICE for MP4 file:

To get metadata from the MP4 source you should actually get the IPropertyStore interface from the MF_PROPERTY_HANDLER_SERVICE service. MSDN is being updated to document this new method of retrieving metadata...

For info, the standard Shell property keys are documented here: Windows Properties.

Shell 和 explorer 正是使用这种方法来检索元数据。

您还可以使用 FilePropertyStore tool from there 快速列出通过 shell 属性 处理程序可用的属性 API: