如何設定播放停止時間
本主題描述如何使用媒體會話來設定播放的停止時間。
設定播放開始前的停止時間
在將拓撲排入佇列以供播放之前,您可以使用 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 介面設定停止時間,請執行下列步驟。
呼叫 MFGetService 以從媒體會話取得 IMFTopologyNodeAttributeEditor 介面。
呼叫 IMFTopology::GetTopologyID 以取得播放拓撲的標識碼。
針對拓撲中的每個輸出節點,呼叫 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;
}
相關主題