WebRTC-Streaming in und um die virtuelle Realität


Die virtuelle Realität ist in diesen Tagen auf dem Vormarsch. Die Ausrüstung, die bisher exklusiv unterstand verrückte Wissenschaftler Geeks mit großem Geld vom Verteidigungsministerium Zurück in den Tagen des The Lawnmower Man, ist derzeit für normale Menschen erschwinglich; Wer keine Tasche mehr hat, kann ein VR-Headset aus Pappe und ein Smartphone nach vielen Rezepten zusammenbauen.


VR kann viel mehr Vorteile bringen als 3-4-5-6-7-something-D-Kino. Nehmen wir an, Sie leben in Chicago und möchten ehrlich verdiente Ressourcen in Immobilien investieren - irgendwo entlang der Küste Floridas. Wie Sie wissen, ist es besser, sich selbst und vor Ort eine Unterkunft auszusuchen, aber was ist, wenn Sie nicht genug Zeit dafür aufwenden können? Hier ist virtuelle Realität gefragt. Stellen Sie sich vor, der Agent stellt eine spezielle Kamera in den Raum und Sie können, ohne Ihren Lieblingsstuhl zu verlassen, diesen Raum untersuchen, den Kopf drehen und sogar die Decke mit einem Wandbild aus dem 18. Jahrhundert „Griechische Götter feiern!“ Bewundern.


Dann, immer noch ohne den Ort zu verlassen, fragen Sie sich vielleicht, was Ihre Kinder im Kindergarten machen. Und noch einmal: Die Kamera befindet sich im Spielzimmer, und Sie können ein intensives sensorisches Erlebnis erzielen, indem Sie alle Ecken untersuchen, in denen sich Ihre Kinder befinden sich verstecken .


Jetzt werden wir herausfinden, wie wir sicherstellen können, dass alles funktioniert und das Immobilienmakler Kinder streuen nicht.


Die Nuancen des VR-Bildes


Technisch gesehen unterscheidet sich ein VR-Media-Stream nicht von einem normalen. Es ist eine Videospur plus eine Audiospur. Aber es gibt eine Nuance.


VR-Stream nimmt ein Stereobild an. Eine spezielle Kamera betrachtet die Welt mit zwei Augen Objektive öffnen sich weit (180 Grad) wie ein Roboter.



die bilder verschmelzen zu einem rahmen,



Daher sollte ein spezieller Player auf dem Gerät des Betrachters installiert sein, der zwei Bilder zu einem macht. Wie Sie sehen, beträgt das Seitenverhältnis des Rahmens 2: 1, wodurch für jedes Auge ein FullHD-Bild erstellt wird.


Die Nuancen von VR-Sendungen


Wir sprechen also von der Übertragung von 4K-Streams mit einer hohen Bitrate. Was haben wir Wir haben RTMP und WebRTC.


RTMP ist billig zuverlässig und praktisch. Es verwendet TCP, was bei nicht so guten Kanälen nützlich ist. Es gibt verschiedene Softwarelösungen für den Publishing-Client, sowohl kostenpflichtig als auch kostenlos. Trotz aller Vorzüge weist RTMP eine hohe Latenz auf. In einem der vorherigen Artikel haben wir eine Verzögerung von 2-3 Sekunden in einem 720p-Stream festgestellt. In einigen Fällen sind Verzögerungen akzeptabel, aber die VR wird hinter der Realität zurückbleiben, und die Kinder werden sich mit Sicherheit zerstreuen.


WebRTC ist wirklich cool. Bei guten Kanälen werden Verzögerungen in Millisekunden gemessen, und die Realität bleibt die Realität. Aber es gibt Nuancen.


Erstens läuft WebRTC standardmäßig auf UDP, was zu Verlusten bei der geringsten Verschlechterung der Kanalqualität führt. Für einen 4K-Stream ist jede Kleinigkeit auf dem Kanal bereits eine Verschlechterung. Dies kann durch Umschalten auf TCP-Transport behoben werden. In diesem Fall ...


