Diffusion de données ASF
Cette rubrique explique comment envoyer des données ASF sur un réseau à l’aide du protocole HTTP. L’envoi de fichiers sur un réseau nécessite l’utilisation de l’objet writer. Vous devez donc avoir une compréhension générale de cet objet avant de lire cette rubrique. Pour plus d’informations, consultez Écriture de fichiers ASF.
Si vous commencez avec des données non compressées, procédez comme suit :
Créez l’objet writer en appelant la fonction WMCreateWriter . Cette fonction retourne un pointeur IWMWriter .
IWMWriter *pWriter; hr = WMCreateWriter(NULL, &pWriter);
Créez l’objet récepteur réseau en appelant la fonction WMCreateWriterNetworkSink , qui retourne un pointeur IWMWriterNetworkSink .
IWMWriterNetworkSink *pNetSink; hr = WMCreateWriterNetworkSink(&pNetSink);
Appelez IWMWriterNetworkSink::Open sur le récepteur réseau et spécifiez le numéro de port à ouvrir ; par exemple, 8080. Si vous le souhaitez, appelez IWMWriterNetworkSink::GetHostURL pour obtenir l’URL de l’hôte. Les clients accèdent au contenu à partir de cette URL. Vous pouvez également appeler IWMWriterNetworkSink::SetMaximumClients pour limiter le nombre de clients.
DWORD dwPortNum = 8080; hr = pNetSink->Open( &dwPortNum)
Attachez le récepteur réseau au writer en appelant IWMWriterAdvanced::AddSink sur l’enregistreur, avec un pointeur vers l’interface IWMWriterNetworkSink du récepteur réseau.
IWMWriterAdvanced *pWriterAdvanced; hr = pWriter->QueryInterface(IID_IWMWriterAdvanced, ( void** ) pWriterAdvanced ); if (SUCCEEDED(hr)) { pWriterAdvanced->AddSink(pNetSink); }
Définissez le profil ASF en appelant la méthode IWMWriter::SetProfile sur l’objet writer, avec un pointeur IWMProfile . Pour plus d’informations sur la création d’un profil, consultez Utilisation des profils.
Si vous le souhaitez, spécifiez des métadonnées à l’aide de l’interface IWMHeaderInfo sur l’enregistreur.
Appelez IWMWriter::BeginWriting sur le writer.
hr = pWriter->BeginWriting();
Pour chaque exemple, appelez la méthode IWMWriter::WriteSample . Spécifiez le numéro de flux, l’heure de présentation, la durée de l’exemple et un pointeur vers l’exemple de mémoire tampon. La méthode WriteSample compresse les exemples.
Lorsque vous avez terminé, appelez IWMWriter::EndWriting sur le writer.
hr = pWriter->EndWriting();
Appelez IWMWriterAdvanced::RemoveSink sur le writer pour détacher l’objet récepteur réseau.
hr = pWriterAdvanced->RemoveSink(pNetSink);
Appelez IWMWriterNetworkSink::Close sur le récepteur réseau pour libérer le port.
hr = pNetSink->Close();
Une autre façon de diffuser du contenu ASF sur un réseau consiste à le lire à partir d’un fichier ASF existant. L’exemple WMVNetWrite fourni dans le Kit de développement logiciel (SDK) illustre cette approche. En plus des étapes répertoriées précédemment, procédez comme suit :
Créez un objet lecteur et appelez la méthode Open avec le nom du fichier.
Appelez IWMReaderAdvanced::SetManualStreamSelection sur l’objet reader, avec la valeur TRUE. Cela permet à l’application de lire chaque flux du fichier, y compris les flux avec exclusion mutuelle.
Interrogez le lecteur pour l’interface IWMProfile . Utilisez ce pointeur lorsque vous appelez IWMWriter::SetProfile sur l’objet writer (étape 5 de la procédure précédente).
Pour chaque flux défini dans le profil, appelez IWMProfile::GetStream pour obtenir le numéro de flux. Transmettez ce numéro de flux à la méthode IWMReaderAdvanced::SetReceiveStreamSamples du lecteur. Cette méthode informe le lecteur de remettre des exemples compressés, plutôt que de les décoder. Les exemples sont remis à l’application via la méthode de rappel IWMReaderCallbackAdvanced::OnStreamSample de l’application .
Vous devez obtenir des informations de codec pour chaque flux que vous lisez non compressé et l’ajouter à l’en-tête avant la diffusion. Pour obtenir les informations de codec, appelez IWMHeaderInfo2::GetCodecInfoCount et IWMHeaderInfo2::GetCodecInfo pour énumérer les codecs associés au fichier dans le lecteur. Sélectionnez les informations de codec qui correspondent à la configuration du flux. Définissez ensuite les informations de codec dans l’enregistreur en appelant IWMHeaderInfo3::AddCodecInfo, en transmettant les informations obtenues à partir du lecteur.
Après avoir défini le profil sur l’enregistreur, appelez IWMWriter::GetInputCount sur l’enregistreur pour obtenir le nombre d’entrées. Pour chaque entrée, appelez IWMWriter::SetInputProps avec la valeur NULL. Cela indique à l’objet writer que l’application fournira des exemples compressés, de sorte que l’enregistreur n’a pas besoin d’utiliser de codecs pour compresser les données. Veillez à appeler SetInputProps avant d’appeler BeginWriting.
Si vous le souhaitez, copiez les attributs de métadonnées du lecteur vers l’enregistreur
Étant donné que les exemples du lecteur sont déjà compressés, utilisez la méthode IWMWriterAdvanced::WriteStreamSample pour écrire les exemples, au lieu de la méthode WriteSample . La méthode WriteStreamSample contourne les procédures de compression habituelles de l’objet writer.
Lorsque le lecteur atteint la fin du fichier, il envoie une notification WMT_EOF à l’application.
En outre, l’application doit piloter l’horloge sur l’objet lecteur, afin que le lecteur extrait les données du fichier aussi rapidement que possible. Pour ce faire, appelez la méthode IWMReaderAdvanced::SetUserProvidedClock sur le lecteur, avec la valeur TRUE. Une fois que le lecteur a envoyé la notification WMT_STARTED, appelez IWMReaderAdvanced::D eliverTime et spécifiez l’intervalle de temps que le lecteur doit fournir. Une fois que le lecteur a terminé de lire cet intervalle de temps, il appelle la méthode de rappel IWMReaderCallbackAdvanced::OnTime de l’application. L’application doit appeler à nouveau DeliverTime pour lire l’intervalle de temps suivant. Par exemple, pour lire à partir du fichier par intervalles d’une seconde :
// 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;
}
Rubriques connexes