Ich grüße alle Leser von Habr. In diesem Jahr hatte ich die Möglichkeit, ein Videokommunikationsmodul für ein Schulungsportal zum Telefonieren per Videokommunikation direkt auf der Website von Lehrern und Schülern zu schreiben. Es war nicht notwendig, eine so frühe Aufgabe zu lösen. Nach einer kurzen Suche stellte ich fest, dass es zwei Möglichkeiten gibt: Flash und
WebRTC . WebRTC in seiner reinen Form erwies sich als kompliziert, und im Allgemeinen ist es natürlich, da die Aufgabe der Videokommunikation nicht einfach ist. Aber dann bin ich auf
PeerJS gestoßen , einen Wrapper für WebRTC. In diesem Artikel werde ich Ihnen erklären, wie Sie Ihren Browser-Dialer schnell organisieren können.
Um das Beispiel zu wiederholen, ist der Zugriff auf Ihre Testseite über das https-Protokoll erforderlich (da die Seite den Zugriff auf die Kamera und das Mikrofon anfordert und der Browser ohne ein sicheres Protokoll einfach einen Fehler ausgibt).
Das Startlayout sieht folgendermaßen aus:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Peer</title> <script src="https://unpkg.com/peerjs@1.0.0/dist/peerjs.min.js"></script> </head> <body> <p><h3> ID: </h3><span id=myid ></span></p> <input id=otherPeerId type=text placeholder="otherPeerId" > <button onclick="callToNode(document.getElementById('otherPeerId').value)"></button> <br> <video id=myVideo muted="muted" width="400px" height="auto" ></video> <div id=callinfo ></div> <video id=remVideo width="400px" height="auto" ></video> </body>
Im Kopfbereich verbinden wir PeerJS remote. Es ist auch möglich, das Skript herunterzuladen und lokal zu verbinden.
input id = otherPeerId - dient zur Eingabe des Festes desjenigen, den wir anrufen werden (Sie können es als Index oder als Telefonnummer verwenden).
Zwei Video-Tags dienen zur Anzeige Ihres eigenen Videos bzw. des Videos des Gesprächspartners.
Nun ein wenig über die WebRTC-Technologie und wie der Anruf getätigt wird. WebRTC ruft ohne Beteiligung des Servers direkt von Client zu Client an. Im ersten Schritt sollten sich also 2 Browser gegenseitig finden. Dazu benötigt ein klassisches WebRTC einen Signalserver, dh einen Server, der einem Browser die Parameter eines anderen Browsers mitteilt, und in WebRTC müssen Sie einen solchen Server selbst organisieren. PeerJS-Entwickler stellen jedoch ihren eigenen Signalserver zur Verfügung. Sie müssen lediglich die Peer-ID an den potenziellen Gesprächspartner übergeben, dh an den eindeutigen Index, der im PeerJS-System empfangen wird. In einem Arbeitsentwurf habe ich es so organisiert:
- Nach dem Laden der Seite wird ein Peer-Objekt erstellt
- Die Peer-ID wird in die MySQL-Datenbank geschrieben
- Wenn die Anruftaste gedrückt wird, wird die Peer-ID des Gesprächspartners aus der Datenbank gezogen und zum Herstellen einer Verbindung verwendet
Im aktuellen Testfall geben wir die Peer-ID des Gesprächspartners in das Textfeld otherPeerId ein
Beginnen wir also mit dem Schreiben von Code.1. Erstellen Sie das Haupt-Peer-Objekt
var peer = new Peer();
2. Zur Eröffnung des Festes erhalten wir die begehrte PeerID, die an den Partner übertragen werden muss, damit er uns kontaktieren kann
peer.on('open', function(peerID) { document.getElementById('myid').innerHTML=peerID; });
3. Um einen Anruf zu erhalten, legen wir den Handler für das Anrufereignis auf
var peercall; peer.on('call', function(call) {
Bei einem eingehenden Anruf erhalten wir ein
Aufrufobjekt , das wir in der globalen Variablen
peercall speichern. Außerdem werden im Informationsblock eine Benachrichtigung über einen eingehenden Anruf und zwei Schaltflächen angezeigt: Akzeptieren und Ablehnen
4. Wir schreiben eine Funktion für die Schaltfläche
Akzeptieren function callanswer() { navigator.mediaDevices.getUserMedia ({ audio: true, video: true }).then(function(mediaStream) { var video = document.getElementById('myVideo'); peercall.answer(mediaStream);
navigator.mediaDevices.getUserMedia - fordert den Zugriff auf Kamera und Mikrofon an. In den Daten des Objekts, das an diese Methode übergeben wird
(Audio: true, Video: true), können Sie dementsprechend nur den Zugriff auf die Kamera oder nur auf das Mikrofon anfordern. Weitere Kommentare direkt zum Code hinzugefügt.
setTimeout wurde empirisch hinzugefügt: Das Video des Partners wurde nicht abgespielt, es funktionierte jedoch mit einer Zeitüberschreitung.
5. Die Funktion des Wählens mit der Anruftaste
function callToNode(peerId) {
Wie im vorherigen Absatz fordern wir Ihren Medienstrom an. Nachdem wir die Aufruffunktion des Peer-Objekts aufgerufen haben, die das Aufrufobjekt an uns zurückgibt, speichern Sie es in Peercall. Wir verarbeiten das Stream-Ereignis, um herauszufinden, was sie beantwortet haben, und fügen den eingehenden Stream in das entsprechende Videoobjekt ein
Das ist alles, aber ...
Wenn sich beide Anrufer hinter dem NATth befinden, wird der Anruf nicht durchgestellt. (Warum? Lesen Sie hier
habr.com/de/company/yandex/blog/419951 )
Um dieses Hindernis zu überwinden, muss beim Erstellen des Peer-Objekts der TURN-Server angegeben werden (Die Frage, wo es erhältlich ist, war nicht die einfachste. Wir mussten unser eigenes VPS unter Ubuntu 16.04 auslösen. Installation mit dem Befehl
apt install coturn
)
Dann wird die Schaffung des Festes ungefähr so aussehen:
var callOptions={'iceServers': [ {url: 'stun:95.xxx.xx.x9:3479', username: "user", credential: "xxxxxxxxxx"}, { url: "turn:95.xxx.xx.x9:3478", username: "user", credential: "xxxxxxxx"}] }; peer= new Peer({config: callOptions});
Endlich der gesamte Code:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Peer</title> <script src="https://unpkg.com/peerjs@1.0.0/dist/peerjs.min.js"></script> </head> <body> <p><h3> ID: </h3><span id=myid ></span></p> <input id=otherPeerId type=text placeholder="otherPeerId" > <button onclick="callToNode(document.getElementById('otherPeerId').value)"></button> <br> <video id=myVideo muted="muted" width="400px" height="auto" ></video> <div id=callinfo ></div> <video id=remVideo width="400px" height="auto" ></video> <script> var callOptions={'iceServers': [ {url: 'stun:95.xxx.xx.x9:3479', username: "user", credential: "xxxxxxxxxx"}, { url: "turn:95.xxx.xx.x9:3478", username: "user", credential: "xxxxxxxx"}] }; peer= new Peer({config: callOptions}); peer.on('open', function(peerID) { document.getElementById('myid').innerHTML=peerID; }); var peercall; peer.on('call', function(call) { </script> </body>
Diese Lösung wurde erfolgreich unter Windows 7 und Ubuntu 18.04 in Chrome, Opera, Firefox getestet. Chrome funktioniert auch unter Android und MacOS, jedoch nicht unter iPhone und iPad.