Поделиться через


Трансляция данных ASF

В этом разделе описывается отправка данных ASF по сети по протоколу HTTP. Для отправки файлов по сети требуется использование объекта записи, поэтому перед чтением этой статьи необходимо иметь общее представление об этом объекте. Дополнительные сведения см. в статье Запись ФАЙЛОВ 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. Подключите сетевой приемник к модулю записи, вызвав IWMWriterAdvanced::AddSink для модуля записи с указателем на интерфейс IWMWriterNetworkSink сетевого приемника.

    IWMWriterAdvanced *pWriterAdvanced;
    hr = pWriter->QueryInterface(IID_IWMWriterAdvanced, ( void** ) pWriterAdvanced );
    if (SUCCEEDED(hr))
    {
        pWriterAdvanced->AddSink(pNetSink);
    }
    
  5. Задайте профиль ASF, вызвав метод IWMWriter::SetProfile для объекта записи с указателем IWMProfile . Сведения о создании профиля см. в разделе Работа с профилями.

  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-файла. Этот подход демонстрируется в примере WMVNetWrite, предоставленном в пакете SDK. В дополнение к описанным выше действиям выполните следующие действия.

  1. Создайте объект средства чтения и вызовите метод Open с именем файла.

  2. Вызовите IWMReaderAdvanced::SetManualStreamSelection в объекте reader со значением TRUE. Это позволяет приложению считывать каждый поток в файле, включая потоки с взаимным исключением.

  3. Запросите у средства чтения интерфейс IWMProfile . Используйте этот указатель при вызове IWMWriter::SetProfile для объекта записи (шаг 5 в предыдущей процедуре).

  4. Для каждого потока, определенного в профиле, вызовите IWMProfile::GetStream , чтобы получить номер потока. Передайте этот номер потока в метод IWMReaderAdvanced::SetReceiveStreamSamples . Этот метод информирует читателя о необходимости доставлять сжатые примеры, а не декодировать их. Примеры будут доставлены в приложение с помощью метода обратного вызова IWMReaderCallbackAdvanced::OnStreamSample .

    Необходимо получить сведения о кодека для каждого считываемого потока без сжатия и добавить их в заголовок перед широковещательной трансляцией. Чтобы получить сведения о кодеке, вызовите IWMHeaderInfo2::GetCodecInfoCount и IWMHeaderInfo2::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 по сети

Работа с приемниками модуля записи