廣播 ASF 資料
本主題描述如何使用 HTTP 通訊協定,跨網路傳送 ASF 資料。 透過網路傳送檔案需要使用寫入器物件,因此在閱讀本主題之前,您應該對這個物件有一般瞭解。 如需詳細資訊,請參閱 撰寫 ASF 檔案。
如果您是從未壓縮的資料開始,請執行下列動作:
藉由呼叫 WMCreateWriter 函式來建立寫入器物件。 此函式會傳回 IWMWriter 指標。
IWMWriter *pWriter; hr = WMCreateWriter(NULL, &pWriter);
藉由呼叫 WMCreateWriterNetworkSink 函式來建立網路接收物件,此函式會傳回 IWMWriterNetworkSink 指標。
IWMWriterNetworkSink *pNetSink; hr = WMCreateWriterNetworkSink(&pNetSink);
在網路接收上呼叫 IWMWriterNetworkSink::Open ,並指定要開啟的埠號碼;例如,8080。 或者,呼叫 IWMWriterNetworkSink::GetHostURL 以取得主機的 URL。 用戶端會從此 URL 存取內容。 您也可以呼叫 IWMWriterNetworkSink::SetMaximumClients 來限制用戶端數目。
DWORD dwPortNum = 8080; hr = pNetSink->Open( &dwPortNum)
在寫入器上呼叫 IWMWriterAdvanced::AddSink ,並使用網路接收器 IWMWriterNetworkSink 介面的指標,將網路接收連結至寫入器。
IWMWriterAdvanced *pWriterAdvanced; hr = pWriter->QueryInterface(IID_IWMWriterAdvanced, ( void** ) pWriterAdvanced ); if (SUCCEEDED(hr)) { pWriterAdvanced->AddSink(pNetSink); }
使用IWMProfile指標在寫入器物件上呼叫IWMWriter::SetProfile方法,以設定 ASF 設定檔。 如需建立設定檔的相關資訊,請參閱 使用設定檔。
選擇性地使用寫入器上的 IWMHeaderInfo 介面來指定中繼資料。
在寫入器上呼叫 IWMWriter::BeginWriting 。
hr = pWriter->BeginWriting();
針對每個範例,呼叫 IWMWriter::WriteSample 方法。 指定資料流程編號、簡報時間、樣本的持續時間,以及範例緩衝區的指標。 WriteSample方法會壓縮範例。
完成後,請在寫入器上呼叫 IWMWriter::EndWriting 。
hr = pWriter->EndWriting();
在寫入器上呼叫 IWMWriterAdvanced::RemoveSink 以中斷網路接收物件。
hr = pWriterAdvanced->RemoveSink(pNetSink);
在網路接收上呼叫 IWMWriterNetworkSink::Close 以釋放埠。
hr = pNetSink->Close();
透過網路串流 ASF 內容的另一種方式是從現有的 ASF 檔案讀取。 SDK 中提供的 WMVNetWrite 範例示範此方法。 除了先前所列的步驟之外,請執行下列動作:
建立讀取器物件,並使用檔案名呼叫 Open 方法。
在讀取器物件上呼叫 IWMReaderAdvanced::SetManualStreamSelection ,其值為 TRUE。 這可讓應用程式讀取檔案中的每個資料流程,包括互斥的資料流程。
查詢 IWMProfile 介面的讀取器。 當您呼叫寫入器物件上的 IWMWriter::SetProfile 時,請使用這個指標, (上一個程式中的步驟 5) 。
針對設定檔中定義的每個資料流程,呼叫 IWMProfile::GetStream 以取得資料流程號碼。 將此資料流程編號傳遞至讀取器的 IWMReaderAdvanced::SetReceiveStreamSamples 方法。 此方法會通知讀者傳遞壓縮的樣本,而不是解碼。 這些範例會透過應用程式的 IWMReaderCallbackAdvanced::OnStreamSample 回呼方法傳遞至應用程式。
您必須取得您所讀取未壓縮之每個資料流程的編解碼器資訊,並在廣播之前將其新增至標頭。 若要取得編解碼器資訊,請呼叫 IWMHeaderInfo2::GetCodecInfoCount 和 IWMHeaderInfo2::GetCodecInfo 來列舉讀取器中檔案相關聯的編解碼器。 選取符合資料流程組態的編解碼器資訊。 然後呼叫 IWMHeaderInfo3::AddCodecInfo,以在寫入器中設定編解碼器資訊,並傳遞從讀取器取得的資訊。
在寫入器上設定設定檔之後,請在寫入器上呼叫 IWMWriter::GetInputCount 以取得輸入數目。 針對每個輸入,使用Null值呼叫IWMWriter::SetInputProps。 這表示應用程式將傳遞壓縮樣本的寫入器物件,因此寫入器不需要使用任何編解碼器來壓縮資料。 呼叫BeginWriting之前,請務必先呼叫SetInputProps。
選擇性地將中繼資料屬性從讀取器複製到寫入器
由於讀取器中的範例已經壓縮,所以請使用 IWMWriterAdvanced::WriteStreamSample 方法來撰寫範例,而不是 WriteSample 方法。 WriteStreamSample方法會略過寫入器物件的一般壓縮程式。
當讀取器到達檔案結尾時,會將WMT_EOF通知傳送給應用程式。
此外,應用程式應該在讀取器物件上驅動時鐘,讓讀取器儘快從檔案提取資料。 若要這樣做,請在讀取器上呼叫 IWMReaderAdvanced::SetUserProvidedClock 方法,其值為 TRUE。 讀取器傳送WMT_STARTED通知之後,呼叫 IWMReaderAdvanced::D eliverTime ,並指定讀取器應該傳遞的時間間隔。 讀取器讀取此時間間隔之後,它會呼叫應用程式的 IWMReaderCallbackAdvanced::OnTime 回呼方法。 應用程式應該再次呼叫 DeliverTime ,以讀取下一個時間間隔。 例如,若要以一秒間隔從檔案讀取:
// Initial call to DeliverTime.
QWORD m_qwTime = 10000000; // 1 second.
hr = m_pReaderAdvanced->DeliverTime(m_qwTime);
// In the callback:
HRESULT CNetWrite::OnTime(QWORD cnsCurrentTime, void *pvContext)
{
HRESULT hr = S_OK;
// Continue calling DeliverTime until the end of the file.
if(!m_bEOF)
{
m_qwTime += 10000000; // 1 second.
hr = m_pReaderAdvanced->DeliverTime(m_qwTime);
}
return S_OK;
}
相關主題