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:
我正在尝试用 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: