ASF データのブロードキャスト
このトピックでは、HTTP プロトコルを使用してネットワーク経由で ASF データを送信する方法について説明します。 ネットワーク経由でファイルを送信するにはライター オブジェクトを使用する必要があるため、このトピックを読む前に、このオブジェクトについて一般的に理解しておく必要があります。 詳細については、「 ASF ファイルの書き込み」を参照してください。
圧縮されていないデータから始める場合は、次の操作を行います。
WMCreateWriter 関数を呼び出してライター オブジェクトを作成します。 この関数は IWMWriter ポインターを返します。
IWMWriter *pWriter; hr = WMCreateWriter(NULL, &pWriter);
IWMWriterNetworkSink ポインターを返す WMCreateWriterNetworkSink 関数を呼び出して、ネットワーク シンク オブジェクトを作成します。
IWMWriterNetworkSink *pNetSink; hr = WMCreateWriterNetworkSink(&pNetSink);
ネットワーク シンクで IWMWriterNetworkSink::Open を呼び出し、開くポート番号を指定します。たとえば、8080 などです。 必要に応じて、 IWMWriterNetworkSink::GetHostURL を呼び出して、ホストの URL を取得します。 クライアントはこの URL からコンテンツにアクセスします。 IWMWriterNetworkSink::SetMaximumClients を呼び出して、クライアントの数を制限することもできます。
DWORD dwPortNum = 8080; hr = pNetSink->Open( &dwPortNum)
ネットワーク シンクをライターにアタッチするには、ネットワーク シンクの IWMWriterNetworkSink インターフェイスへのポインターを使用して、ライターで IWMWriterAdvanced::AddSink を呼び出します。
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 コンテンツをネットワーク経由でストリーミングするもう 1 つの方法は、既存の ASF ファイルからそれを読み取る方法です。 SDK で提供される WMVNetWrite サンプルは、このアプローチを示しています。 前述の手順に加えて、次の操作を行います。
リーダー オブジェクトを作成し、ファイルの名前を指定して Open メソッドを呼び出します。
リーダー オブジェクトで、値 TRUE を指定して IWMReaderAdvanced::SetManualStreamSelection を呼び出します。 これにより、アプリケーションはファイル内のすべてのストリーム (相互除外を含むストリームを含む) を読み取ります。
リーダーに IWMProfile インターフェイスのクエリを実行します。 ライター オブジェクトで IWMWriter::SetProfile を呼び出すときに、このポインターを使用します (前の手順の手順 5)。
プロファイルで定義されているすべてのストリームについて、 IWMProfile::GetStream を呼び出してストリーム番号を取得します。 このストリーム番号をリーダーの IWMReaderAdvanced::SetReceiveStreamSamples メソッドに渡します。 このメソッドは、圧縮されたサンプルをデコードするのではなく、圧縮されたサンプルを配信するようにリーダーに通知します。 サンプルは、アプリケーションの IWMReaderCallbackAdvanced::OnStreamSample コールバック メソッドを介してアプリケーションに配信されます。
圧縮されていないストリームを読み取るたびにコーデック情報を取得し、ブロードキャストする前にヘッダーに追加する必要があります。 コーデック情報を取得するには、 IWMHeaderInfo2::GetCodecInfoCount と IWMHeaderInfo2::GetCodecInfo を呼び出して、リーダー内のファイルに関連付けられているコーデックを列挙します。 ストリーム構成に一致するコーデック情報を選択します。 次に、 IWMHeaderInfo3::AddCodecInfo を呼び出してライターにコーデック情報を設定し、リーダーから取得した情報を渡します。
ライターでプロファイルを設定した後、ライターで IWMWriter::GetInputCount を呼び出して、入力の数を取得します。 入力ごとに、値 NULL を指定して IWMWriter::SetInputProps を呼び出 します。 これは、アプリケーションが圧縮されたサンプルを提供することをライター オブジェクトに示します。そのため、ライターはコーデックを使用してデータを圧縮する必要はありません。 BeginWriting を呼び出す前に、必ず SetInputProps を呼び出してください。
必要に応じて、リーダーからライターにメタデータ属性をコピーします
リーダーのサンプルは既に圧縮されているため、WriteSample メソッドではなく IWMWriterAdvanced::WriteStreamSample メソッドを使用してサンプルを書き込みます。 WriteStreamSample メソッドは、ライター オブジェクトの通常の圧縮プロシージャをバイパスします。
リーダーは、ファイルの末尾に達すると、WMT_EOF通知をアプリケーションに送信します。
さらに、リーダーが可能な限り迅速にファイルからデータをプルできるように、アプリケーションはリーダー オブジェクトのクロックを駆動する必要があります。 これを行うには、リーダーの IWMReaderAdvanced::SetUserProvidedClock メソッドを呼び出し、値 TRUE を指定します。 リーダーがWMT_STARTED通知を送信 したら、IWMReaderAdvanced::D eliverTime を呼び出し、リーダーが配信する時間間隔を指定します。 この時間間隔の読み取りが完了すると、アプリケーションの IWMReaderCallbackAdvanced::OnTime コールバック メソッドが呼び出されます。 アプリケーションは、次の時間間隔を読み取るために DeliverTime をもう一度呼び出す必要があります。 たとえば、ファイルから 1 秒間隔で読み取る場合:
// 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;
}
関連トピック