https://d226lax1qjow5r.cloudfront.net/blog/blogposts/custom-video-streams-opentok-api-dr/Publishing-Custom-Video-Streams-with-the-OpenTok-API.png

Veröffentlichung benutzerdefinierter Videostreams mit der OpenTok-API

Zuletzt aktualisiert am May 11, 2021

Lesedauer: 4 Minuten

Als Kind wollte ich in der Weihnachtszeit immer in der Nähe von Schnee sein, aber leider lebe ich in der Nähe von San Francisco, so dass bei uns nie Schnee fällt. Damit es sich anfühlt, als würde es schneien, bauen wir eine Videochat-App mit der OpenTok-API mit sich bewegenden Schneeflocken in unserem Video-Stream!

Voraussetzungen

Bevor wir beginnen, stellen Sie bitte sicher, dass Sie eine TokBox Konto sowie den API-Schlüssel und das API-Geheimnis aus einem API-Projekt haben.

Aufbau der App

Erstellen Sie ein Verzeichnis und benennen Sie es nach Ihren Wünschen:

mkdir publisher-with-snowflakes cd publisher-with-snowflakes

Mit dem folgenden Befehl erstellen wir einige Dateien in diesem Verzeichnis:

touch index.html index.js

Unsere Projektstruktur sollte nun wie folgt aussehen:

publisher-with-snowflakes
├── index.js
├── index.html

Nachdem wir nun unser Projekt erstellt haben, fügen wir etwas OpenTok-Code in unsere index.js Datei hinzufügen.

const apiKey = '';
const sessionId = '';
const token = '';

const session = OT.initSession(apiKey, sessionId);
const publisher = OT.initPublisher('publisher');

session.on({
 streamCreated: event => {
   session.subscribe(event.stream);
 },
 sessionConnected: event => {
   session.publish(publisher);
 },
});

session.connect(token, (error) => {
 if (error) {
   console.log(`There was an error connecting to the session ${error.message}`);
 }
});

Im obigen Code haben wir die Initialisierung von Sitzung und Publisher Objekte mit OT.initSession und OT.initPublisher Methoden. Anschließend setzen wir Ereignis-Listener auf dem Sitzungsobjekt für streamCreated und sessionConnected wo wir einen Stream abonnieren, wenn er erstellt wird, und unseren Stream veröffentlichen, wenn wir mit der Sitzung verbunden sind. Nach dem Einstellen der Sitzungs-Ereignis-Listener versuchen wir, eine Verbindung zur Sitzung mit einem OpenTok Token.

Machen wir weiter und fügen wir die index.js Datei zum index.html zusammen mit dem OpenTok.js SDK.

<html>
  <head>
    <script src="https://static.opentok.com/v2/js/opentok.min.js"></script>
    <script src="index.js"></script>
  </head>
    <body>
    <div id="publisher"></div>
  </body>
</html>

Da wir nun wissen, wie man einen Publisher erstellt und in einer Sitzung veröffentlicht, müssen wir eine benutzerdefinierte Videoquelle mithilfe der Leinwand-API und der snowflake-greenscreen.mp4 Videodatei.

Benutzerdefinierte Videoquelle

const closeToGreen = (r, g, b) => {
 // 86, 246, 61
 if (g > (b * 1.4) && g > (r * 1.4)) {
   return true;
 }
 return false;
};

