如何設定播放停止時間

本主題描述如何使用媒體會話來設定播放的停止時間。

設定播放開始前的停止時間

在將拓撲排入佇列以供播放之前,您可以使用 MF_TOPONODE_MEDIASTOP 屬性來指定停止時間。 針對拓撲中的每個輸出節點,將 MF_TOPONODE_MEDIASTOP 的值設定為 100 奈秒單位的停止時間。

請注意,在播放開始之後設定此屬性沒有任何作用。 因此,請先設定 屬性,再呼叫IMFMediaSession::Start

下列程式代碼示範如何在現有的拓撲上設定停止時間。

template <class Q>
HRESULT GetCollectionObject(IMFCollection *pCollection, DWORD dwIndex, Q **ppObject)
{
    *ppObject = NULL;   // zero output

    IUnknown *pUnk = NULL;
    HRESULT hr = pCollection->GetElement(dwIndex, &pUnk);
    if (SUCCEEDED(hr))
    {
        hr = pUnk->QueryInterface(IID_PPV_ARGS(ppObject));
        pUnk->Release();
    }
    return hr;
}

HRESULT SetMediaStop(IMFTopology *pTopology, const LONGLONG& stop)
{
    IMFCollection *pCol = NULL;
    DWORD cNodes;

    HRESULT hr = pTopology->GetSourceNodeCollection(&pCol);
    if (SUCCEEDED(hr))
    {
        hr = pCol->GetElementCount(&cNodes);
    }
    if (SUCCEEDED(hr))
    {
        for (DWORD i = 0; i < cNodes; i++)
        {
            IMFTopologyNode *pNode;
            hr = GetCollectionObject(pCol, i, &pNode);
            if (SUCCEEDED(hr))
            {
                pNode->SetUINT64(MF_TOPONODE_MEDIASTOP, stop);
            }
            pNode->Release();
        }
    }
    SafeRelease(&pCol);
    return hr;
}

設定播放開始后的停止時間

您可以使用 IMFTopologyNodeAttributeEditor 介面,在媒體會話開始播放之後設定停止時間。

重要

這個介面有嚴重的限制,因為停止時間會指定為32位值。 這表示您可以使用這個介面設定的最大停止時間是0xFFFFFFFF,或僅超過 7 分鐘。 這項限制是因為結構定義不正確。

 

若要使用 IMFTopologyNodeAttributeEditor 介面設定停止時間,請執行下列步驟。

  1. 呼叫 MFGetService 以從媒體會話取得 IMFTopologyNodeAttributeEditor 介面。

  2. 呼叫 IMFTopology::GetTopologyID 以取得播放拓撲的標識碼。

  3. 針對拓撲中的每個輸出節點,呼叫 IMFTopologyNodeAttributeEditor::UpdateNodeAttributes 此方法會採用拓撲標識碼和MFTOPONODE_ATTRIBUTE_UPDATE結構的指標 初始化 結構,如下所示。

    member
    NodeId 節點標識碼。 若要取得節點標識符,請呼叫 IMFTopologyNode::GetTopoNodeID
    guidAttributeKey MF_TOPONODE_MEDIASTOP
    attrType MF_ATTRIBUTE_UINT64
    u64 停止時間,以 100 奈秒為單位。

     

請小心正確設定 attrType 的值。 雖然 u64 是 32 位類型,但方法會要求 attrType 設定為 MF_ATTRIBUTE_UINT64

下列程式代碼顯示這些步驟。

HRESULT SetMediaStopDynamic(IMFMediaSession *pSession, IMFTopology *pTopology, const LONGLONG& stop)
{
    if (stop > MAXUINT32)
    {
        return E_INVALIDARG;
    }

    IMFTopologyNodeAttributeEditor *pAttr = NULL;
    IMFCollection *pCol = NULL;
    IMFTopologyNode *pNode = NULL;

    HRESULT hr = MFGetService(pSession, MF_TOPONODE_ATTRIBUTE_EDITOR_SERVICE, IID_PPV_ARGS(&pAttr));
    if (FAILED(hr))
    {
        goto done;
    }

    TOPOID id;
    hr = pTopology->GetTopologyID(&id);
    if (FAILED(hr))
    {
        goto done;
    }

    DWORD cNodes;
    hr = pTopology->GetSourceNodeCollection(&pCol);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pCol->GetElementCount(&cNodes);
    if (FAILED(hr))
    {
        goto done;
    }

    for (DWORD i = 0; i < cNodes; i++)
    {
        IMFTopologyNode *pNode;
        hr = GetCollectionObject(pCol, i, &pNode);
        if (FAILED(hr))
        {
            goto done;
        }

        TOPOID nodeID;
        hr = pNode->GetTopoNodeID(&nodeID);
        if (FAILED(hr))
        {
            goto done;
        }

        MFTOPONODE_ATTRIBUTE_UPDATE update;
        update.NodeId = nodeID;
        update.guidAttributeKey = MF_TOPONODE_MEDIASTOP;
        update.attrType = MF_ATTRIBUTE_UINT64;
        update.u64 = (UINT32)stop;

        hr = pAttr->UpdateNodeAttributes(id, 1, &update);
        if (FAILED(hr))
        {
            goto done;
        }
        SafeRelease(&pNode);
    }

done:
    SafeRelease(&pNode);
    SafeRelease(&pCol);
    SafeRelease(&pAttr);
    return hr;
}

音訊/視訊播放