Guide pratique pour créer une playlist

Cette rubrique explique comment utiliser la source de séquence pour lire une séquence de fichiers.

Vue d’ensemble

Pour lire les fichiers multimédias dans une séquence, l’application doit ajouter des topologies dans une séquence pour créer une playlist et mettre en file d’attente ces topologies sur la session multimédia pour lecture.

La source du séquenceur garantit une lecture fluide en initialisant et en chargeant la topologie suivante avant que la session multimédia commence à lire la topologie actuelle. Cela permet à l’application de démarrer rapidement la topologie suivante chaque fois qu’elle est nécessaire.

La session multimédia est responsable de l’alimentation des données vers les récepteurs et de la lecture des topologies dans la source de séquence. En outre, la session multimédia gère le temps de présentation des segments.

Pour plus d’informations sur la façon dont la source de séquenceur gère les topologies, consultez À propos de la source sequencer.

Cette procédure contient les étapes suivantes :

  1. Composants requis
  2. Initialisation de Media Foundation
  3. Création d’objets Media Foundation
  4. Création de la source multimédia
  5. Création de topologies partielles
  6. Ajout de topologies à la source sequencer
  7. Définition de la première topologie sur la session multimédia
  8. Mise en file d’attente de la topologie suivante sur la session multimédia
  9. Publication de la source sequencer

Les exemples de code présentés dans cette rubrique sont des extraits de l’exemple de code source de la rubrique Sequencer, qui contient l’exemple de code complet.

Prérequis

Avant de commencer cette procédure, familiarisez-vous avec les concepts suivants de Media Foundation :

Lisez également Comment lire des fichiers multimédias avec Media Foundation, car l’exemple de code shwon ici développe le code de cette rubrique.

Initialisation de Media Foundation

Avant de pouvoir utiliser des interfaces ou méthodes Media Foundation, initialisez Media Foundation en appelant la fonction MFStartup . Pour plus d’informations, consultez Initialisation de Media Foundation.

    hr = MFStartup(MF_VERSION);

Création d’objets Media Foundation

Ensuite, créez les objets Media Foundation suivants :

  • Session multimédia. Cet objet expose l’interface IMFMediaSession , qui fournit des méthodes pour lire, suspendre et arrêter la topologie actuelle.
  • Source du séquenceur. Cet objet expose l’interface IMFSequencerSource , qui fournit des méthodes pour ajouter, mettre à jour et supprimer des topologies dans une séquence.
  1. Appelez la fonction MFCreateMediaSession pour créer la session multimédia.
  2. Appelez IMFMediaEventQueue::BeginGetEvent pour demander le premier événement à la session multimédia.
  3. Appelez la fonction MFCreateSequencerSource pour créer la source du séquenceur.

Le code suivant crée la session multimédia et demande le premier événement :

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

Création de la source multimédia

Ensuite, créez une source multimédia pour le premier segment de playlist. Utilisez le programme de résolution de source pour créer une source multimédia à partir d’une URL. Pour ce faire, appelez la fonction MFCreateSourceResolver pour créer un programme de résolution de source, puis appelez la méthode IMFSourceResolver::CreateObjectFromURL pour créer la source multimédia.

Pour plus d’informations sur les sources multimédias, consultez Sources multimédias.

Création de topologies partielles

Chaque segment de la source du séquenceur a sa propre topologie partielle. Ensuite, créez des topologies partielles pour les sources multimédias. Pour une topologie partielle, les nœuds sources de topologie sont connectés directement aux nœuds de sortie, sans spécifier de transformations intermédiaires. Media Session utilise l’objet chargeur de topologie pour résoudre la topologie. Une fois qu’une topologie est résolue, les décodeurs et autres nœuds de transformation requis sont ajoutés. La source du séquenceur peut également contenir des topologies complètes.

Pour créer l’objet de topologie, utilisez la fonction MFCreateTopology , puis utilisez l’interface IMFTopologyNode pour créer des nœuds de flux.

Pour obtenir des instructions complètes sur l’utilisation de ces éléments de programmation pour créer des topologies, consultez Création de topologies de lecture.

Une application peut lire une partie sélectionnée de la source native en configurant le nœud source. Pour ce faire, définissez l’attribut MF_TOPONODE_MEDIASTART et l’attribut MF_TOPONODE_MEDIASTOP sur MF_TOPOLOGY_SOURCESTREAM_NODE nœuds de topologie. Spécifiez l’heure de démarrage du média et l’heure d’arrêt du média par rapport au début de la source native en tant que types UINT64 .

Ajout de topologies à la source sequencer

Ensuite, ajoutez à la source du séquenceur les topologies partielles que vous avez créées. Chaque élément de séquence, appelé segment, se voit attribuer un identificateur MFSequencerElementId . Pour plus d’informations sur la façon dont la source de séquenceur gère les topologies, consultez À propos de la source sequencer.

Une fois toutes les topologies ajoutées à la source du séquenceur, l’application doit marquer le dernier segment de la séquence pour mettre fin à la lecture dans le pipeline. Sans cet indicateur, la source du séquenceur s’attend à ce que d’autres topologies soient ajoutées.

  1. Appelez la méthode IMFSequencerSource::AppendTopology pour ajouter une topologie spécifique à la source du séquenceur.

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

    AppendTopology ajoute la topologie spécifiée à la séquence. Cette méthode retourne l’identificateur de segment dans le paramètre pdwId .

    Si la topologie est la dernière dans la source du séquenceur, passez SequencerTopologyFlags_Last dans le paramètre dwFlags . Cette valeur est définie dans l’énumération MFSequencerTopologyFlags .

  2. Appelez IMFSequencerSource::UpdateTopologyFlags pour mettre à jour les indicateurs de la topologie associée à l’identificateur de segment dans la liste d’entrée. Dans ce cas, l’appel indique que le segment spécifié est le dernier segment du séquenceur. (Cet appel est facultatif si la dernière topologie est spécifiée dans l’appel 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;
            }
        }
    

L’application peut remplacer la topologie d’un segment par une autre topologie en appelant IMFSequencerSource::UpdateTopology et en transmettant la nouvelle topologie dans pTopology. S’il existe de nouvelles sources natives dans la nouvelle topologie, les sources sont ajoutées au cache source. La liste de pré-inscriptions est également actualisée.

Définition de la première topologie sur la session multimédia

Ensuite, mettre en file d’attente la première topologie de la source de séquence sur la session multimédia. Pour obtenir la première topologie à partir de la source du séquenceur, l’application doit appeler la méthode IMFMediaSourceTopologyProvider::GetMediaSourceTopology . Cette méthode retourne la topologie partielle, qui est résolue par la session multimédia.

Pour plus d’informations sur les topologies partielles, consultez À propos des topologies.

  1. Récupérez la source multimédia native pour la première topologie de la source de séquence.

  2. Créez un descripteur de présentation pour la source multimédia en appelant la méthode IMFMediaSource::CreatePresentationDescriptor .

  3. Récupérez la topologie associée pour la présentation en appelant la méthode IMFMediaSourceTopologyProvider::GetMediaSourceTopology .

  4. Définissez la première topologie de la session multimédia en appelant IMFMediaSession::SetTopology.

    Appelez SetTopology avec le paramètre dwSetTopologyFlags défini sur NULL. Cela indique à la session multimédia de démarrer la topologie spécifiée une fois la topologie actuelle terminée. Étant donné que dans ce cas, la topologie spécifiée est la première topologie et qu’il n’y a pas de présentation actuelle, la session multimédia démarre immédiatement la nouvelle présentation.

    La valeur NULL indique également que Media Session doit résoudre la topologie, car la topologie retournée par le fournisseur de topologie est toujours une topologie partielle.

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

Mise en file d’attente de la topologie suivante sur la session multimédia

Ensuite, l’application doit gérer l’événement MENewPresentation .

La source sequencer déclenche MENewPresentation lorsque la session multimédia commence à lire un segment dont un autre segment est suivi. Cet événement informe l’application de la topologie suivante dans la source de séquence en fournissant le descripteur de présentation pour le segment suivant dans la liste préliminaire. L’application doit récupérer la topologie associée à l’aide du fournisseur de topologie et la mettre en file d’attente sur la session multimédia. La source du séquenceur prérolle ensuite cette topologie, ce qui garantit une transition fluide entre les présentations.

Lorsque l’application recherche plusieurs segments, l’application reçoit plusieurs événements MENewPresentation lorsque la source du séquenceur actualise la liste de prérolls et configure la topologie appropriée. L’application doit gérer chaque événement et mettre en file d’attente la topologie retournée dans les données d’événement, sur la session multimédia. Pour plus d’informations sur l’ignorer des segments, consultez Utilisation de la source sequencer.

Pour plus d’informations sur l’obtention des notifications sources du séquenceur, consultez Événements source sequencer.

  1. Dans le gestionnaire d’événements MENewPresentation , récupérez le descripteur de présentation du segment suivant à partir des données d’événement.

  2. Obtenez la topologie associée pour la présentation en appelant la méthode IMFMediaSourceTopologyProvider::GetMediaSourceTopology .

  3. Définissez la topologie sur la session multimédia en appelant la méthode IMFMediaSession::SetTopology .

    La session multimédia démarre la nouvelle présentation une fois la présentation actuelle terminée.

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

Libération de la source sequencer

Enfin, arrêtez la source du séquenceur. Pour ce faire, appelez la méthode IMFMediaSource::Shutdown sur la source du séquenceur. Cet appel arrête toutes les sources multimédias natives sous-jacentes dans la source du séquenceur.

Après avoir libéré la source du séquenceur, l’application doit fermer et arrêter la session multimédia en appelant IMFMediaSession::Close et IMFMediaSession::Shutdown, dans cet ordre.

Pour éviter les fuites de mémoire, l’application doit libérer des pointeurs vers les interfaces Media Foundation lorsqu’elles ne sont plus nécessaires.

Étapes suivantes

Cette procédure pas à pas a montré comment créer une playlist de base à l’aide de la source du séquenceur. Après avoir créé la playlist, vous pouvez ajouter des fonctionnalités avancées telles que le saut de segment, la modification de l’état de lecture et la recherche dans un segment. La liste suivante fournit des liens vers les rubriques associées :

Sequencer Source