Partilhar via


Transmissão de dados ASF

[A funcionalidade associada a esta página, Windows Media Format 11 SDK, é uma funcionalidade herdada. Foi substituído pelo Source Reader e pelo Sink Writer. do Source Reader e Sink Writer foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda vivamente que o novo código utilize Source Reader e Sink Writer em vez de SDK do Windows Media Format 11, sempre que possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]

Este tópico descreve como enviar dados ASF através de uma rede usando o protocolo HTTP. O envio de arquivos através de uma rede requer o uso do objeto writer, portanto, você deve ter uma compreensão geral desse objeto antes de ler este tópico. Para obter mais informações, consulte Escrevendo arquivos ASF.

Se você estiver começando com dados não compactados, faça o seguinte:

  1. Crie o objeto writer chamando a função WMCreateWriter. Esta função retorna um ponteiro IWMWriter.

    IWMWriter *pWriter;
    hr = WMCreateWriter(NULL, &pWriter);
    
  2. Crie o objeto coletor de rede chamando a função WMCreateWriterNetworkSink , que retorna um ponteiro IWMWriterNetworkSink.

    IWMWriterNetworkSink *pNetSink;
    hr = WMCreateWriterNetworkSink(&pNetSink);
    
  3. Chame IWMWriterNetworkSink::Open no coletor de rede e especifique o número da porta a abrir; por exemplo, 8080. Opcionalmente, chame IWMWriterNetworkSink::GetHostURL para obter a URL do host. Os clientes acessarão o conteúdo desse URL. Você também pode chamar IWMWriterNetworkSink::SetMaximumClients para restringir o número de clientes.

    DWORD dwPortNum = 8080;
    hr = pNetSink->Open( &dwPortNum)
    
  4. Anexe o coletor de rede ao gravador chamando IWMWriterAdvanced::AddSink no gravador, com um ponteiro para a interface IWMWriterNetworkSink do coletor de rede.

    IWMWriterAdvanced *pWriterAdvanced;
    hr = pWriter->QueryInterface(IID_IWMWriterAdvanced, ( void** ) pWriterAdvanced );
    if (SUCCEEDED(hr))
    {
        pWriterAdvanced->AddSink(pNetSink);
    }
    
  5. Defina o perfil ASF chamando o método IWMWriter::SetProfile no objeto writer, com um ponteiroIWMProfile. Para obter informações sobre como criar um perfil, consulte Trabalhando com perfis.

  6. Opcionalmente, especifique metadados usando a interfaceIWMHeaderInfo no gravador.

  7. Ligue IWMWriter::BeginWriting sobre o escritor.

    hr = pWriter->BeginWriting();
    
  8. Para cada amostra, chame o método IWMWriter::WriteSample. Especifique o número do fluxo, o tempo de apresentação, a duração da amostra e um ponteiro para o buffer de amostra. O método WriteSample compacta os exemplos.

  9. Quando terminar, chame IWMWriter::EndWriting no escritor.

    hr = pWriter->EndWriting();
    
  10. Chame IWMWriterAdvanced::RemoveSink no gravador para desanexar o objeto do coletor de rede.

    hr = pWriterAdvanced->RemoveSink(pNetSink);
    
  11. Ligue IWMWriterNetworkSink::Feche no coletor de rede para liberar a porta.

    hr = pNetSink->Close();
    

Outra maneira de transmitir conteúdo ASF através de uma rede é lê-lo a partir de um arquivo ASF existente. O exemplo WMVNetWrite fornecido no SDK demonstra essa abordagem. Além das etapas listadas anteriormente, faça o seguinte:

  1. Crie um objeto leitor e chame o método Open com o nome do arquivo.

  2. Chame IWMReaderAdvanced::SetManualStreamSelection no objeto reader, com o valor TRUE. Isso permite que o aplicativo leia todos os fluxos no arquivo, incluindo fluxos com exclusão mútua.

  3. Consulte o leitor para a interface IWMProfile. Use esse ponteiro ao chamar IWMWriter::SetProfile no objeto writer (etapa 5 no procedimento anterior).

  4. Para cada fluxo definido no perfil, chame IWMProfile::GetStream para obter o número do fluxo. Passe esse número de fluxo para o método IWMReaderAdvanced::SetReceiveStreamSamples do leitor . Esse método informa o leitor a entregar amostras comprimidas, em vez de decodificá-las. As amostras serão entregues ao aplicativo pelo método de retorno de chamada IWMReaderCallbackAdvanced::OnStreamSample.

    Você deve obter informações de codec para cada fluxo lido sem compactação e adicioná-lo ao cabeçalho antes da transmissão. Para obter as informações de codec, chame IWMHeaderInfo2::GetCodecInfoCount e IWMHeaderInfo2::GetCodecInfo para enumerar os codecs associados ao arquivo no leitor. Selecione as informações do codec que correspondem à configuração do fluxo. Em seguida, defina as informações do codec no gravador, chamando IWMHeaderInfo3::AddCodecInfo, passando as informações obtidas do leitor.

  5. Depois de definir o perfil no gravador, chame IWMWriter::GetInputCount no gravador para obter o número de entradas. Para cada entrada, chame IWMWriter::SetInputProps com o valor NULL. Isso indica ao objeto gravador que o aplicativo fornecerá amostras compactadas, portanto, o gravador não precisa usar nenhum codecs para compactar os dados. Certifique-se de invocar SetInputProps antes de invocar BeginWriting.

  6. Opcionalmente, pode copiar os atributos dos metadados do leitor para o escritor.

  7. Como as amostras do leitor já estão compactadas, use o método IWMWriterAdvanced::WriteStreamSample para gravar as amostras, em vez do método WriteSample. O método WriteStreamSample ignora os procedimentos de compactação usuais do objeto gravador.

  8. Quando o leitor chega ao final do arquivo, ele envia uma notificação de WMT_EOF para o aplicativo.

Além disso, o aplicativo deve acionar o relógio no objeto leitor, para que o leitor extraia dados do arquivo o mais rápido possível. Para fazer isso, chame o IWMReaderAdvanced::SetUserProvidedClock método no leitor, com o valor TRUE. Depois que o leitor enviar a notificação de WMT_STARTED, chame IWMReaderAdvanced::DeliverTime e especifique o intervalo de tempo que o leitor deve processar. Após o leitor terminar de ler este intervalo de tempo, ele chama o método de retorno de chamada IWMReaderCallbackAdvanced::OnTime do aplicativo. O aplicativo deve chamar DeliverTime novamente para ler o próximo intervalo de tempo. Por exemplo, para ler o arquivo em intervalos de um segundo:

// 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;
}

Enviar Dados ASF Pela Rede

Trabalhando com o Writer Sinks