如何使用Media Foundation播放受保护的MP4内容?
使用Media Foundation播放受保护MP4文件的问题求助
我正尝试用Media Foundation播放MP4文件,按照官方文档可以正常播放未受保护的文件,但播放受保护文件时始终失败。根据播放受保护文件的官方文档说明,这类文件需要额外操作才能播放。我使用了微软PlayReady测试页面提供的前两个MP4测试文件(Media Foundation本应兼容微软自有DRM系统),但无论如何调整操作,播放受保护MP4都会报错MF_E_UNSUPPORTED_BYTESTREAM_TYPE。
失败发生在MESessionTopologySet事件触发期间,而且我实现的IMFContentProtectionManager仅在QueryInterface()时被调用过一次。当前环境是Windows 10系统,请问该如何正确使用Media Foundation播放受保护MP4文件?
以下是我使用的代码:
// initialization HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); hr = MFStartup(MF_VERSION); // load source IMFSourceResolver* SourceResolver = NULL; hr = MFCreateSourceResolver(&SourceResolver); MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID; IUnknown* Object = NULL; hr = SourceResolver->CreateObjectFromURL(L"tearsofsteel_1080p_60s_24fps.6000kbps.1920x1080.h264-8b.2ch.128kbps.aac.avsep.cenc.mp4", MF_RESOLUTION_MEDIASOURCE | MF_RESOLUTION_READ, NULL, &ObjectType, &Object); IMFMediaSource* MediaSource = NULL; hr = Object->QueryInterface(&MediaSource); IMFPresentationDescriptor* PresentationDescriptor = NULL; hr = MediaSource->CreatePresentationDescriptor(&PresentationDescriptor); hr = MFRequireProtectedEnvironment(PresentationDescriptor); wprintf_s(L"MFRequireProtectedEnvironment() hr=0x%.08X\n", hr); // get first stream IMFStreamDescriptor* StreamDescriptor = NULL; BOOL Selected = FALSE; hr = PresentationDescriptor->GetStreamDescriptorByIndex(0, &Selected, &StreamDescriptor); IMFMediaTypeHandler* MediaTypeHandler = NULL; hr = StreamDescriptor->GetMediaTypeHandler(&MediaTypeHandler); GUID MajorType = GUID_NULL; hr = MediaTypeHandler->GetMajorType(&MajorType); // create appropriate renderer IMFActivate* Activate = NULL; if (MajorType == MFMediaType_Video) { hr = MFCreateVideoRendererActivate(NULL, &Activate); } else if (MajorType == MFMediaType_Audio) { hr = MFCreateAudioRendererActivate(&Activate); } // build the topology IMFTopology* Topology = NULL; hr = MFCreateTopology(&Topology); // build the source node IMFTopologyNode* SourceTopologyNode = NULL; hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &SourceTopologyNode); hr = SourceTopologyNode->SetUnknown(MF_TOPONODE_SOURCE, MediaSource); hr = SourceTopologyNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, PresentationDescriptor); hr = SourceTopologyNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, StreamDescriptor); hr = Topology->AddNode(SourceTopologyNode); // build the output node IMFTopologyNode* OutputTopologyNode = NULL; hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &OutputTopologyNode); hr = OutputTopologyNode->SetObject(Activate); hr = OutputTopologyNode->SetUINT32(MF_TOPONODE_STREAMID, 0); hr = OutputTopologyNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE); hr = Topology->AddNode(OutputTopologyNode); hr = SourceTopologyNode->ConnectOutput(0, OutputTopologyNode, 0); // create the protected session IMFMediaSession* MediaSession = NULL; IMFAttributes* Configuration = NULL; hr = MFCreateAttributes(&Configuration, 1); IUnknown* ContentProtectionManager = new ContentProtectionManagerImpl(); Configuration->SetUnknown(MF_SESSION_CONTENT_PROTECTION_MANAGER, ContentProtectionManager); IMFActivate* EnablerActivate = NULL; hr = MFCreatePMPMediaSession(0, Configuration, &MediaSession, &EnablerActivate); // set the topology hr = MediaSession->SetTopology(0, Topology); // get the event status IMFMediaEvent* Event = NULL; hr = MediaSession->GetEvent(0, &Event); MediaEventType Type = MEUnknown; hr = Event->GetType(&Type); HRESULT Status = S_OK; hr = Event->GetStatus(&Status); wprintf_s(L"Event Type=%d Status=0x%.08X\n", Type, Status);
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

