Comment créer une application de diffusion en direct et en vidéo avec WebRTC
Published: 2024-02-08 05:37:06

Qu'est-ce que le streaming vidéo WebRTC ?
-----------------------------------------

Le streaming vidéo WebRTC est un projet gratuit et open-source qui permet aux navigateurs web et aux appareils mobiles tels que iOS et Android de fournir une communication en temps réel. Cette fonctionnalité permet d'intégrer facilement dans une page web des fonctions d'application telles que la vidéoconférence peer-to-peer. Avec le streaming vidéo WebRTC, un chat vidéo basé sur un navigateur peut être conçu rapidement avec HTML et JavaScript, sans qu'aucun code d'arrière-plan ne soit nécessaire. Il s'agit d'un élément clé de l'[engagement du public en direct](https://www.pubnub.com/solutions/live-audience-engagement/) et des solutions de [collaboration multi-utilisateurs](https://www.pubnub.com/solutions/multiuser-collaboration/), qui améliore l'expérience de l'utilisateur sur des plateformes telles que les médias sociaux, les applications de diffusion vidéo en direct et les réseaux de diffusion de contenu. L'adaptabilité de WebRTC en fait un outil essentiel pour le développement d'applications, répondant à un large éventail d'applications allant des services en nuage d'Amazon à la vidéo à la demande de Netflix, en passant par la plateforme de streaming de Twitch, Facebook Live et les fonctions interactives sur Hulu, Spotify et les appareils Apple.