Zweitens wird WebRTC vom Browser gesendet, und wir wissen beide, welcher Browser derzeit der beliebteste auf dem Planeten ist (Spoiler - es ist kein IE6). In diesem beliebten Browser beträgt die maximale Publikations-Bitrate auf Modulebene 2500 kbit / s. Wie Google denkt Dies ist genug für FullHD, aber nicht genug für 4K. Wenn die Bitrate nicht auf 5 bis 10 Mbit / s beschleunigt wird, sehen die Betrachter bewegte Aquarellflecken anstelle der virtuellen Realität. Glücklicherweise gibt es spezielle Einstellungen zum Übertakten der Bitrate, die funktionieren so ziemlich alle Browser auf der Chromium Engine. Wenn wir dieses Hindernis überwinden, werden wir auf ...


Drittens werden wir auf Kanalbandbreite stoßen. Um ein VR-Bild mit der oben genannten Bitrate zu veröffentlichen und wiederzugeben, benötigt der Client Kanäle mit 20+ Mbit oder besser 50 und noch besser 100+ Mbit, sowohl zum Herunterladen als auch zum Hochladen. In diesem Fall sollten dies nicht die Parameter sein, über die der Anbieter in Werbebroschüren spricht, sondern die tatsächliche Bandbreite vom Client zum Server. Übrigens lesen Sie, wie man es ohne Iperf und Kommandozeile misst . Entsprechend ist es auf der Serverseite wünschenswert, 10 GB zu haben, wenn eine große Anzahl von Streams vorgesehen ist.


Viertens ergibt sich aus den Anforderungen für Kanäle. Das Transcodieren eines 4K-Streams beansprucht zu viele Prozessorressourcen auf dem Server. Daher müssen Sie entweder einen King-Size-Server auswählen, der teuer ist, oder die Codierung für Grafikkarten verwenden, die ebenfalls sehr teuer ist, oder die Transcodierung vermeiden. Das heißt, ändern Sie niemals die Auflösung, Bildrate und Bitrate der Streams während der Übertragung.


Versuchen wir das mal


Nehmen wir:



Stellen Sie die Kamera auf einen Tisch oder ein Stativ



Schließen Sie es wie externe Laufwerke über USB 3.0 mit 1 A an den PC an



Beachten Sie, dass die Kamera sehr empfindlich auf Geräte reagiert. Wenn der Laptop über 2 USB 3.0-Anschlüsse verfügt, kann es durchaus vorkommen, dass sie nicht mit einem dieser Anschlüsse zusammenarbeitet. Verwenden Sie kein billiges chinesisches Verbindungskabel. Alle in der Norm vorgesehenen Stifte müssen vorhanden sein. Selbst bei einer perfekten Verbindung kann die Kamera Störungen erzeugen, wie ein alter Fernseher bei einem Gewitter. Das einzig Positive ist, dass für Windows 10 keine Treiber erforderlich sind. Es ist eine ehrliche Plug-n-Play-Verbindung.


Wir werden die erforderlichen Bitratenlimits auf der Serverseite festlegen


webrtc_cc_min_bitrate=5000000 webrtc_cc_max_bitrate=10000000 

Öffnen Sie in Chrome die Seite eines Beispiels, und legen Sie die erforderlichen Parameter für die Aufzeichnung des Streams von der Kamera fest


  • Auflösung von 3072x1536
  • FPS 24 (die Kamera unterstützt nur dieses FPS beim Senden über den Browser)
  • TCP-Transport

und konfigurieren Sie die SDP-Einstellungen so, dass der Browser die Bitrate auf der Clientseite nicht verringert


 x-google-max-bitrate=10000;x-google-min-bitrate=5000 

oder auf der Serverseite (in diesem Fall gelten die Einstellungen für alle Publishing-Clients)


 webrtc_sdp_min_bitrate_bps=5000000 webrtc_sdp_max_bitrate_bps=10000000 


Veröffentlichen wir den Stream von der Kamera



Versuchen wir nun, den Stream mit einem normalen WebRTC-Player abzuspielen



Alles ist gut ... Fast. Die Virtualität ist nicht wirklich virtuell. Lassen Sie uns nun denselben Stream in einem speziellen Player abspielen, der auf der Seite eingebettet ist



Das ist jetzt besser (und wir haben auch Katzen). Wenn Sie den Stream auf einem mobilen Gerät oder in einer VR-Brille abspielen, können Sie Ihren Kopf drehen, und wir bewegen die Maus im Browser auf dem PC. Irgendwo in diesem Raum versteckt sich ein Kind. Lassen Sie uns nach links schauen



Und jetzt nach rechts



Und jetzt auf



