Media Foundation播放音频

#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;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值