#include <mfapi.h>
#include <mfidl.h>
#include <mfobjects.h>
#include <mfmediaengine.h>
#include <mfplay.h>
#include <mfreadwrite.h>
#include <mferror.h>
#include <windows.h>
#include <atlbase.h>
#include <iostream>
#pragma comment (lib,"Mfplat.lib")
#pragma comment (lib,"Mf.lib")
#pragma comment (lib,"Mfreadwrite.lib")
#pragma comment (lib,"Mfplay.lib")
int mda_main(HWND hWnd) {
// 初始化Media Foundation平台
HRESULT hr = MFStartup(MF_VERSION);
if (FAILED(hr)) {
std::cerr << "Failed to initialize Media Foundation." << std::endl;
return hr;
}
// 创建媒体会话
IMFMediaSession* pSession = NULL;
hr = MFCreateMediaSession(NULL, &pSession);
if (FAILED(hr)) {
std::cerr << "Failed to create media session." << std::endl;
return hr;
}
// 创建源解析器
IMFSourceResolver* pSourceResolver = NULL;
IUnknown* pSource = NULL;
MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID;
IMFMediaSource* pMediaSource = NULL;
hr = MFCreateSourceResolver(&pSourceResolver);
if (FAILED(hr)) {
std::cerr << "Failed to create source resolver." << std::endl;
return hr;
}
// 从URL创建媒体源
hr = pSourceResolver->CreateObjectFromURL(
L"G:\\HERO.mp3", // 音频文件路径
MF_RESOLUTION_MEDIASOURCE,
NULL,
&ObjectType,
&pSource
);
if (FAILED(hr)) {
std::cerr << "Failed to create media source from URL." << std::endl;
return hr;
}
hr = pSource->QueryInterface(IID_PPV_ARGS(&pMediaSource));
if (FAILED(hr)) {
std::cerr << "Failed to query media source interface." << std::endl;
return hr;
}
// 创建拓扑
IMFTopology* pTopology = NULL;
hr = MFCreateTopology(&pTopology);
if (FAILED(hr)) {
std::cerr << "Failed to create topology." << std::endl;
return hr;
}
// 创建演示描述符
IMFPresentationDescriptor* pPresentationDescriptor = NULL;
hr = pMediaSource->CreatePresentationDescriptor(&pPresentationDescriptor);
if (FAILED(hr)) {
std::cerr << "Failed to create presentation descriptor." << std::endl;
return hr;
}
DWORD cStreams = 0;
hr = pPresentationDescriptor->GetStreamDescriptorCount(&cStreams);
if (FAILED(hr)) {
std::cerr << "Failed to get stream descriptor count." << std::endl;
return hr;
}
for (DWORD i = 0; i < cStreams; i++) {
// 获取流描述符
IMFStreamDescriptor* pStreamDescriptor = NULL;
BOOL fSelected = FALSE;
hr = pPresentationDescriptor->GetStreamDescriptorByIndex(i, &fSelected, &pStreamDescriptor);
if (FAILED(hr)) {
std::cerr << "Failed to get stream descriptor by index." << std::endl;
return hr;
}
if (fSelected) {
// 创建源节点
IMFTopologyNode* pSourceNode = NULL;
hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &pSourceNode);
if (FAILED(hr)) {
std::cerr << "Failed to create source node." << std::endl;
return hr;
}
hr = pSourceNode->SetUnknown(MF_TOPONODE_SOURCE, pMediaSource);
if (FAILED(hr)) {
std::cerr << "Failed to set source on source node." << std::endl;
return hr;
}
hr = pSourceNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPresentationDescriptor);
if (FAILED(hr)) {
std::cerr << "Failed to set presentation descriptor on source node." << std::endl;
return hr;
}
hr = pSourceNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, pStreamDescriptor);
if (FAILED(hr)) {
std::cerr << "Failed to set stream descriptor on source node." << std::endl;
return hr;
}
hr = pTopology->AddNode(pSourceNode);
if (FAILED(hr)) {
std::cerr << "Failed to add source node to topology." << std::endl;
return hr;
}
// 创建输出节点
IMFTopologyNode* pOutputNode = NULL;
hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pOutputNode);
if (FAILED(hr)) {
std::cerr << "Failed to create output node." << std::endl;
return hr;
}
IMFActivate* pRendererActivate = NULL;
hr = MFCreateAudioRendererActivate(&pRendererActivate);
if (FAILED(hr)) {
std::cerr << "Failed to create audio renderer activate." << std::endl;
return hr;
}
hr = pOutputNode->SetObject(pRendererActivate);
if (FAILED(hr)) {
std::cerr << "Failed to set object on output node." << std::endl;
return hr;
}
hr = pTopology->AddNode(pOutputNode);
if (FAILED(hr)) {
std::cerr << "Failed to add output node to topology." << std::endl;
return hr;
}
// 连接节点
hr = pSourceNode->ConnectOutput(0, pOutputNode, 0);
if (FAILED(hr)) {
std::cerr << "Failed to connect nodes." << std::endl;
return hr;
}
pStreamDescriptor->Release();
}
}
hr = pSession->SetTopology(0, pTopology);
if (FAILED(hr)) {
std::cerr << "Failed to set topology on session." << std::endl;
return hr;
}
// 开始播放
PROPVARIANT varStart;
PropVariantInit(&varStart);
hr = pSession->Start(&GUID_NULL, &varStart);
if (FAILED(hr)) {
std::cerr << "Failed to start session." << std::endl;
return hr;
}
// 等待播放完成
IMFMediaEvent* pEvent = NULL;
while (true) {
hr = pSession->GetEvent(0, &pEvent);
if (FAILED(hr)) {
std::cerr << "Failed to get session event." << std::endl;
return hr;
}
MediaEventType meType;
hr = pEvent->GetType(&meType);
if (FAILED(hr)) {
std::cerr << "Failed to get event type." << std::endl;
return hr;
}
if (meType == MESessionEnded) {
std::cout << "Playback ended." << std::endl;
break;
}
pEvent->Release();
}
// 清理资源
pSession->Close();
pSource->Release();
pSourceResolver->Release();
pMediaSource->Release();
pPresentationDescriptor->Release();
pTopology->Release();
pSession->Release();
MFShutdown();
return 0;
}
Media Foundation播放音频
最新推荐文章于 2024-07-29 14:29:21 发布