const getCanvasStream = () => {
 let canvas;
 let videoElement;
 let filterVideo;
 let ctx;
 let stopped = false;
 let filterCtx;
 let filterCanvas;
 let cameraCtx;
 let cameraCanvas;

 const drawFrame = () => {
   cameraCtx.drawImage(videoElement, 0, 0, cameraCanvas.width, cameraCanvas.height);
   filterCtx.drawImage(filterVideo, 0, 0, filterCanvas.width, filterCanvas.height);

   const cameraData = cameraCtx.getImageData(0, 0, cameraCanvas.width, cameraCanvas.height);
   const filterData = filterCtx.getImageData(0, 0, filterCanvas.width, filterCanvas.height);
   const res = new Uint8ClampedArray(cameraData.data.length);
   for (let i = 0; i < cameraData.data.length; i += 4) {
     let imgData = cameraData;
     if (!closeToGreen(filterData.data[i], filterData.data[i+1], filterData.data[i+2])) {
       imgData = filterData;
     }
     res[i] = imgData.data[i];
     res[i + 1] = imgData.data[i + 1];
     res[i + 2] = imgData.data[i + 2];
     res[i + 3] = imgData.data[i + 3];
   }
   ctx.putImageData(new ImageData(res, cameraData.width, cameraData.height), 0, 0);
   if (!stopped) {
     requestAnimationFrame(drawFrame);
   } else {
     ctx = null;
   }
 };

 canvas = document.createElement('canvas');
 ctx = canvas.getContext('2d');
 canvas.width = 640;
 canvas.height = 480;

 // Get the Camera video
 OT.getUserMedia({
   audioSource: null
 }).then((stream) => {
   videoElement = document.createElement('video');
   videoElement.srcObject = stream;
   videoElement.play();
   cameraCanvas = document.createElement('canvas');
   cameraCanvas.width = videoElement.width = 640;
   cameraCanvas.height = videoElement.height = 480;
   cameraCtx = cameraCanvas.getContext('2d');

   requestAnimationFrame(drawFrame);
 });

 // Get the filter video
 filterVideo = document.createElement('video');
 filterVideo.setAttribute('loop', true);
 filterCanvas = document.createElement('canvas');
 filterVideo.src = 'snowflake-greenscreen.mp4';
 filterCanvas.width = filterVideo.width = 640;
 filterCanvas.height = filterVideo.height = 480;
 filterVideo.play();
 filterCtx = filterCanvas.getContext('2d');

 return {
   canvas,
   stop: () => {
     stopped = true;
   }
 };
};

In dem obigen Code verwenden wir OT.getUserMedia, eine Umhüllung von navigator.mediaDevices.getUserMedia, um ein MediaStream Objekt zu erhalten. Wir verwenden dann das Video MediaStreamTrackaus dem MediaStream Objekt, um ein Bild auf die Leinwand zu zeichnen. Nach dem Anhängen des Videos MediaStreamTrackändern wir das Bild auf der Leinwand, indem wir den Schneeflockenfilter anwenden.

Nachdem wir nun einen Mechanismus zum Erfassen des Kamerastroms und zum Hinzufügen eines Schneeflockenfilters erstellt haben, setzen wir die videoSource Eigenschaft für den Herausgeber.

const canvasStream = getCanvasStream();
const publisher = OT.initPublisher('publisher', {
  videoSource: canvasStream.canvas.captureStream(30).getVideoTracks()[0],
});

Beachten Sie, dass wir im obigen Code die captureStream Methode des canvas Objekts verwendet, um das resultierende MediaStream Objekt und rufen getVideoTracks()[0] auf dieses Objekt, um das Video MediaStreamTrack Objekt zu erhalten.

Um die Veröffentlichung Ihres benutzerdefinierten Videos in der Sitzung zu starten, fügen Sie die apiKey, sessionId, und token Werte hinzu!

Wenn Sie Ihre App laden, sollten Sie das Video Ihrer Kamera mit dem Schneeflocken-Filter sehen:

Video stream with snowflakesVideo stream with snowflakes

Bekannte Beschränkungen

  • Die benutzerdefinierte Streaming-API funktioniert mit Chrome 51+, Firefox 49+ und Safari 11+. Sie funktioniert nicht in den Browsern IE und Edge.

  • Wenn das Browserfenster den Fokus verliert, z. B. wenn Sie eine neue Registerkarte öffnen, wird das Video angehalten oder verlangsamt sich.

Den gesamten Code für diese Beispielanwendung finden Sie hier. Um weitere Beispiele für die Verwendung von OpenTok mit Canvas zu sehen, besuchen Sie bitte die OpenTok-Web-Beispiele Repository.

Share:

https://a.storyblok.com/f/270183/384x384/63f654d765/manik.png
Manik SachdevaVonage Ehemalige

Manik ist ein leitender Software-Ingenieur. Er arbeitet gerne mit Entwicklern zusammen und entwirft APIs. Wenn er nicht gerade APIs oder SDKs entwickelt, kann man ihn bei Konferenzen und Meetups als Redner antreffen.