![](https://www.pubnub.com/cdn/3prze68gbwl1/3zeNU3Nn3bvFIa3CxPAK0H/ac3b96f11d8b13ae8157150e39a4b910/webrtc-video-call-chatengine.jpg)

Comment fonctionne la diffusion vidéo WebRTC ?
----------------------------------------------

WebRTC permet aux utilisateurs de diffuser de l'audio et de la vidéo en peer-to-peer dans les navigateurs web modernes. Cette fonctionnalité est prise en charge par les dernières versions de Chrome, FireFox, Edge, Safari et Opera sur les ordinateurs de bureau, ainsi que par les navigateurs web natifs iOS et Android. C'est la base des solutions de [streaming de données](https://www.pubnub.com/solutions/data-streaming/) fournies par PubNub.

Pour faire de l'appareil d'un utilisateur un client WebRTC, il suffit d'initialiser un nouvel objet `RTCPeerConnection()` dans le JavaScript frontal.

Architecture du streaming en direct WebRTC
------------------------------------------

Le chat vidéo est établi sur deux appareils clients ou plus à l'aide du protocole WebRTC. La connexion peut être établie selon l'un des deux modes suivants. Le premier mode est le mode pair-à-pair, ce qui signifie que les paquets audio et vidéo sont diffusés directement de client à client avec la [configuration RTC](https://developer.mozilla.org/en-US/docs/Web/API/RTCConfiguration). Cette configuration fonctionne tant que les deux machines ont une adresse IP accessible par l'internet public.

Toutefois, il n'est pas judicieux de s'appuyer sur des connexions peer-to-peer pour le chat vidéo et la conférence dans le navigateur dans les applications de production. Il est fréquent que le cadre ICE (Interactive Connectivity Establishment) ne parvienne pas à établir une connexion entre deux utilisateurs lorsque l'un d'entre eux, ou les deux, se trouvent derrière un système de sécurité LAN avancé.

Pour pallier ce problème, vous pouvez configurer votre RTCConfiguration de manière à ce qu'elle tente d'abord une connexion d'égal à égal, puis qu'elle se rabatte sur une connexion relayée en cas d'échec de cette dernière.

![](https://www.pubnub.com/cdn/3prze68gbwl1/asset-17suaysk1qa1jcu/afcb88a1d7f5aaaaebe8c91413347091/webrtc-p2p-stun-pubnub.png)

Si les adresses IP accessibles au public ne sont pas une option, une connexion WebRTC doit être établie via un serveur TURN. Le cadre ICE décidera si cela est nécessaire lorsque les utilisateurs essaieront de se connecter.

Ne construisez pas un serveur de signalisation WebRTC pour votre diffusion en direct - utilisez PubNub
------------------------------------------------------------------------------------------------------

WebRTC laisse de côté un composant très important du streaming de chat vidéo. Un client doit utiliser un service de signalisation pour communiquer des messages avec son ou ses pairs. PubNub permet à un développeur d'implémenter entièrement, et à moindre coût, des fonctionnalités telles qu'un service de signalisation WebRTC. Cela est facilité par la [documentation](https://www.pubnub.com/docs) complète de PubNub sur la configuration de votre compte et l'envoi/réception de messages.

### Exemples de chat vidéo en streaming avec WebRTC

Ces messages concernent des événements tels que :

-   Moi, utilisateur A, j'aimerais vous appeler, utilisateur B.
    
-   L'utilisateur A est en train d'essayer de vous appeler, utilisateur B
    
-   Je, Utilisateur B, accepte votre appel Utilisateur A
    
-   Je, Utilisateur B, rejette votre appel Utilisateur A
    
-   Je, Utilisateur B, souhaite mettre fin à notre appel Utilisateur A
    
-   Je, Utilisateur A, souhaite mettre fin à notre appel Utilisateur B
    
-   Messagerie instantanée textuelle comme dans Slack, Google Hangouts, Skype, Facebook Messenger, etc.
    
-   Session Codec audio/vidéo et données de connectivité de l'utilisateur.
    

Ces messages font partie du **flux de transactions de signalisation** qui est décrit dans la [documentation du Mozilla Developer Network pour Web](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Signaling_and_video_calling)RTC.Le serveur de signalisation WebRTC est un concept abstrait. De nombreux services peuvent devenir ce "serveur de signalisation", comme WebSockets, Socket.IO ou PubNub. Si vous êtes chargé de créer une solution pour cela, vous finirez par vous poser des questions : Faut-il construire ou acheter ?

### Pourquoi PubNub : Extensions logiques comme le streaming vidéo WebRTC one-to-many

PubNub permet à un développeur comme vous de mettre en œuvre un service de signalisation WebRTC de manière complète et peu coûteuse. Une [bibliothèque WebRTC Open Source qui utilise PubNub](https://github.com/stephenlb/webrtc-sdk) est disponible sur GitHub. Cependant, la solution de streaming de données PubNub suivante est encore plus rapide que la construction avec le SDK WebRTC, car notre plateforme vous permet de construire rapidement et facilement une application qui supporte le streaming un-à-plusieurs à n'importe quelle échelle.

Package soutenu par la communauté pour les appels vidéo WebRTC
--------------------------------------------------------------

PubNub est comme un CDN global pour les données en temps réel. Les développeurs peuvent utiliser son [IaaS](https://www.pubnub.com/learn/glossary/what-is-infrastructure-as-a-service-iaas/) pour créer des plateformes de streaming en temps réel de haute qualité, des applications mobiles et bien plus encore. Des SDK PubNub sont disponibles pour tous les langages de programmation et tous les appareils, permettant des connexions pub/sub fiables, la livraison de données et le contrôle du réseau, le tout en quelques lignes de code.

Tutoriel d'application de streaming vidéo WebRTC avec Javascript, HTML, CSS
---------------------------------------------------------------------------

Dans ce tutoriel, nous utiliserons JavaScript, HTML et CSS pour construire notre application de chat vidéo. Cependant, si vous souhaitez utiliser un framework front-end moderne comme Vue, [React](https://www.pubnub.com/docs/chat/sdks/messages/sending-messages), ou Angular, vous pouvez consulter la [page des tutoriels PubNub](https://www.pubnub.com/blog/category/build/) mis à jour ou le [centre de ressources PubNub Chat](https://www.pubnub.com/docs/chat/overview). Nous disposons également d'une équipe de développement substantielle disponible pour consultation.

Pour commencer, vous pouvez utiliser le [HTML](https://github.com/ajb413/pubnub-js-webrtc/blob/master/example/index.html) et le [CSS](https://github.com/ajb413/pubnub-js-webrtc/blob/master/example/style.css) de mon exemple de projet. Ces fichiers présentent une interface utilisateur d'application de chat vidéo très générique. L'application d'exemple n'a qu'un seul chat global et aucun chat privé 1:1, bien qu'ils soient faciles à mettre en œuvre.

Application de streaming vidéo WebRTC HTML
------------------------------------------

Ouvrez **index.html** avec votre éditeur de texte favori. **Remplacez les** balises de script sous la balise body de votre fichier HTML par ces 2 scripts CDN. Laissez la troisième balise de script qui fait référence à **app.js.** Nous écrirons ce fichier ensemble.

```js
<script type="text/javascript" src="https://cdn.pubnub.com/sdk/javascript/pubnub.4.32.0.js"></script>
<script src="https://cdn.jsdelivr.net/npm/pubnub-js-webrtc@latest/dist/pubnub-js-webrtc.js"></script>
```

L'étape suivante consiste à créer votre propre fichier app.js dans le même répertoire que votre fichier index.html. La raison pour laquelle nous devons créer un nouveau fichier app.js est que le script de mon exemple utilise [Xirsys](https://xirsys.com/). Mon compte privé est relié à mon serveur Functions. Vous devrez créer votre propre serveur back-end et votre propre compte si vous souhaitez utiliser un fournisseur TURN comme Xirsys. Mon prochain article de blog contiendra un tutoriel pour construire des applications WebRTC avec TURN.

Le script app.js que nous écrirons ensemble n'utilisera que des connexions WebRTC peer-to-peer gratuites. Si vous essayez de faire un appel vidéo en direct avec 2 appareils sur le même réseau local, votre application fonctionnera. Il n'est pas certain qu'une connexion d'appel vidéo puisse être établie avec des clients situés sur des réseaux distincts (en raison de la sécurité NAT). C'est pourquoi il est essentiel de bien comprendre les protocoles de diffusion en continu.

### WebRTC streaming vidéo app javascript

Tout d'abord, nous allons faire référence à tous les éléments du DOM à partir du fichier index.html. Une fois que nous pouvons y faire référence dans notre code JavaScript, nous pouvons les manipuler par programme.

```js
const chatInterface = document.getElementById('chat-interface');
const myVideoSample = document.getElementById('my-video-sample');
const myVideo = document.getElementById('my-video');
const remoteVideo = document.getElementById('remote-video');
const videoModal = document.getElementById('video-modal');
const closeVideoButton = document.getElementById('close-video');
const brokenMyVideo = document.getElementById('broken-my-video');
const brokenSampleVideo = document.getElementById('broken-sample-video');
const usernameModal = document.getElementById('username-input-modal');
const usernameInput = document.getElementById('username-input');
const joinButton = document.getElementById('join-button');
const callConfirmModal = document.getElementById('call-confirm-modal');
const callConfirmUsername = document.getElementById('call-confirm-username');
const yesCallButton = document.getElementById('yes-call');
const noCallButton = document.getElementById('no-call');
const incomingCallModal = document.getElementById('incoming-call-modal');
const callFromSpan = document.getElementById('call-from');
const acceptCallButton = document.getElementById('accept-call');
const rejectCallButton = document.getElementById('reject-call');
const onlineList = document.getElementById('online-list');
const chat = document.getElementById('chat');
const log = document.getElementById('log');
const messageInput = document.getElementById('message-input');
const submit = document.getElementById('submit');
```

Ensuite, nous allons ajouter quelques variables qui contiennent un nom de classe CSS, des informations globales sur l'application et des informations sur la configuration WebRTC. Dans le dictionnaire RTCConfiguration, nous ajoutons les informations des serveurs STUN et TURN pour les appels WebRTC. Il s'agit d'une étape cruciale pour un contenu vidéo de haute qualité dans votre service de streaming.

```js
const hide = 'hide';
// PubNub Channel for sending/receiving global chat messages
//     also used for user presence with Presence
const globalChannel = 'global-channel';
let webRtcPhone;
let pubnub;
// An RTCConfiguration dictionary from the browser WebRTC API
// Add STUN and TURN server information here for WebRTC calling
const rtcConfig = {};
let username; // User's name in the app
let myAudioVideoStream; // Local audio and video stream
let noVideoTimeout; // Used to check if a video connection succeeded
const noVideoTimeoutMS = 5000; // Error alert if the video fails to connect
```

Nous allons maintenant aborder une partie du code client impératif pour la fonctionnalité du paquet WebRTC. C'est là que l'aspect temps réel de votre plateforme de streaming vidéo entre en jeu.

```js
// Init the audio and video stream on this client
getLocalStream().then((localMediaStream) => {
    myAudioVideoStream = localMediaStream;
    myVideoSample.srcObject = myAudioVideoStream;
    myVideo.srcObject = myAudioVideoStream;
}).catch(() => {
    myVideo.classList.add(hide);
    myVideoSample.classList.add(hide);
    brokenMyVideo.classList.remove(hide);
    brokenSampleVideo.classList.remove(hide);
});
// Prompt the user for a username input
getLocalUserName().then((myUsername) => {
    username = myUsername;
    usernameModal.classList.add(hide);
    initWebRtcApp();
});
// Send a chat message when Enter key is pressed
messageInput.addEventListener('keydown', (event) => {
    if (event.keyCode === 13 && !event.shiftKey) {
        event.preventDefault();
        sendMessage();
        return;
    }
});
// Send a chat message when the submit button is clicked
submit.addEventListener('click', sendMessage);
const closeVideoEventHandler = (event) => {
    videoModal.classList.add(hide);
    chatInterface.classList.remove(hide);
    clearTimeout(noVideoTimeout);
    webRtcPhone.disconnect(); // disconnects the current phone call
}
// Register a disconnect event handler when the close video button is clicked
closeVideoButton.addEventListener('click', closeVideoEventHandler);
```

Le nouveau code que nous venons d'ajouter

-   demande au navigateur s'il peut accéder à la webcam et au microphone de l'ordinateur, et stocke l'objet stream dans une variable globale.
    
-   Demande à l'utilisateur un "nom d'utilisateur" dans l'application avant d'initialiser la partie WebRTC de l'application.
    
-   Enregistre des gestionnaires d'événements pour les messages de chat, par exemple lorsqu'un utilisateur clique sur le bouton d'envoi ou appuie sur la touche Entrée.
    
-   Crée un autre gestionnaire d'événements pour la fermeture du chat vidéo par l'utilisateur.
    

Ensuite, nous allons ajouter le code d'initialisation pour la partie WebRTC de l'application web. Dans cette partie, nous initialisons notre instance PubNub avec la dernière version du SDK 4.32.0.

```js
const initWebRtcApp = () => {
    // WebRTC phone object event for when the remote peer's video becomes available.
    const onPeerStream = (webRTCTrackEvent) => {
        console.log('Peer audio/video stream now available');
        const peerStream = webRTCTrackEvent.streams[0];
        window.peerStream = peerStream;
        remoteVideo.srcObject = peerStream;
    };
    // WebRTC phone object event for when a remote peer attempts to call you.
    const onIncomingCall = (fromUuid, callResponseCallback) => {
        let username = document.getElementById(fromUuid).children[1].innerText;
        incomingCall(username).then((acceptedCall) => {
            if (acceptedCall) {
                // End an already open call before opening a new one
                webRtcPhone.disconnect();
                videoModal.classList.remove(hide);
                chatInterface.classList.add(hide);
                noVideoTimeout = setTimeout(noVideo, noVideoTimeoutMS);
            }
            callResponseCallback({ acceptedCall });
        });
    };
    // WebRTC phone object event for when the remote peer responds to your call request.
    const onCallResponse = (acceptedCall) => {
        console.log('Call response: ', acceptedCall ? 'accepted' : 'rejected');
        if (acceptedCall) {
            videoModal.classList.remove(hide);
            chatInterface.classList.add(hide);
            noVideoTimeout = setTimeout(noVideo, noVideoTimeoutMS);
        }
    };
    // WebRTC phone object event for when a call disconnects or timeouts.
    const onDisconnect = () => {
        console.log('Call disconnected');
        videoModal.classList.add(hide);
        chatInterface.classList.remove(hide);
        clearTimeout(noVideoTimeout);
    };
    // Lists the online users in the UI and registers a call method to the click event
    //     When a user clicks a peer's name in the online list, the app calls that user.
    const addToOnlineUserList = (occupant) => {
        const userId = occupant.uuid;
        const name = occupant.state ? occupant.state.name : null;
        if (!name) return;
        const userListDomElement = createUserListItem(userId, name);
        const alreadyInList = document.getElementById(userId);
        const isMe = pubnub.getUUID() === userId;
        if (alreadyInList) {
            removeFromOnlineUserList(occupant.uuid);
        } 
        if (isMe) {
            return;
        }
        onlineList.appendChild(userListDomElement);
        userListDomElement.addEventListener('click', (event) => {
            const userToCall = userId;
            confirmCall(name).then((yesDoCall) => {
                if (yesDoCall) {
                    webRtcPhone.callUser(userToCall, {
                        myStream: myAudioVideoStream
                    });
                }
            });
        });
    }
    const removeFromOnlineUserList = (uuid) => {
        const div = document.getElementById(uuid);
        if (div) div.remove();
    };
    pubnub = new PubNub({
        publishKey : '_YOUR_PUBNUB_PUBLISH_API_KEY_HERE_',
        subscribeKey : '_YOUR_PUBNUB_SUBSCRIBE_API_KEY_HERE_'
    });
    // This PubNub listener powers the text chat and online user list population.
    pubnub.addListener({
        message: function(event) {
            // Render a global chat message in the UI
            if (event.channel === globalChannel) {
                renderMessage(event);
            }
        },
        status: function(statusEvent) {
            if (statusEvent.category === "PNConnectedCategory") {
                pubnub.setState({
                    state: {
                        name: username
                    },
                    channels: [globalChannel],
                    uuid: pubnub.getUUID()
                });
                pubnub.hereNow({
                    channels: [globalChannel],
                    includeUUIDs: true,
                    includeState: true
                },
                (status, response) => {
                    response.channels[globalChannel].occupants
                        .forEach(addToOnlineUserList);
                });
            }
        },
        presence: (status, response) => {
            if (status.error) {
                console.error(status.error);
            } else if (status.channel === globalChannel) {
                if (status.action === "join") {
                    addToOnlineUserList(status, response);
                } else if (status.action === "state-change") {
                    addToOnlineUserList(status, response);
                } else if (status.action === "leave") {
                    removeFromOnlineUserList(status.uuid);
                } else if (status.action === "timeout") {
                    removeFromOnlineUserList(response.uuid);
                }
            }
        }
    });
    pubnub.subscribe({
        channels: [globalChannel],
        withPresence: true
    });
    window.ismyuuid = pubnub.getUUID();
    // Disconnect PubNub before a user navigates away from the page
    window.onbeforeunload = (event) => {
        pubnub.unsubscribe({
            channels: [globalChannel]
        });
    };
    // WebRTC phone object configuration.
    let config = {
        rtcConfig,
        ignoreNonTurn: false,
        myStream: myAudioVideoStream,
        onPeerStream,   // is required
        onIncomingCall, // is required
        onCallResponse, // is required
        onDisconnect,   // is required
        pubnub          // is required
    };
    webRtcPhone = new WebRtcPhone(config);
};
```

Dans le code d'initialisation de la partie WebRTC de l'application web, nous avons fait quelques mises à jour pour refléter les dernières fonctionnalités offertes par PubNub. Il s'agit d'un élément essentiel pour garantir la compatibilité de votre application de streaming vidéo avec les dernières tendances technologiques.

Le code que nous venons d'ajouter à app.js s'exécute après que l'utilisateur a saisi son "nom d'utilisateur" :

-   déclare tous les gestionnaires d'événements du plugin pour les événements d'appel WebRTC
    
-   Ajoute et supprime les éléments de la liste des utilisateurs en ligne au fur et à mesure que les utilisateurs se connectent et se déconnectent de l'application.
    
-   Enregistre un gestionnaire d'événements pour passer un nouvel appel vidéo à un utilisateur chaque fois que son nom est cliqué dans l'interface utilisateur de la liste.
    
-   Enregistre un gestionnaire d'événements pour rendre les nouveaux messages de chat chaque fois qu'un message est envoyé au chat global, en temps réel.
    
-   Configure PubNub pour envoyer et écouter les messages en temps réel avec le [modèle de messagerie Pub/Sub](https://www.pubnub.com/products/pubnub-platform/)
    
-   Initialise le paquet WebRTC et transmet l'objet de configuration à l'instance.
    

Avant de continuer, il est important de noter que nous devons insérer nos clés API PubNub gratuites dans cette fonction. Nous pouvons obtenir des clés gratuites pour toujours en utilisant le formulaire d'inscription ci-dessous. Ces clés sont gratuites jusqu'à 1 million de transactions par mois, ce qui est idéal pour les amateurs ou les applications professionnelles de validation de concept.

Vous pouvez insérer vos clés API Pub/Sub dans le fichier app.js dans l'objet d'initialisation PubNub, comme vous pouvez le voir dans l'extrait de code précédent.

```js
pubnub = new PubNub({
    publishKey : 'PUBLISH_KEY',
    subscribeKey : 'SUBSCRIBE_KEY',
    uuid: "UUID"
});
```

Nous devons **activer la fonctionnalité Presence** dans le tableau de bord d'administration de PubNub. Lorsque vous créez un jeu de clés PubNub, la fonction de Présence est désactivée par défaut sur la clé. Nous pouvons l'activer pour la clé en allant dans le [PubNub Admin Dashboard](https://dashboard.pubnub.com/) et en cliquant sur l'interrupteur à bascule. Pour en savoir plus sur la fonction de présence et ses possibilités, consultez notre [documentation](https://www.pubnub.com/docs/general/presence/overview).

L'application d'exemple utilise la [présence](https://www.pubnub.com/docs/general/presence/overview) pour montrer quels utilisateurs sont en ligne dans l'application. Nous utilisons l'UUID de l'utilisateur PubNub pour conserver des références uniques à chaque utilisateur dans l'application. Lorsque nous effectuons un appel vidéo WebRTC, nous utilisons l'UUID pour que les deux utilisateurs puissent afficher le nom d'utilisateur correspondant dans leur interface utilisateur.

Ensuite, nous aurons besoin de quelques méthodes utilitaires pour exécuter des fonctionnalités spécifiques à l'interface utilisateur. Ces méthodes ne sont pas spécifiques à toutes les applications WebRTC, elles ne servent qu'à faire fonctionner l'interface utilisateur que j'ai conçue. Ajoutez ce code à la fin du fichier app.js.

```js
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// UI Render Functions
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
function renderMessage(message) {
    const messageDomNode = createMessageHTML(message);
    log.append(messageDomNode);
    // Sort messages in chat log based on their timetoken (value of DOM id)
    sortNodeChildren(log, 'id');
    chat.scrollTop = chat.scrollHeight;
}
function incomingCall(name) {
    return new Promise((resolve) => {
        acceptCallButton.onclick = function() {
            incomingCallModal.classList.add(hide);
            resolve(true);
        }
        rejectCallButton.onclick = function() {
            incomingCallModal.classList.add(hide);
            resolve(false);
        }
        callFromSpan.innerHTML = name;
        incomingCallModal.classList.remove(hide);
    });
}
function confirmCall(name) {
    return new Promise((resolve) => {
        yesCallButton.onclick = function() {
            callConfirmModal.classList.add(hide);
            resolve(true);
        }
        noCallButton.onclick = function() {
            callConfirmModal.classList.add(hide);
            resolve(false);
        }
        callConfirmUsername.innerHTML = name;
        callConfirmModal.classList.remove(hide);
    });
}
function getLocalUserName() {
    return new Promise((resolve) => {
        usernameInput.focus();
        usernameInput.value = '';
        usernameInput.addEventListener('keyup', (event) => {
            const nameLength = usernameInput.value.length;
            if (nameLength > 0) {
                joinButton.classList.remove('disabled');
            } else {
                joinButton.classList.add('disabled');
            }
            if (event.keyCode === 13 && nameLength > 0) {
                resolve(usernameInput.value);
            }
        });
        joinButton.addEventListener('click', (event) => {
            const nameLength = usernameInput.value.length;
            if (nameLength > 0) {
                resolve(usernameInput.value);
            }
        });
    });
}
function getLocalStream() {
    return new Promise((resolve, reject) => {
        navigator.mediaDevices
        .getUserMedia({
            audio: true,
            video: true
        })
        .then((avStream) => {
            resolve(avStream);
        })
        .catch((err) => {
            alert('Cannot access local camera or microphone.');
            console.error(err);
            reject();
        });
    });
}
function createUserListItem(userId, name) {
    const div = document.createElement('div');
    div.id = userId;
    const img = document.createElement('img');
    img.src = './phone.png';
    const span = document.createElement('span');
    span.innerHTML = name;
    div.appendChild(img);
    div.appendChild(span);
    return div;
}
function createMessageHTML(messageEvent) {
    const text = messageEvent.message.text;
    const jsTime = parseInt(messageEvent.timetoken.substring(0,13));
    const dateString = new Date(jsTime).toLocaleString();
    const senderUuid = messageEvent.publisher;
    const senderName = senderUuid === pubnub.getUUID()
        ? username
        : document.getElementById(senderUuid).children[1].innerText;
    const div = document.createElement('div');
    const b = document.createElement('b');
    div.id = messageEvent.timetoken;
    b.innerHTML = `${senderName} (${dateString}): `;
    div.appendChild(b);
    div.innerHTML += text;
    return div;
}
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Utility Functions
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
function sendMessage() {
    const messageToSend = messageInput.value.replace(/?
|/g, '');
    const trimmed = messageToSend.replace(/(\s)/g, '');
    if (trimmed.length > 0) {
        pubnub.publish({
            channel: globalChannel,
            message: {
                text: messageToSend
            }
        });
    }
    messageInput.value = '';
}
// Sorts sibling HTML elements based on an attribute value
function sortNodeChildren(parent, attribute) {
    const length = parent.children.length;
    for (let i = 0; i < length-1; i++) {
        if (parent.children[i+1][attribute] < parent.children[i][attribute]) {
            parent.children[i+1].parentNode
                .insertBefore(parent.children[i+1], parent.children[i]);
            i = -1;
        }
    }
}
function noVideo() {
    const message = 'No peer connection made.
' +
        'Try adding a TURN server to the WebRTC configuration.';
    if (remoteVideo.paused) {
        alert(message);
        closeVideoEventHandler();
    }
}
```

### **CSS pour l'application de streaming vidéo WebRTC**

Nous avons besoin de styles CSS dans notre application pour que l'interface utilisateur soit jolie et agréable. Le fichier index.html contient déjà une référence au fichier style.css, ajoutez-le donc dans le même dossier. Le [fichier style.css](https://github.com/ajb413/pubnub-js-webrtc/blob/master/example/style.css) pour cette application WebRTC est disponible dans le dépôt GitHub.

C'est fait ! Vous pouvez maintenant déployer vos fichiers web frontaux statiques sur une plateforme d'hébergement web comme WordPress ou des [pages GitHub](https://pages.github.com/). Votre application de chat WebRTC pourra être utilisée par n'importe qui dans le monde. Le code est compatible avec les mobiles, ce qui signifie que les derniers navigateurs web sur iOS et Android seront en mesure d'exécuter l'application pour la vidéo en face à face !

**FAQ sur l'offre de streaming WebRTC**
---------------------------------------

### **Le package WebRTC fait-il officiellement partie de PubNub ?**

Non. Il s'agit d'un projet open-source soutenu par la communauté. Si vous avez des questions ou besoin d'aide, contactez [devrel@pubnub.com.](mailto:devrel@pubnub.com) Si vous souhaitez signaler un bogue, faites-le sur la [page GitHub Issues](https://github.com/ajb413/pubnub-js-webrtc/issues).

### **PubNub diffuse-t-il des données audio ou vidéo avec WebRTC ?**

Non. PubNub s'associe très bien avec WebRTC en tant que service de signalisation. Cela signifie que PubNub signale des événements de client à client en utilisant la messagerie Pub/Sub. Ces événements sont les suivants :

-   Moi, utilisateur A, j'aimerais vous appeler, utilisateur B.
    
-   L'utilisateur A est en train d'essayer de vous appeler, utilisateur B
    
-   Je, Utilisateur B, accepte votre appel Utilisateur A
    
-   Je, Utilisateur B, rejette votre appel Utilisateur A
    
-   Je, Utilisateur B, souhaite mettre fin à notre appel Utilisateur A
    
-   Je, Utilisateur A, souhaite mettre fin à notre appel Utilisateur B
    
-   Messagerie instantanée textuelle comme dans Slack, Google Hangouts, Skype, Facebook Messenger, etc.
    

### **Puis-je faire un appel de groupe avec plus de 2 participants en utilisant WebRTC et PubNub ?**

Il est possible de développer des appels de groupe avec WebRTC et PubNub, cependant, le package actuel PubNub JS WebRTC ne peut connecter que 2 utilisateurs dans un appel privé, et non un simulcast supporté par WebRTC à partir de plus de 2 utilisateurs. La communauté pourrait développer cette fonctionnalité à l'avenir, mais il n'y a aucun plan de développement à ce jour.

**Démarrer avec PubNub pour votre application WebRTC**
------------------------------------------------------

Développement de logiciels utilisant PubNub pour votre application de streaming en direct. Assurez une faible latence et des coûts de développement en vous inscrivant simplement à un compte gratuit et en intégrant nos API dans votre application WebRTC. Vous aurez rapidement un MVP de votre application de chat. Avec PubNub, vous aurez accès à [à de nombreux outils et ressources](https://www.pubnub.com/docs) pour vous aider à construire une application de chat robuste et évolutive.

Pour commencer, suivez les étapes suivantes :

-   [Créez un compte PubNub gratuit.](https://admin.pubnub.com/#/register)
    
-   [Suivez](https://www.pubnub.com/tutorials/) un tutoriel étape par étape pour configurer et construire une application de chat avec le SDK PubNub.
    
-   [Ajoutez des fonctionnalités telles que les notifications push mobiles](https://www.pubnub.com/tutorials/) à vos applications de chat iOS ou Android en suivant un [tutoriel détaillé](https://www.pubnub.com/tutorials/).
    

[Visitez nos documents pour en savoir plus sur](https://www.pubnub.com/docs) la construction de votre application web de chat en temps réel.

Comment PubNub peut-il vous aider ?
===================================

Cet article a été publié à l'origine sur [PubNub.com](https://www.pubnub.com/blog/integrating-video-calling-in-chat-with-webrtc-and-pubnub/)

Notre plateforme aide les développeurs à construire, livrer et gérer l'interactivité en temps réel pour les applications web, les applications mobiles et les appareils IoT.

La base de notre plateforme est le réseau de messagerie en temps réel le plus grand et le plus évolutif de l'industrie. Avec plus de 15 points de présence dans le monde, 800 millions d'utilisateurs actifs mensuels et une fiabilité de 99,999 %, vous n'aurez jamais à vous soucier des pannes, des limites de concurrence ou des problèmes de latence causés par les pics de trafic.

Découvrez PubNub
----------------

Découvrez le [Live Tour](https://www.pubnub.com/tour/introduction/) pour comprendre les concepts essentiels de chaque application alimentée par PubNub en moins de 5 minutes.

S'installer
-----------

Créez un [compte PubNub](https://admin.pubnub.com/signup/) pour un accès immédiat et gratuit aux clés PubNub.

Commencer
---------

La [documentation PubNub](https://www.pubnub.com/docs) vous permettra de démarrer, quel que soit votre cas d'utilisation ou votre [SDK](https://www.pubnub.com/docs).