Создание списка воспроизведения
В этом разделе описывается использование источника последовательности для воспроизведения последовательности файлов.
Общие сведения
Чтобы воспроизвести файлы мультимедиа в последовательности, приложение должно добавить топологии в последовательность, чтобы создать список воспроизведения, и поместить эти топологии в очередь в сеансе мультимедиа для воспроизведения.
Источник sequencer обеспечивает беспроблемное воспроизведение путем инициализации и загрузки следующей топологии до того, как сеанс мультимедиа начнет воспроизводить текущую топологию. Это позволяет приложению быстро запускать следующую топологию всякий раз, когда это необходимо.
Сеанс мультимедиа отвечает за передачу данных в приемники и воспроизведение топологий в источнике последовательности. Кроме того, сеанс мультимедиа управляет временем презентации для сегментов.
Дополнительные сведения о том, как источник sequencer управляет топологиями, см. в разделе Сведения об источнике Sequencer.
Это пошаговое руководство содержит следующие действия.
- Предварительные условия
- Инициализация Media Foundation
- Создание объектов Media Foundation
- Создание источника мультимедиа
- Создание частичных топологий
- Добавление топологий в источник Sequencer
- Настройка первой топологии в сеансе мультимедиа
- Постановка в очередь следующей топологии в сеансе мультимедиа
- Освобождение источника 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 , который предоставляет методы для добавления, обновления и удаления топологий в последовательности.
- Вызовите функцию MFCreateMediaSession , чтобы создать сеанс мультимедиа.
- Вызовите IMFMediaEventQueue::BeginGetEvent , чтобы запросить первое событие из сеанса мультимедиа.
- Вызовите функцию 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 ожидает добавления дополнительных топологий.
Вызовите метод IMFSequencerSource::AppendTopology , чтобы добавить определенную топологию в источник секвенсора.
hr = m_pSequencerSource->AppendTopology( pTopology, SequencerTopologyFlags_Last, &SegmentId );
AppendTopology добавляет указанную топологию в последовательность. Этот метод возвращает идентификатор сегмента в параметре pdwId .
Если топология является последней в источнике sequencer, передайте SequencerTopologyFlags_Last в параметре dwFlags . Это значение определяется в перечислении MFSequencerTopologyFlags .
Вызовите 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 . Этот метод возвращает частичную топологию, которая разрешается сеансом мультимедиа.
Сведения о частичных топологиях см. в разделе Сведения о топологиях.
Получение собственного источника мультимедиа для первой топологии источника последовательности.
Создайте дескриптор презентации для источника мультимедиа, вызвав метод IMFMediaSource::CreatePresentationDescriptor .
Получите связанную топологию для презентации, вызвав метод IMFMediaSourceTopologyProvider::GetMediaSourceTopology .
Задайте первую топологию в сеансе мультимедиа, вызвав 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.
В обработчике событий MENewPresentation получите дескриптор презентации для следующего сегмента из данных события.
Получите связанную топологию для презентации, вызвав метод IMFMediaSourceTopologyProvider::GetMediaSourceTopology .
Задайте топологию в сеансе мультимедиа, вызвав метод 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. После создания списка воспроизведения может потребоваться добавить дополнительные функции, такие как пропуск сегмента, изменение состояния воспроизведения и поиск в сегменте. В следующем списке приведены ссылки на соответствующие разделы:
- Управление состояниями презентации. Источник секвенсора использует сеанс мультимедиа для управления транспортировкой, например Воспроизведение, Приостановка и Остановка.
- Практическое руководство по выполнению очистки описывает шаги, необходимые для поиска определенной позиции в потоке.
Связанные темы