Compartir a través de


Cómo crear una lista de reproducción

En este tema se describe cómo usar el origen de secuencia para reproducir una secuencia de archivos.

Información general

Para reproducir archivos multimedia en una secuencia, la aplicación debe agregar topologías en una secuencia para crear una lista de reproducción y poner en cola estas topologías en la sesión multimedia para su reproducción.

El origen del secuenciador garantiza la reproducción sin problemas inicializando y cargando la siguiente topología antes de que la sesión multimedia empiece a reproducir la topología actual. Esto permite que la aplicación inicie la siguiente topología rápidamente siempre que sea necesario.

La sesión multimedia es responsable de alimentar los datos a los receptores y reproducir las topologías en el origen de secuencia. Además, la sesión multimedia administra el tiempo de presentación de los segmentos.

Para obtener más información sobre cómo administra el origen del secuenciador las topologías, vea Acerca del origen del secuenciador.

Este tutorial contiene los pasos siguientes:

  1. Requisitos previos
  2. Inicialización de Media Foundation
  3. Creación de objetos de Media Foundation
  4. Crear el origen multimedia
  5. Crear topologías parciales
  6. Adición de topologías al origen del secuenciador
  7. Establecer la primera topología en la sesión multimedia
  8. Poner en cola la topología siguiente en la sesión multimedia
  9. Liberación del origen del secuenciador

Los ejemplos de código que se muestran en este tema son extractos del tema Código de ejemplo fuente del secuenciador, que contiene el código de ejemplo completo.

Requisitos previos

Antes de comenzar este tutorial, familiarícese con los siguientes conceptos de Media Foundation:

Lea también Cómo reproducir archivos multimedia con Media Foundation, ya que el código de ejemplo shwon aquí se expande en el código de ese tema.

Inicialización de Media Foundation

Para poder usar cualquier interfaz o método de Media Foundation, inicialice Media Foundation llamando a la función MFStartup . Para obtener más información, vea Inicializar Media Foundation.

    hr = MFStartup(MF_VERSION);

Creación de objetos de Media Foundation

A continuación, cree los siguientes objetos de Media Foundation:

  • Sesión multimedia. Este objeto expone la interfaz IMFMediaSession , que proporciona métodos para reproducir, pausar y detener la topología actual.
  • Origen del secuenciador. Este objeto expone la interfaz IMFSequencerSource , que proporciona métodos para agregar, actualizar y eliminar topologías en una secuencia.
  1. Llame a la función MFCreateMediaSession para crear la sesión multimedia.
  2. Llame a IMFMediaEventQueue::BeginGetEvent para solicitar el primer evento de la sesión multimedia.
  3. Llame a la función MFCreateSequencerSource para crear el origen del secuenciador.

El código siguiente crea la sesión multimedia y solicita el primer 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;
}

Crear el origen multimedia

A continuación, cree un origen multimedia para el primer segmento de lista de reproducción. Use el Solucionador de origen para crear un origen multimedia a partir de una dirección URL. Para ello, llame a la función MFCreateSourceResolver para crear un solucionador de origen y, a continuación, llame al método IMFSourceResolver::CreateObjectFromURL para crear el origen multimedia.

Para obtener información sobre los orígenes multimedia, vea Orígenes multimedia.

Crear topologías parciales

Cada segmento del origen del secuenciador tiene su propia topología parcial. A continuación, cree topologías parciales para orígenes multimedia. En el caso de una topología parcial, los nodos de origen de la topología se conectan directamente a los nodos de salida, sin especificar ninguna transformación intermedia. La sesión multimedia usa el objeto del cargador de topologías para resolver la topología. Una vez resuelta una topología, se agregan los descodificadores necesarios y otros nodos de transformación. El origen del secuenciador también puede contener topologías completas.

Para crear el objeto de topología, use la función MFCreateTopology y, a continuación, use la interfaz IMFTopologyNode para crear nodos de secuencia.

Para obtener instrucciones completas sobre el uso de estos elementos de programación para crear topologías, consulte Creating Playback Topologies( Crear topologías de reproducción).

Una aplicación puede reproducir una parte seleccionada del origen nativo configurando el nodo de origen. Para ello, establezca el atributo MF_TOPONODE_MEDIASTART y el atributo MF_TOPONODE_MEDIASTOPen MF_TOPOLOGY_SOURCESTREAM_NODE nodos de topología. Especifique la hora de inicio de medios y la hora de detención de medios en relación con el inicio del origen nativo como tipos UINT64 .

Adición de topologías al origen del secuenciador

A continuación, agregue al origen del secuenciador las topologías parciales que ha creado. A cada elemento de secuencia, denominado segmento, se le asigna un identificador MFSequencerElementId . Para obtener más información sobre cómo administra el origen del secuenciador las topologías, vea Acerca del origen del secuenciador.

