DCSIMG
More Media Info with Media Foundation - Pavel's Blog
Sign in | Join | Help

Pavel's Blog

Pavel is a software guy that is interested in almost everything
software related... way too much for too little time

More Media Info with Media Foundation

Getting information on media files is possible through Media Foundation, as we’ve seen, using the various “descriptors”. If we look at Windows Explorer, we can see other information presented, such as artist, title and other metadata. This information is also accessible through media foundation, without resorting to the (mostly) dreadful shell API.

To get to these properties, we can query the media source for the IMFGetService, which is conceptually similar to IServiceProvider used in various APIs – that is, an interface that allows getting another interface that is easier to implement as a separate object. We’ll query for the MF_PROPERTY_HANDLER_SERVICE service type and look for the IPropertyStore interface. We can do this more fluently using the MFGetService helper.

With an IPropertyStore pointer in hand, we can query various properties (the full list is here).

And in code:

CComPtr<IMFSourceResolver> spResolver;
CHECK_HR(::MFCreateSourceResolver(&spResolver));
MF_OBJECT_TYPE type;
CComPtr<IUnknown> spUnkSource;
CHECK_HR(spResolver->CreateObjectFromURL(url, MF_RESOLUTION_MEDIASOURCE, NULL, &type, &spUnkSource));
CComQIPtr<IMFMediaSource> spSource(spUnkSource);
 
CComPtr<IPropertyStore> spStore;
CHECK_HR(::MFGetService(spSource, MF_PROPERTY_HANDLER_SERVICE, __uuidof(IPropertyStore), (void**)&spStore));
 
PROPVARIANT value;
if(SUCCEEDED(spStore->GetValue(PKEY_Title, &value)) && value.pwszVal) {
	wcout << "Title: " << value.pwszVal << endl;
	::PropVariantClear(&value);
}
if(SUCCEEDED(spStore->GetValue(PKEY_Author, &value)) && value.pwszVal) {
	wcout << "Author: " << value.pwszVal << endl;
	::PropVariantClear(&value);
}
if(SUCCEEDED(spStore->GetValue(PKEY_Audio_Format, &value)) && value.pwszVal) {
	wcout << "Audio Format: " << value.pwszVal << endl;
	::PropVariantClear(&value);
}
if(SUCCEEDED(spStore->GetValue(PKEY_Audio_ChannelCount, &value)) && value.intVal) {
	cout << "# Audio channels: " << value.intVal << endl;
}
if(SUCCEEDED(spStore->GetValue(PKEY_Audio_EncodingBitrate, &value)) && value.intVal) {
	cout << "Average bitrate: " << (value.intVal >> 10) << " kbps" << endl;
}
if(SUCCEEDED(spStore->GetValue(PKEY_Audio_SampleRate, &value))) {
	cout << "Samples/sec: " << value.intVal << endl;
}
if(SUCCEEDED(spStore->GetValue(PKEY_Audio_SampleSize, &value)) && value.intVal) {
	cout << "Bits/sample: " << value.intVal << endl;
}
 
if(SUCCEEDED(spStore->GetValue(PKEY_Video_FrameRate, &value)) && value.intVal) {
	cout << "Video frame rate: " << value.uintVal / 1000 << " fps" << endl;
}
if(SUCCEEDED(spStore->GetValue(PKEY_Video_FrameWidth, &value)) && value.intVal) {
	PROPVARIANT height;
	spStore->GetValue(PKEY_Video_FrameHeight, &height);
	cout << "Video frame size: " << value.intVal << " X " << height.intVal << endl;
}
if(SUCCEEDED(spStore->GetValue(PKEY_Video_Director, &value)) && value.pwszVal) {
	wcout << "Director: " << value.pwszVal << endl;
	::PropVariantClear(&value);
}

Those are just some of the properties we can query. It’s also possible to enumerate all the properties in the IPropertyStore using IPropertyStore::GetCount and IPropertyStore::GetAt, displaying their names and values.

Try it on some media files!

Comments List

No Comments

Leave a Comment

(required) 
(
required
)
 
(optional)
(required) 

Enter the numbers above: