Создание списка воспроизведения

В этом разделе описывается использование источника последовательности для воспроизведения последовательности файлов.

Общие сведения

Чтобы воспроизвести файлы мультимедиа в последовательности, приложение должно добавить топологии в последовательность, чтобы создать список воспроизведения, и поместить эти топологии в очередь в сеансе мультимедиа для воспроизведения.

Источник sequencer обеспечивает беспроблемное воспроизведение путем инициализации и загрузки следующей топологии до того, как сеанс мультимедиа начнет воспроизводить текущую топологию. Это позволяет приложению быстро запускать следующую топологию всякий раз, когда это необходимо.

Сеанс мультимедиа отвечает за передачу данных в приемники и воспроизведение топологий в источнике последовательности. Кроме того, сеанс мультимедиа управляет временем презентации для сегментов.

Дополнительные сведения о том, как источник sequencer управляет топологиями, см. в разделе Сведения об источнике Sequencer.

Это пошаговое руководство содержит следующие действия.

  1. Предварительные условия
  2. Инициализация Media Foundation
  3. Создание объектов Media Foundation
  4. Создание источника мультимедиа
  5. Создание частичных топологий
  6. Добавление топологий в источник Sequencer
  7. Настройка первой топологии в сеансе мультимедиа
  8. Постановка в очередь следующей топологии в сеансе мультимедиа
  9. Освобождение источника Sequencer

Примеры кода, показанные в этом разделе, являются выдержками из раздела Sequencer Source Example Code, который содержит полный пример кода.

Предварительные требования

Перед началом работы с этим пошаговыми сведениями ознакомьтесь со следующими понятиями Media Foundation:

Также ознакомьтесь с разделом Воспроизведение файлов мультимедиа с помощью Media Foundation, так как пример кода shwon здесь расширяет код в этом разделе.

Инициализация Media Foundation

Прежде чем использовать интерфейсы или методы Media Foundation, инициализируйте Media Foundation, вызвав функцию MFStartup . Дополнительные сведения см. в разделе Инициализация Media Foundation.

    hr = MFStartup(MF_VERSION);

Создание объектов Media Foundation

Затем создайте следующие объекты Media Foundation:

  • Сеанс мультимедиа. Этот объект предоставляет интерфейс IMFMediaSession , который предоставляет методы для воспроизведения, приостановки и остановки текущей топологии.
  • Источник sequencer. Этот объект предоставляет интерфейс IMFSequencerSource , который предоставляет методы для добавления, обновления и удаления топологий в последовательности.
  1. Вызовите функцию MFCreateMediaSession , чтобы создать сеанс мультимедиа.
  2. Вызовите IMFMediaEventQueue::BeginGetEvent , чтобы запросить первое событие из сеанса мультимедиа.
  3. Вызовите функцию MFCreateSequencerSource , чтобы создать источник sequencer.

Следующий код создает сеанс мультимедиа и запрашивает первое событие:

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

Создание источника мультимедиа

Затем создайте источник мультимедиа для первого сегмента списка воспроизведения. Используйте сопоставитель источников для создания источника мультимедиа на основе URL-адреса. Для этого вызовите функцию MFCreateSourceResolver , чтобы создать сопоставитель источника, а затем вызовите метод IMFSourceResolver::CreateObjectFromURL для создания источника мультимедиа.

Сведения об источниках мультимедиа см. в разделе Источники мультимедиа.

Создание частичных топологий

Каждый сегмент в источнике секвенсора имеет собственную частичную топологию. Затем создайте частичные топологии для источников мультимедиа. Для частичной топологии исходные узлы топологии подключаются непосредственно к выходным узлам без указания промежуточных преобразований. Сеанс мультимедиа использует объект загрузчика топологии для разрешения топологии. После разрешения топологии добавляются необходимые декодеры и другие узлы преобразования. Источник sequencer также может содержать полные топологии.

Чтобы создать объект топологии, используйте функцию MFCreateTopology , а затем используйте интерфейс IMFTopologyNode для создания узлов потока.

Полные инструкции по использованию этих элементов программирования для создания топологий см. в разделе Создание топологий воспроизведения.

Приложение может воспроизвести выбранную часть собственного источника, настроив исходный узел. Для этого задайте атрибуты MF_TOPONODE_MEDIASTART и MF_TOPONODE_MEDIASTOP на узлах топологии MF_TOPOLOGY_SOURCESTREAM_NODE . Укажите время начала и время остановки носителя относительно запуска собственного источника в качестве типов UINT64 .

Добавление топологий в источник Sequencer

Затем добавьте в источник sequencer созданные частичные топологии. Каждому элементу последовательности, называемому сегментом, назначается идентификатор MFSequencerElementId . Дополнительные сведения о том, как источник sequencer управляет топологиями, см. в разделе Сведения об источнике Sequencer.

После добавления всех топологий в источник sequencer приложение должно пометить последний сегмент последовательности, чтобы завершить воспроизведение в конвейере. Без этого флага источник sequencer ожидает добавления дополнительных топологий.

  1. Вызовите метод IMFSequencerSource::AppendTopology , чтобы добавить определенную топологию в источник секвенсора.

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

    AppendTopology добавляет указанную топологию в последовательность. Этот метод возвращает идентификатор сегмента в параметре pdwId .

    Если топология является последней в источнике sequencer, передайте SequencerTopologyFlags_Last в параметре dwFlags . Это значение определяется в перечислении MFSequencerTopologyFlags .

  2. Вызовите IMFSequencerSource::UpdateTopologyFlags , чтобы обновить флаги для топологии, связанной с идентификатором сегмента во входном списке. В этом случае вызов указывает, что указанный сегмент является последним сегментом в секвенсоре. (Этот вызов необязателен, если последняя топология указана в вызове 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;
            }
        }
    

Приложение может заменить топологию сегмента другой топологией, вызвав IMFSequencerSource::UpdateTopology и передав новую топологию в pTopology. Если в новой топологии есть новые собственные источники, они добавляются в исходный кэш. Список предварительной подготовки также обновляется.

Настройка первой топологии в сеансе мультимедиа

Затем поставить первую топологию в источник последовательности в сеансе мультимедиа. Чтобы получить первую топологию из источника sequencer, приложение должно вызвать метод IMFMediaSourceTopologyProvider::GetMediaSourceTopology . Этот метод возвращает частичную топологию, которая разрешается сеансом мультимедиа.

Сведения о частичных топологиях см. в разделе Сведения о топологиях.

  1. Получение собственного источника мультимедиа для первой топологии источника последовательности.

  2. Создайте дескриптор презентации для источника мультимедиа, вызвав метод IMFMediaSource::CreatePresentationDescriptor .

  3. Получите связанную топологию для презентации, вызвав метод IMFMediaSourceTopologyProvider::GetMediaSourceTopology .

  4. Задайте первую топологию в сеансе мультимедиа, вызвав IMFMediaSession::SetTopology.

    Вызовите SetTopology с параметром dwSetTopologyFlags , имеющим значение NULL. Это указывает сеансу мультимедиа запустить указанную топологию после завершения текущей топологии. Так как в этом случае указанная топология является первой топологией и текущей презентации нет, сеанс мультимедиа немедленно запускает новую презентацию.

    Значение NULL также указывает, что сеанс мультимедиа должен разрешать топологию, так как топология, возвращаемая поставщиком топологии, всегда является частичной топологией.

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

Постановка в очередь следующей топологии в сеансе мультимедиа

Затем приложение должно обработать событие MENewPresentation .

Источник Sequencer вызывает meNewPresentation , когда сеанс мультимедиа начинает воспроизводить сегмент, за которым следует другой сегмент. Это событие информирует приложение о следующей топологии в источнике последовательности, предоставляя дескриптор презентации для следующего сегмента в списке предварительной версии. Приложение должно получить связанную топологию с помощью поставщика топологии и поместить ее в очередь в сеансе мультимедиа. Затем источник sequencer предварительно выполняет эту топологию, что обеспечивает простой переход между презентациями.

Когда приложение выполняет поиск между сегментами, приложение получает несколько событий MENewPresentation , так как источник sequencer обновляет список предварительной версии и настраивает правильную топологию. Приложение должно обрабатывать каждое событие и ставить в очередь топологию, возвращаемую в данных события, в сеансе мультимедиа. Сведения о пропуске сегментов см. в разделе Использование источника Sequencer.

Сведения о получении уведомлений об источнике sequencer см. в разделе События источника sequencer.

  1. В обработчике событий MENewPresentation получите дескриптор презентации для следующего сегмента из данных события.

  2. Получите связанную топологию для презентации, вызвав метод IMFMediaSourceTopologyProvider::GetMediaSourceTopology .

  3. Задайте топологию в сеансе мультимедиа, вызвав метод IMFMediaSession::SetTopology .

    Сеанс мультимедиа запускает новую презентацию после завершения текущей презентации.

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

Освобождение источника Sequencer

Наконец, завершите работу источника sequencer. Для этого вызовите метод IMFMediaSource::Shutdown в источнике sequencer. Этот вызов завершает работу всех базовых собственных источников мультимедиа в источнике sequencer.

После освобождения источника sequencer приложение должно закрыть и завершить сеанс мультимедиа, вызвав IMFMediaSession::Close и IMFMediaSession::Shutdown в этом порядке.

Чтобы избежать утечек памяти, приложение должно освободить указатели на интерфейсы Media Foundation, когда они больше не нужны.

Next Steps

В этом пошаговом руководстве показано, как создать базовый список воспроизведения с помощью источника sequencer. После создания списка воспроизведения может потребоваться добавить дополнительные функции, такие как пропуск сегмента, изменение состояния воспроизведения и поиск в сегменте. В следующем списке приведены ссылки на соответствующие разделы:

Источник Sequencer