如何设置播放停止时间
本主题介绍如何在使用媒体会话时设置播放的停止时间。
在播放开始前设置停止时间
在对拓扑进行排队播放之前,可以使用 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,以获取播放拓扑的 ID。
对于拓扑中的每个输出节点,请调用 IMFTopologyNodeAttributeEditor::UpdateNodeAttributes。 此方法采用拓扑 ID 和指向 MFTOPONODE_ATTRIBUTE_UPDATE 结构的指针。 按如下所示初始化结构。
成员 值 NodeId 节点 ID。 若要获取节点 ID,请调用 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;
}
相关主题