使用 Sequencer 來源
本主題描述如何使用 Sequencer 來源 。 它包含以下各節:
如需排序器來源的一般概觀,請參閱 關於 Sequencer 來源 。
概觀
排序器來源會公開下列介面。
介面 | 描述 |
---|---|
IMFMediaSource | 公開一般媒體來源功能。 |
IMFSequencerSource | 可讓應用程式新增或移除拓撲。 |
IMFMediaSourceTopologyProvider | 擷取媒體會話上要排入佇列的下一個拓撲。 |
IMFMediaSourcePresentationProvider | 媒體會話用來結束區段。 應用程式不會使用此介面。 |
IMFGetService | 查詢服務介面 的 排序器來源。 |
若要播放一連串媒體來源,請執行下列步驟:
- 若要建立排序器來源,請呼叫 MFCreateSequencerSource 函式。
- 針對每個區段,建立播放拓撲,如建立播放拓撲 中所述 。 若要將拓撲新增至簡報,請呼叫 IMFSequencerSource::AppendTopology 。
- 開始播放之前,請在排序器來源上呼叫 IMFMediaSource::CreatePresentationDescriptor 。 這個方法會傳回第一個區段之簡報描述元的指標。 若要取得與此區段相關聯的拓撲,請在 IMFMediaSourceTopologyProvider 介面的 排序器來源上呼叫 QueryInterface 。 將簡報描述項傳遞至 IMFMediaSourceTopologyProvider::GetMediaSourceTopology 方法。 這個方法會傳回拓撲的指標。
- 藉由呼叫媒體會話的 IMFMediaSession::SetTopology 方法,將第一個區段的 拓撲傳遞至媒體會話。
- 呼叫 IMFMediaSession::Start 開始 播放。
- 當排序器來源準備好預先註冊下一個 區段時,它會傳送 MENewPresentation 事件,其事件資料為 IMFPresentationDescriptor 介面指標。 同樣地,藉由在排序器來源上呼叫 GetMediaSourceTopology 來取得區段的拓撲,並藉由呼叫 SetTopology 在媒體會話上設定拓撲。 不需要重新開機媒體來源:它會自動播放至下一個區段。
- 在應用程式結束之前,請呼叫 IMFMediaSource::Shutdown 來關閉排序器來源。
下列程式碼示範如何取得拓撲,並在媒體會話上加以設定:
// 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;
}
如需完整的程式碼範例,請參閱 Sequencer 原始程式碼 。
新增拓撲
排序器來源會維護兩個拓撲清單: 輸入清單 和 預先註冊清單 。
輸入清單是對應至播放清單區段的拓撲集合,其順序是由應用程式呼叫 IMFSequencerSource::AppendTopology 來新增。 這個方法會為每個拓撲指派類型 MFSequencerElementId 的唯 一區段識別碼 。 區段識別碼會設定為所有來源拓撲節點的屬性。 應用程式可以使用 MF_TOPONODE_SEQUENCE_ELEMENTID 屬性,從來源節點 取得區段識別碼。 如果應用程式多次在相同的拓撲上呼叫 AppendTopology ,則輸入清單可能會有重複的拓撲;不過,它們是由其唯一區段識別碼所識別。
預先註冊清單是輸入清單拓撲的集合,已初始化以準備播放。 這可讓媒體會話在作用中拓撲結束時順暢地轉換為下一個拓撲。 應用程式無法直接從預先註冊清單中新增或移除拓撲;選取輸入清單中的拓撲以供播放時,由排序器來源產生。 這會導致排序器來源將輸入清單中的下一個拓撲新增至預先標籤清單。 這麼做之後,排序器來源會以非同步方式引發 MENewPresentation 事件,並將預先註冊拓撲的簡報描述元當做事件資料傳遞。 應用程式必須使用媒體會話的 IMFMediaEventGenerator 介面來接聽此事件,並藉由呼叫 IMFMediaSession::SetTopology ,在媒體會話上排入預編拓撲佇列。 這必須在媒體會話完成使用中拓撲的播放之前完成。 SetTopology 會通知媒體會話下一個拓撲,在播放作用中拓撲結束後,它必須播放。 為了確保順暢的轉換,應用程式必須在媒體會話完成播放先前的拓撲之前呼叫 SetTopology 。 否則,區段之間會有差距。
只要使用中拓撲之後有拓撲,即會引發 MENewPresentation 事件。 因此,如果輸入清單只包含一個拓撲,或是使用中拓撲是輸入清單中的最後一個拓撲,則不會引發此事件。
預先註冊清單會與輸入清單同步處理,而且每次在輸入清單中加入或刪除拓撲時都會重新整理。
刪除拓撲
若要從排序器來源移除拓撲,應用程式必須呼叫 IMFSequencerSource::D eleteTopology 方法,並指定區段識別碼。
呼叫 DeleteTopology 之前,應用程式必須確定媒體會話未使用應用程式想要刪除的拓撲。 若要這樣做,在應用程式呼叫 DeleteTopology 之前,必須執行下列兩項動作:
已接收具有 MF_TOPOSTATUS_ENDED 的 MESessionTopologyStatus 事件,以確保媒體會話已完成播放。
已收到具有MF_TOPOSTATUS_STARTED_SOURCE的 MESessionTopologyStatus ,讓下一個拓撲確保媒體會話已開始播放下一個拓撲, 收到 MESessionEnded 事件,以確保媒體會話是以排序器來源中的最後一個拓撲完成。
如果刪除的區段是作用中的拓撲,則會停止播放,而排序器來源會 引發 MEEndOfPresentationSegment 事件。 如果作用中的拓撲也是最後一個拓撲, 則會引發 MEEndOfPresentation 事件。
略過至區段
應用程式可以跳至序列中的特定區段,方法是啟動 具有區段位移的媒體會話 ,如下所示:
呼叫 MFCreateSequencerSegmentOffset 函式來建立區段位移。 在 dwId 參數中指定區段的 識別碼。 (識別碼是由 傳回的 當您第一次將拓撲新增至排序器來源時,IMFSequencerSource::AppendTopology 方法。hnsOffset 參數會指定相對於區段開頭的時間位移。 此時會開始播放。 針對 pvarSegmentOffset 參數,傳入空 的 PROPVARIANT 位址。 當函式傳回時,這個 PROPVARIANT 會包含區段位移。
在 媒體會話上呼叫 IMFMediaSession::Start 方法。 針對 pguidTimeFormat 參數,請使用 GUID 值MF_TIME_FORMAT_SEGMENT_OFFSET。 此值表示依區段位移搜尋。 針對 pvarStartPosition 參數,傳遞在上一個步驟中建立的 PROPVARIANT 位址。
下列程式碼範例示範如何跳至序列中指定區段的開頭。
// Skips to the specified segment in the sequencer source
HRESULT CPlaylist::SkipTo(DWORD index)
{
if (index >= m_count)
{
return E_INVALIDARG;
}
MFSequencerElementId ID = m_segments[index].SegmentID;
PROPVARIANT var;
HRESULT hr = MFCreateSequencerSegmentOffset(ID, NULL, &var);
if (SUCCEEDED(hr))
{
hr = m_pSession->Start(&MF_TIME_FORMAT_SEGMENT_OFFSET, &var);
PropVariantClear(&var);
}
return hr;
}
當應用程式跨區段搜尋時,當排序器來源結束目前的區段並準備播放新區段時,應用程式會收到數個事件。 由於這些事件是以非同步方式接收,因此很難預測確切的事件順序。 這些事件如下所示:
排序器來源會針對媒體會話所略過的新區段傳送 MENewPresentation 事件。
當排序器來源結束使用中區段時,它會傳送 MEEndOfPresentationSegment 事件。
排序器來源接著會取消預先標籤拓撲。 這會導致已取消的拓撲發生下列事件:
接下來,排序器來源會傳送新區段的事件,包括各種 MESessionTopologyStatus 事件。
如果新區段不是清單上的最後一個區段,則排序器來源會重新整理預先註冊清單,並針對新的預先註冊拓撲引發另一個 MENewPresentation 。 如需預先註冊清單中拓撲的相關資訊,請參閱 關於 Sequencer 來源 。
如需排序器來源所傳送事件的詳細資訊,請參閱 Sequencer 來源事件 主題 。
相關主題