Como definir o tempo de parada de reprodução
Este tópico descreve como definir um tempo de parada para reprodução ao usar a Sessãode Mídia.
Definindo a hora de parada antes do início da reprodução
Antes de enfileirar uma topologia para reprodução, você pode especificar o tempo de parada usando o atributo MF_TOPONODE_MEDIASTOP. Para cada nó de saída na topologia, defina o valor da MF_TOPONODE_MEDIASTOP para o tempo de parada em unidades de 100 nanossegundos.
Observe que a configuração desse atributo após o início da reprodução não tem efeito. Portanto, defina o atributo antes de chamar IMFMediaSession::Start.
O código a seguir mostra como definir o tempo de parada em uma topologia existente.
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;
}
Definindo o tempo de parada após o início da reprodução
Há uma maneira de definir o tempo de parada após a Sessão de Mídia iniciar a reprodução usando a interface IMFTopologyNodeAttributeEditor.
Importante
Essa interface tem uma limitação séria, pois o tempo de parada é especificado como um valor de 32 bits. Isso significa que o tempo máximo de parada que você pode definir usando essa interface é 0xFFFFFFFF ou pouco mais de sete minutos. Essa limitação ocorre devido a uma definição de estrutura incorreta.
Para definir o tempo de parada usando a interface IMFTopologyNodeAttributeEditor, execute as etapas a seguir.
Chame MFGetService para obter a interface IMFTopologyNodeAttributeEditor da Sessão de Mídia.
Chame IMFTopology::GetTopologyID para obter a ID da topologia de reprodução.
Para cada nó de saída na topologia, chame IMFTopologyNodeAttributeEditor::UpdateNodeAttributes. Esse método usa a ID da topologia e um ponteiro para uma estrutura MFTOPONODE_ATTRIBUTE_UPDATE. Inicialize a estrutura da seguinte maneira.
Membro Valor NodeId A ID do nó. Para obter a ID do nó, chame IMFTopologyNode::GetTopoNodeID. guidAttributeKey MF_TOPONODE_MEDIASTOP attrType MF_ATTRIBUTE_UINT64 u64 O tempo de parada, em unidades de 100 nanossegundos.
Tenha cuidado para definir o valor de attrType corretamente. Embora u64 seja um tipo de 32 bits, o método exige que attrType seja definido como MF_ATTRIBUTE_UINT64.
O código a seguir mostra essas etapas.
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;
}
Tópicos relacionados