Wo ist das Kind? Dort versteckt er sich hinter dem Vorhang. Aber die Katzen sehen ihn!


Wir brauchen mehr Code!


Es gibt wenig Code auf der Client-Seite.


Veröffentlichen wir den Stream über die Browserseite


 session.createStream({ name: streamName, display: localVideo, cacheLocalResources: true, transport: "TCP", sdpHook: rewriteSdp, constraints: { audio:true, video: { width: 3072, height: 1536, frameRate: 24 } } }).publish(); 

Funktion zum Überschreiben des SDP-Browsers


 function rewriteSdp(sdp) { var sdpStringFind = "a=fmtp:(.*) (.*)"; var sdpStringReplace = "a=fmtp:$1 $2;x-google-max-bitrate=10000;x-google-min-bitrate=5000"; var newSDP = sdp.sdpString.toString(); newSDP = newSDP.replace(new RegExp(sdpStringFind,"g"), sdpStringReplace); return newSDP; } 

Ein Beispiel für eine Seite mit einem VR-Player


 <!DOCTYPE html> <html> <head> <title>WebRTC Delight</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script type="text/javascript" src="../../../../flashphoner.js"></script> <script type="text/javascript" src="../../dependencies/jquery/jquery-1.12.0.js"></script> <script type="text/javascript" src="../../dependencies/js/utils.js"></script> <script src="dl8-player.js" async></script> <meta name="dl8-custom-format" content='{"name": "STEREO_TERPON","base":"STEREO_MESH","params":{"uri": "03198702.json"}}'> </head> <body> <div style="width: 50%;" id="display"> <dl8-live-video id="remoteVideo" format="STEREO_TERPON"> \<source> </dl8-live-video> </div> <input class="form-control" type="text" id="playStream" placeholder="Stream Name"> <button id="playBtn" type="button" class="btn btn-default" disabled>Play</button> <button id="stopBtn" type="button" class="btn btn-default" disabled>Stop</button> <script> Flashphoner.init({flashMediaProviderSwfLocation: '../../../../media-provider.swf'}); var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS; var STREAM_STATUS = Flashphoner.constants.STREAM_STATUS; var STREAM_STATUS_INFO = Flashphoner.constants.STREAM_STATUS_INFO; var playBtn = document.getElementById('playBtn'); var display = document.getElementById('display'); var dl8video = null; var url = setURL(); document.addEventListener('x-dl8-evt-ready', function () { dl8video = document.getElementById('remoteVideo'); $('#playBtn').prop('disabled', false).click(function() { playStream(); }); }); function playStream() { $('#playBtn').prop('disabled', true); $('#stopBtn').prop('disabled', false); var video = dl8video.contentElement; Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function (session) { var session = Flashphoner.getSessions()[0]; session.createStream({ name: document.getElementById('playStream').value, display: display, remoteVideo: video, transport: "TCP" }).on(STREAM_STATUS.PLAYING, function (stream) { dl8video.start(); $('#stopBtn').prop('disabled', false).click(function() { $('#playBtn').prop('disabled', false); $('#stopBtn').prop('disabled', true); stream.stop(); dl8video.exit(); }); }).play(); }) } </script> </body> </html> 

Normalerweise übergeben wir beim Erstellen eines Streams für einen Player (Abfrage session.createStream() ) das div-Element, in das das Videoelement session.createStream() wird, um den Stream über WebRTC abzuspielen. Der VR-Player verwendet jedoch ein eigenes Videoelement, und wir müssen es irgendwie in den Code der verwendeten API weiterleiten. Dazu übergeben wir das Videoelement des Drittanbieter-Players mit dem Parameter remoteVideo direkt an session.createStream ()


Als Server wird demo.flashphoner.com verwendet. Beispiele für Webanwendungen finden Sie unter den folgenden Links.


Viel Glück bei Ihren VR-Bemühungen! Viel Spaß beim Streamen!



  1. Kanalqualitätsindikator für Server WebRTC über TCP - Qualitätskontrolle der Kanäle vom Client zum Server
  2. Videoübertragung von der Webkamera eines Browsers oder mobilen Geräts - WebRTC-Streaming vom Browser
  3. Dokumentation zur Verwendung von WCS mit einem VR-Player
  4. WCS - Server zur Übertragung von VR 360-Videos über WebRTC

Source: https://habr.com/ru/post/de482270/


All Articles