Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
[Функция, связанная с этой страницей, Windows Media Format 11 SDK, является устаревшей. Это было заменено Инструментом чтения источника и Инструментом записи приемника. Читатель источника и Записывающее устройство приемника оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует при возможности использовать новые компоненты Source Reader и Sink Writer вместо Windows Media Format 11 SDK. Корпорация Майкрософт предлагает, что существующий код, использующий устаревшие API, будет перезаписан для использования новых API, если это возможно.]
В этом разделе описывается, как отправлять данные ASF через сеть с помощью протокола HTTP. Для отправки файлов через сеть требуется использование объекта записи, поэтому перед чтением этого раздела необходимо иметь общее представление об этом объекте. Для получения дополнительных сведений см. раздел Запись файлов 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)Подключите сетевой приемник к Writer, вызвав IWMWriterAdvanced::AddSink с указателем на интерфейс IWMWriterNetworkSink.
IWMWriterAdvanced *pWriterAdvanced; hr = pWriter->QueryInterface(IID_IWMWriterAdvanced, ( void** ) pWriterAdvanced ); if (SUCCEEDED(hr)) { pWriterAdvanced->AddSink(pNetSink); }Задайте профиль ASF, вызвав метод IWMWriter::SetProfile для объекта записи с помощью указателя IWMProfile. Сведения о создании профиля см. в разделе Работы с профилями.
При необходимости укажите метаданные с помощью интерфейса 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-файла. Пример WMVNetWrite, предоставленный в пакете SDK, демонстрирует этот подход. Помимо описанных ранее шагов сделайте следующее:
Создайте объект чтения и вызовите метод open с именем файла.
Вызов функции IWMReaderAdvanced::SetManualStreamSelection на объекте чтения со значением TRUE. Это позволяет приложению считывать каждый поток в файле, включая потоки с взаимным исключением.
Запросите средство чтения для интерфейса IWMProfile. Используйте этот указатель при вызове IWMWriter::SetProfile в объекте записи (шаг 5 в предыдущей процедуре).
Для каждого потока, определенного в профиле, вызовите IWMProfile::GetStream, чтобы получить номер потока. Передайте этот номер потока метода IWMReaderAdvanced::SetReceiveStreamSamples. Этот метод информирует читателя о необходимости доставить сжатые образцы, вместо декодирования их. Примеры будут доставлены в приложение с помощью метода обратного вызова IWMReaderCallbackAdvanced::OnStreamSample .
Перед трансляцией необходимо получить сведения о кодеке для каждого потока, считываемого без сжатия, и добавить его в заголовок. Чтобы получить сведения о кодеке, вызовите IWMHeaderInfo2::GetCodecInfoCount и IWMHeaderInfo2::GetCodecInfo, чтобы перечислить кодеки, связанные с файлом в средстве чтения. Выберите сведения кодека, соответствующие конфигурации потока. Затем задайте сведения кодека в записывающем устройстве, вызвав IWMHeaderInfo3::AddCodecInfo, передав сведения, полученные от устройства чтения.
После настройки профиля на писателе вызовите IWMWriter::GetInputCount, чтобы получить количество входов. Для каждого ввода вызовите IWMWriter::SetInputProps со значением NULL. Это указывает объекту записи, что приложение будет доставлять сжатые образцы, поэтому записи не нужно использовать кодеки для сжатия данных. Убедитесь, что вызываете SetInputProps перед вызовом BeginWriting.
При необходимости скопируйте атрибуты метаданных из считывателя в записывающее устройство.
Так как примеры из средства чтения уже сжаты, используйте метод IWMWriterAdvanced::WriteStreamSample для записи примеров вместо метода WriteSample. Метод WriteStreamSample пропускает обычные процедуры сжатия объекта записи.
Когда средство чтения достигнет конца файла, оно отправляет в приложение уведомление WMT_EOF.
Кроме того, приложение должно управлять часами в объекте чтения, чтобы читатель извлекает данные из файла как можно быстрее. Для этого вызовите метод IWMReaderAdvanced::SetUserProvidedClock для средства чтения со значением TRUE. Когда ридер отправляет уведомление WMT_STARTED, вызовите IWMReaderAdvanced::DeliverTime и укажите интервал времени, который должен воспроизводить ридер. После завершения чтения этого интервала времени он вызывает метод приложения 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;
}
Связанные разделы