Como criar uma lista de reprodução
Este tópico descreve como usar a Fonte de Sequência para reproduzir uma sequência de arquivos.
Visão geral
Para reproduzir arquivos de mídia em uma sequência, o aplicativo deve adicionar topologias em uma sequência para criar uma lista de reprodução e enfileirar essas topologias na sessão de mídia para reprodução.
A fonte de sequência assegura uma reprodução contínua ao inicializar e carregar a próxima topologia antes que a Sessão de Mídia comece a reproduzir a topologia atual. Isso permite que o aplicativo inicie a próxima topologia rapidamente sempre que necessário.
A Sessão de Mídia é responsável por alimentar os dados para os coletores e reproduzir as topologias na fonte de sequência. Além disso, a Media Session gere o tempo de apresentação dos segmentos.
Para obter mais informações sobre como a fonte do sequenciador gerencia topologias, consulte Sobre a fonte do sequenciador.
Este passo a passo contém as seguintes etapas:
- Pré-requisitos
- inicializando o Media Foundation
- Criando objetos do Media Foundation
- Criando a fonte de mídia
- Criação de topologias parciais
- Adicionando topologias ao de origem do Sequencer
- Definindo a primeira topologia na sessão de mídia
- Colocar em fila a próxima configuração da rede na sessão multimédia
- Libertando a fonte do Sequenciador
Os exemplos de código mostrados neste tópico são trechos do tópico Sequencer Source Example Code, que contém o código de exemplo completo.
Pré-requisitos
Antes de iniciar este passo a passo, familiarize-se com os seguintes conceitos do Media Foundation:
Leia também Como reproduzir arquivos de mídia com o Media Foundation, porque o código de exemplo mostrado aqui expande o código nesse tópico.
A inicializar Media Foundation
Antes de poder usar qualquer interface ou método do Media Foundation, inicialize o Media Foundation chamando a função MFStartup. Para obter mais informações, consulte Initializing Media Foundation.
hr = MFStartup(MF_VERSION);
Criando objetos do Media Foundation
Em seguida, crie os seguintes objetos Media Foundation:
- Sessão de imprensa. Este objeto expõe o interface IMFMediaSession, que fornece métodos para reproduzir, pausar e parar a topologia atual.
- Fonte do sequenciador. Este objeto expõe o interface IMFSequencerSource, que fornece métodos para adicionar, atualizar e excluir topologias em uma sequência.
- Chame a função MFCreateMediaSession para criar a Sessão de Mídia.
- Chame IMFMediaEventQueue::BeginGetEvent para solicitar o primeiro evento da Sessão de Média.
- Chame a função MFCreateSequencerSource para criar a origem do sequenciador.
O código a seguir cria a sessão de mídia e solicita o primeiro evento:
// Create a new instance of the media session.
HRESULT CPlayer::CreateSession()
{
// Close the old session, if any.
HRESULT hr = CloseSession();
if (FAILED(hr))
{
goto done;
}
assert(m_state == Closed);
// Create the media session.
hr = MFCreateMediaSession(NULL, &m_pSession);
if (FAILED(hr))
{
goto done;
}
// Start pulling events from the media session
hr = m_pSession->BeginGetEvent((IMFAsyncCallback*)this, NULL);
if (FAILED(hr))
{
goto done;
}
m_state = Ready;
done:
return hr;
}
Criando a fonte de mídia
Em seguida, crie uma fonte de mídia para o primeiro segmento da lista de reprodução. Use o Source Resolver para criar uma origem de mídia a partir de um URL. Para fazer isso, chame a função MFCreateSourceResolver para criar um resolvedor de origem e, em seguida, chame o IMFSourceResolver::CreateObjectFromURL método para criar a fonte de mídia.
Para obter informações sobre fontes de mídia, consulte Fontes de mídia.
Criando topologias parciais
Cada segmento na fonte do sequenciador tem sua própria topologia parcial. Em seguida, crie topologias parciais para fontes de mídia. Para uma topologia parcial, os nós de origem da topologia são conectados diretamente aos nós de saída, sem especificar nenhuma transformação intermediária. A Sessão de Mídia usa o objeto do carregador de topologia para resolver a topologia. Depois que uma topologia é resolvida, os decodificadores necessários e outros nós de transformação são adicionados. A origem do sequenciador também pode conter topologias completas.
Para criar o objeto de topologia, use a função MFCreateTopology e, em seguida, use a interfaceIMFTopologyNodepara criar nós de fluxo.
Para obter instruções completas sobre como usar esses elementos de programação para criar topologias, consulte Criando topologias de reprodução.
Um aplicativo pode reproduzir uma parte selecionada da fonte nativa configurando o nó de origem. Para fazer isso, defina o atributo MF_TOPONODE_MEDIASTART e o atributo MF_TOPONODE_MEDIASTOP nos nós de topologia MF_TOPOLOGY_SOURCESTREAM_NODE. Especifique o tempo de início da mídia e o tempo de paragem da mídia em relação ao início da fonte nativa como tipos UINT64.
Adicionando topologias à origem do Sequencer
Em seguida, adicione à origem do sequenciador as topologias parciais que você criou. Cada elemento de sequência, chamado de segmento, recebe um identificador MFSequencerElementId. Para obter mais informações sobre como a fonte do sequenciador gerencia topologias, consulte Sobre a fonte do sequenciador.
Depois que todas as topologias são adicionadas à origem do sequenciador, o aplicativo deve sinalizar o último segmento da sequência para encerrar a reprodução no pipeline. Sem esse sinalizador, a fonte do sequenciador espera que mais topologias sejam adicionadas.
Chame o método IMFSequencerSource::AppendTopology para adicionar uma topologia específica à fonte do sequenciador.
hr = m_pSequencerSource->AppendTopology( pTopology, SequencerTopologyFlags_Last, &SegmentId );
AppendTopology adiciona a topologia especificada à sequência. Esse método retorna o identificador de segmento no parâmetro pdwId.
Se a topologia for a última na origem do sequenciador, passe SequencerTopologyFlags_Last no parâmetro dwFlags. Esse valor é definido na enumeraçãoMFSequencerTopologyFlags.
Chame IMFSequencerSource::UpdateTopologyFlags para atualizar os sinalizadores da topologia associada ao identificador de segmento na lista de entrada. Nesse caso, a chamada indica que o segmento especificado é o último segmento do sequenciador. (Esta chamada é opcional se a última topologia for especificada na chamada AppendTopology.)
BOOL bFirstSegment = (NumSegments() == 0); if (!bFirstSegment) { // Remove the "last segment" flag from the last segment. hr = m_pSequencerSource->UpdateTopologyFlags(LastSegment(), 0); if (FAILED(hr)) { goto done; } }
O aplicativo pode substituir a topologia de um segmento por outra topologia chamando o IMFSequencerSource::UpdateTopology e passando a nova topologia em pTopology. Se houver novas fontes nativas na nova topologia, as fontes serão adicionadas ao cache de origem. A lista de pré-rolagem também é atualizada.
Definindo a primeira topologia da sessão de mídia
Em seguida, coloque em fila a primeira topologia na sequência de origem na Sessão Multimédia. Para obter a primeira topologia da origem do sequenciador, o aplicativo deve chamar o IMFMediaSourceTopologyProvider::GetMediaSourceTopology método. Esse método retorna a topologia parcial, que é resolvida pela sessão de mídia.
Para obter informações sobre topologias parciais, consulte Sobre topologias.
Recupere a fonte de mídia nativa para a primeira topologia da fonte de sequência.
Crie um descritor de apresentação para a fonte de mídia chamando o IMFMediaSource::CreatePresentationDescriptor método.
Recupere a topologia associada para a apresentação chamando o IMFMediaSourceTopologyProvider::GetMediaSourceTopology método.
Defina a primeira topologia na sessão de mídia chamando IMFMediaSession::SetTopology.
Chamar SetTopology com o parâmetro dwSetTopologyFlags definido como NULL. Isso instrui a Sessão de Mídia a iniciar a topologia especificada quando a topologia atual for concluída. Como nesse caso, a topologia especificada é a primeira topologia e não há nenhuma apresentação atual, a Sessão de Mídia inicia a nova apresentação imediatamente.
O valor NULL também indica que Media Session deve resolver a topologia porque a topologia retornada pelo provedor de topologia é sempre uma topologia parcial.
// Queues the next topology on the session.
HRESULT CPlaylist::QueueNextSegment(IMFPresentationDescriptor *pPD)
{
IMFMediaSourceTopologyProvider *pTopoProvider = NULL;
IMFTopology *pTopology = NULL;
//Get the topology for the presentation descriptor
HRESULT hr = m_pSequencerSource->QueryInterface(IID_PPV_ARGS(&pTopoProvider));
if (FAILED(hr))
{
goto done;
}
hr = pTopoProvider->GetMediaSourceTopology(pPD, &pTopology);
if (FAILED(hr))
{
goto done;
}
//Set the topology on the media session
m_pSession->SetTopology(NULL, pTopology);
done:
SafeRelease(&pTopoProvider);
SafeRelease(&pTopology);
return hr;
}
Colocando em fila a próxima topologia na sessão de mídia
Em seguida, o aplicativo precisa lidar com o evento MENewPresentation.
A fonte do Sequencer gera MENewPresentation quando a Sessão de Mídia começa a reproduzir um segmento seguido por outro segmento. Esse evento informa o aplicativo sobre a próxima topologia na fonte de sequência, fornecendo o descritor de apresentação para o próximo segmento na lista de preroll. A aplicação deve recuperar a topologia associada, usando o fornecedor de topologia, e enfileirá-la na Sessão de Multimédia. Em seguida, a fonte do sequenciador prepara esta topologia previamente, garantindo uma transição perfeita entre apresentações.
Quando a aplicação procura entre segmentos, a aplicação recebe vários eventos MENewPresentation à medida que a fonte do sequenciador atualiza a lista de preroll e configura a topologia correta. A aplicação deve manipular cada evento e colocar em fila a topologia retornada pelos dados do evento, na Sessão de Mídia. Para obter informações sobre como ignorar segmentos, consulte Usando a origem do Sequencer.
Para obter informações sobre como obter notificações de origem do sequenciador, consulte Sequencer Source Events.
No gestor de eventos MENewPresentation, recupere o descritor de apresentação para o próximo segmento dos dados do evento.
Obtenha a topologia associada para a apresentação chamando o IMFMediaSourceTopologyProvider::GetMediaSourceTopology método.
Defina a topologia na sessão de mídia chamando o IMFMediaSession::SetTopology método.
A Sessão de Mídia inicia a nova apresentação quando a apresentação atual for concluída.
HRESULT CPlaylist::OnNewPresentation(IMFMediaEvent *pEvent)
{
IMFPresentationDescriptor *pPD = NULL;
HRESULT hr = GetEventObject(pEvent, &pPD);
if (SUCCEEDED(hr))
{
// Queue the next segment on the media session
hr = QueueNextSegment(pPD);
}
SafeRelease(&pPD);
return hr;
}
Liberando a fonte do Sequencer
Finalmente, desligue a fonte do sequenciador. Para fazer isso, chame o IMFMediaSource::Shutdown método na fonte do sequenciador. Essa chamada desliga todas as fontes de mídia nativas subjacentes na fonte do sequenciador.
Depois de liberar a fonte do sequenciador, o aplicativo deve fechar e desligar a sessão de mídia chamando IMFMediaSession::Close e IMFMediaSession::Shutdown, nessa ordem.
Para evitar vazamentos de memória, o aplicativo deve liberar ponteiros para interfaces do Media Foundation quando eles não forem mais necessários.
Próximos passos
Este passo a passo ilustra como criar uma lista de reprodução básica usando a fonte do sequenciador. Depois de criar a lista de reprodução, você pode querer adicionar recursos avançados, como pular segmento, alterar o estado de reprodução e procurar dentro de um segmento. A lista a seguir fornece links para os tópicos relacionados:
- Como controlar estados de apresentação: A fonte do sequenciador depende da Sessão de Media para fornecer controle de transporte, como Reproduzir, Pausar e Parar.
- How to Perform Scrubbing descreve as etapas necessárias para buscar uma posição específica em um fluxo.
Tópicos relacionados