共用方式為


廣播 ASF 數據

[與此頁面相關聯的功能 Windows Media Format 11 SDK是舊版功能。 來源讀取器終端寫入器已經取代了它。 來源讀取器接收寫入器 已針對 Windows 10 和 Windows 11 優化。 Microsoft 強烈建議,新程式碼盡可能使用 Source ReaderSink Writer 來取代 Windows Media Format 11 SDK。 Microsoft建議使用舊版 API 的現有程式代碼,盡可能改寫成使用新的 API。]

本主題描述如何使用 HTTP 通訊協定,跨網路傳送 ASF 數據。 透過網路傳送檔案需要使用寫入器物件,因此在閱讀本主題之前,您應該先大致了解這個物件。 如需更多資訊,請參閱 撰寫 ASF 檔案

如果您從未壓縮的數據開始,請執行下列動作:

  1. 呼叫 WMCreateWriter 函式來建立寫入器物件。 此函式會傳回 IWMWriter 指標。

    IWMWriter *pWriter;
    hr = WMCreateWriter(NULL, &pWriter);
    
  2. 呼叫 WMCreateWriterNetworkSink 函式來建立網路接收物件,此函式會傳回 IWMWriterNetworkSink 指標。

    IWMWriterNetworkSink *pNetSink;
    hr = WMCreateWriterNetworkSink(&pNetSink);
    
  3. 在網路接收器上呼叫 IWMWriterNetworkSink::Open,並指定要開啟的埠號碼;例如8080。 或者,呼叫 IWMWriterNetworkSink::GetHostURL 以取得主機的 URL。 用戶端會從此 URL 存取內容。 您也可以呼叫 IWMWriterNetworkSink::SetMaximumClients 來限制用戶端數目。

    DWORD dwPortNum = 8080;
    hr = pNetSink->Open( &dwPortNum)
    
  4. 將網路接收器附加至寫入器,方法是使用指向網路接收器的 IWMWriterNetworkSink 介面指針,呼叫寫入器上的 IWMWriterAdvanced::AddSink

    IWMWriterAdvanced *pWriterAdvanced;
    hr = pWriter->QueryInterface(IID_IWMWriterAdvanced, ( void** ) pWriterAdvanced );
    if (SUCCEEDED(hr))
    {
        pWriterAdvanced->AddSink(pNetSink);
    }
    
  5. 使用 IWMProfile 指標,在寫入器物件上呼叫 IWMWriter::SetProfile 方法來設定 ASF 配置檔。 如需建立設定檔的相關信息,請參閱 使用設定檔

  6. 選擇性地使用寫入器上的 IWMHeaderInfo 介面來指定元數據。

  7. 在寫入器上呼叫 IWMWriter::BeginWriting

    hr = pWriter->BeginWriting();
    
  8. 針對每個範例,呼叫 IWMWriter::WriteSample 方法。 指定數據流編號、表示時間、範例的持續時間,以及範例緩衝區的指標。 WriteSample 方法會壓縮範例。

  9. 完成時,請在寫入器上呼叫 IWMWriter::EndWriting

    hr = pWriter->EndWriting();
    
  10. 在寫入器上呼叫 IWMWriterAdvanced::RemoveSink 以解除網路接收物件。

    hr = pWriterAdvanced->RemoveSink(pNetSink);
    
  11. 在網路接收器上呼叫 IWMWriterNetworkSink::Close 來釋放該埠。

    hr = pNetSink->Close();
    

透過網路串流 ASF 內容的另一種方式是從現有的 ASF 檔案讀取它。 SDK 中提供的 WMVNetWrite 範例示範此方法。 除了先前所列的步驟之外,請執行下列動作:

  1. 建立讀取器對象,並以檔名呼叫Open方法。

  2. 在讀取器物件上呼叫 IWMReaderAdvanced::SetManualStreamSelection,並將值設定為 TRUE。 這可讓應用程式讀取檔案中的每個數據流,包括相互排除的數據流。

  3. 查詢 IWMProfile 介面的讀取器。 當您在寫入器物件上呼叫 IWMWriter::SetProfile 時,請使用此指標(上一個程式中的步驟 5)。

  4. 針對配置檔中定義的每個數據流,呼叫 IWMProfile::GetStream 以取得數據流號碼。 將此數據流編號傳遞至讀取器的 IWMReaderAdvanced::SetReceiveStreamSamples 方法。 此方法會通知讀取器傳遞壓縮的樣本,而不是譯碼。 範例會透過應用程式的 IWMReaderCallbackAdvanced::OnStreamSample 回呼方法傳遞至應用程式。

    您必須取得未壓縮之每個數據流的編解碼器資訊,並在廣播之前將其新增至標頭。 若要取得編解碼器資訊,請呼叫 IWMHeaderInfo2::GetCodecInfoCountIWMHeaderInfo2::GetCodecInfo 來列舉讀取器中檔案相關聯的編解碼器。 選取符合數據流組態的編解碼器資訊。 然後,呼叫 IWMHeaderInfo3::AddCodecInfo,以設定寫入器中的編解碼器資訊,並傳遞從讀取器取得的資訊。

  5. 在寫入器上設定配置檔之後,請在寫入器上呼叫 IWMWriter::GetInputCount,以取得輸入數目。 針對每個輸入,呼叫 IWMWriter::SetInputProps,並使用值 NULL 。 這向寫入器物件指出應用程式會傳遞壓縮的樣本,因此寫入器不需要使用任何編解碼器來壓縮數據。 請務必在呼叫 BeginWriting之前先呼叫 SetInputProps

  6. 選擇性地將元數據屬性從讀取器複製到寫入器

  7. 由於讀取器中的範例已經壓縮,因此請使用 IWMWriterAdvanced::WriteStreamSample 方法來撰寫範例,而不是使用 WriteSample 方法。 WriteStreamSample 方法會略過寫入器物件的一般壓縮程式。

  8. 當讀取器到達檔案結尾時,它會將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;
}

透過網路傳送 ASF 資料

與寫入器接收器合作