Una vez agregadas todas las topologías al origen del secuenciador, la aplicación debe marcar el último segmento de la secuencia para finalizar la reproducción en la canalización. Sin esta marca, el origen del secuenciador espera que se agreguen más topologías.

  1. Llame al método IMFSequencerSource::AppendTopology para agregar una topología específica al origen del secuenciador.

        hr = m_pSequencerSource->AppendTopology(
            pTopology, 
            SequencerTopologyFlags_Last, 
            &SegmentId
            );
    

    AppendTopology agrega la topología especificada a la secuencia. Este método devuelve el identificador de segmento en el parámetro pdwId .

    Si la topología es la última del origen del secuenciador, pase SequencerTopologyFlags_Last en el parámetro dwFlags . Este valor se define en la enumeración MFSequencerTopologyFlags .

  2. Llame a IMFSequencerSource::UpdateTopologyFlags para actualizar las marcas de la topología asociada al identificador de segmento de la lista de entrada. En este caso, la llamada indica que el segmento especificado es el último segmento del secuenciador. (Esta llamada es opcional si se especifica la última topología en la llamada 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;
            }
        }
    

La aplicación puede reemplazar la topología de un segmento por otra topología llamando a IMFSequencerSource::UpdateTopology y pasando la nueva topología en pTopology. Si hay nuevos orígenes nativos en la nueva topología, los orígenes se agregan a la memoria caché de origen. La lista de inscripción previa también se actualiza.

Establecer la primera topología en la sesión multimedia

A continuación, pone en cola la primera topología del origen de secuencia en la sesión multimedia. Para obtener la primera topología del origen del secuenciador, la aplicación debe llamar al método IMFMediaSourceTopologyProvider::GetMediaSourceTopology . Este método devuelve la topología parcial, que resuelve la sesión multimedia.

Para obtener información sobre las topologías parciales, vea Acerca de las topologías.

  1. Recupere el origen de medios nativos para la primera topología del origen de secuencia.

  2. Cree un descriptor de presentación para el origen multimedia llamando al método IMFMediaSource::CreatePresentationDescriptor .

  3. Recupere la topología asociada para la presentación llamando al método IMFMediaSourceTopologyProvider::GetMediaSourceTopology .

  4. Establezca la primera topología en la sesión multimedia llamando a IMFMediaSession::SetTopology.

    Llame a SetTopology con el parámetro dwSetTopologyFlags establecido en NULL. Esto indica a la sesión multimedia que inicie la topología especificada cuando se haya completado la topología actual. Como en este caso, la topología especificada es la primera topología y no hay ninguna presentación actual, la sesión multimedia inicia la nueva presentación inmediatamente.

    El valor NULL también indica que la sesión multimedia debe resolver la topología porque la topología devuelta por el proveedor de topología siempre es una topología 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;
}

Poner en cola la topología siguiente en la sesión multimedia

A continuación, la aplicación debe controlar el evento MENewPresentation .

El origen del secuenciador genera MENewPresentation cuando la sesión multimedia comienza a reproducir un segmento que tiene otro segmento que lo sigue. Este evento informa a la aplicación sobre la siguiente topología en el origen de secuencia proporcionando el descriptor de presentación para el siguiente segmento de la lista de inscripción previa. La aplicación debe recuperar la topología asociada, mediante el proveedor de topología y ponerla en cola en la sesión multimedia. A continuación, el origen del secuenciador preinscribe esta topología, lo que garantiza una transición sin problemas entre presentaciones.

Cuando la aplicación busca entre segmentos, la aplicación recibe varios eventos MENewPresentation a medida que el origen del secuenciador actualiza la lista de inscripción previa y configura la topología correcta. La aplicación debe controlar cada evento y poner en cola la topología devuelta en los datos del evento, en la sesión multimedia. Para obtener información sobre cómo omitir segmentos, vea Uso del origen del secuenciador.

Para obtener información sobre cómo obtener notificaciones de origen del secuenciador, vea Eventos de origen del secuenciador.

  1. En el controlador de eventos MENewPresentation , recupere el descriptor de presentación para el siguiente segmento de los datos del evento.

  2. Obtenga la topología asociada para la presentación llamando al método IMFMediaSourceTopologyProvider::GetMediaSourceTopology .

  3. Establezca la topología en la sesión multimedia llamando al método IMFMediaSession::SetTopology .

    La sesión multimedia inicia la nueva presentación cuando se ha completado la presentación actual.

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;
}

Liberar el origen del secuenciador

Por último, apague el origen del secuenciador. Para ello, llame al método IMFMediaSource::Shutdown en el origen del secuenciador. Esta llamada cierra todos los orígenes de medios nativos subyacentes en el origen del secuenciador.

Después de liberar el origen del secuenciador, la aplicación debe cerrar y apagar la sesión multimedia llamando a IMFMediaSession::Close y IMFMediaSession::Shutdown, en ese orden.

Para evitar pérdidas de memoria, la aplicación debe liberar punteros a las interfaces de Media Foundation cuando ya no se necesiten.

Pasos siguientes

En este tutorial se ilustra cómo crear una lista de reproducción básica mediante el origen del secuenciador. Después de crear la lista de reproducción, es posible que quiera agregar características avanzadas, como omitir segmentos, cambiar el estado de reproducción y buscar dentro de un segmento. En la lista siguiente se proporcionan vínculos a los temas relacionados:

Origen del secuenciador