Streams veröffentlichen — Web

Sobald Sie mit einer Sitzung verbundenkönnen Sie einen Stream veröffentlichen, den andere mit der Sitzung verbundene Clients anzeigen können.

Dieses Thema umfasst die folgenden Abschnitte:

Prüfen, ob ein Client über Veröffentlichungsfunktionen verfügt

Sobald Sie eine Verbindung zu einer Sitzung hergestellt haben, können Sie überprüfen, ob der Client Daten veröffentlichen kann. Überprüfen Sie den Wert des capabilities.publish Eigenschaft der Session Objekt. Ist er auf 1 gesetzt, kann der Client veröffentlichen:

if (session.capabilities.publish == 1) {
    // The client can publish. See the next section.
} else {
    // The client cannot publish.
    // You may want to notify the user.
}

Um zu veröffentlichen, muss der Client eine Verbindung zur Sitzung mit einem Token herstellen, dem eine Rolle zugewiesen ist, die die Veröffentlichung unterstützt. Es muss eine angeschlossene Kamera und ein Mikrofon vorhanden sein. Außerdem muss die Client-Umgebung die Veröffentlichung unterstützen (siehe Browser-Unterstützung).

Außerdem wird die Veröffentlichung nur auf HTTPS-Seiten unterstützt.

Initialisierung eines Publishers

Die OT.initPublisher() Methode initialisiert und gibt ein Publisher-Objekt zurück. Das Publisher-Objekt stellt die Ansicht eines Videos dar, das Sie veröffentlichen:

var publisher;
var targetElement = 'publisherContainer';

publisher = OT.initPublisher(targetElement, null, function(error) {
  if (error) {
    // The client cannot publish.
    // You may want to notify the user.
  } else {
    console.log('Publisher initialized.');
  }
});

Die OT.initPublisher() erhält drei Parameter:

  • targetElement- (Optional) Legt das DOM-Element fest, das durch das Publisher-Video ersetzt wird.

  • properties- (Optional) Eine Reihe von Eigenschaften, mit denen der Publisher angepasst wird. Die properties Der Parameter enthält außerdem Optionen zur Angabe eines vom Publisher verwendeten Audio- und Videoeingabegeräts (siehe Einstellung der vom Herausgeber verwendeten Kamera und des Mikrofons). Die Website properties Der Parameter enthält außerdem Optionen zur Anpassung der Darstellung der Ansicht auf der HTML-Seite (siehe Anpassen der Benutzeroberfläche) und wählen Sie, ob Audio und Video veröffentlicht werden sollen (siehe Nur Audio oder Video veröffentlichen). Weitere Optionen für Publisher finden Sie in der Dokumentation zum properties Parameter des OT.initPublisher() Methode.

  • completionHandler- (Optional) Ein Beendigungshandler, der angibt, ob der Publisher erfolgreich oder mit einem Fehler instanziiert wurde.

Sie können dieses Publisher-Objekt an die Session.publish() Methode zum Veröffentlichen eines Streams in einer Sitzung. Siehe Veröffentlichen eines Streams.

Vor dem Anruf Session.publish()können Sie dieses Publisher-Objekt verwenden, um das Mikrofon und die Kamera zu testen, die mit dem Publisher verbunden sind.

Die insertMode Eigenschaft der properties Parameter des OT.initPublisher() Methode gibt an, wie das Publisher-Objekt in das HTML-DOM eingefügt wird, und zwar in Bezug auf die targetElement Parameter. Sie können diesen Parameter auf einen der folgenden Werte einstellen:

  • "replace" - Das Publisher-Objekt ersetzt den Inhalt des targetElements. Dies ist der Standard.
  • "after" - Das Publisher-Objekt ist ein neues Element, das nach dem targetElement im HTML-DOM eingefügt wird. (Publisher und targetElement haben beide dasselbe Elternelement).
  • "before" - Das Publisher-Objekt ist ein neues Element, das vor dem targetElement im HTML-DOM eingefügt wird. (Publisher und targetElement haben beide dasselbe Elternelement).
  • "append" - Das Publisher-Objekt ist ein neues Element, das als untergeordnetes Element des targetElements hinzugefügt wird. Wenn es weitere untergeordnete Elemente gibt, wird der Publisher als letztes untergeordnetes Element des targetElements angefügt.

Der folgende Code fügt zum Beispiel ein neues Publisher-Objekt als Kind einer publisherContainer DOM-Element:

// Try setting insertMode to other values: "replace", "after", or "before":
var publisherProperties = {insertMode: "append"};
var publisher = OT.initPublisher('publisherContainer', publisherProperties, function (error) {
  if (error) {
    console.log(error);
  } else {
    console.log("Publisher initialized.");
  }
});

Erkennen, wann ein Client den Zugriff auf die Kamera und das Mikrofon gewährt hat

Bevor ein Publisher-Objekt auf die Kamera und das Mikrofon des Clients zugreifen kann, muss der Benutzer den Zugriff darauf gewähren. Das Publisher-Objekt löst Ereignisse aus, wenn der Benutzer den Zugriff auf die Kamera und das Mikrofon gewährt oder verweigert:

publisher.on({
  accessAllowed: function (event) {
    // The user has granted access to the camera and mic.
  },
  accessDenied: function accessDeniedHandler(event) {
    // The user has denied access to the camera and mic.
  }
});

Außerdem löst ein Publisher-Objekt Ereignisse aus, wenn dem Benutzer die Option angezeigt wird, den Zugriff auf die Kamera und das Mikrofon zuzulassen oder zu verweigern:

publisher.on({
  accessDialogOpened: function (event) {
    // The Allow/Deny dialog box is opened.
  },
  accessDialogClosed, function (event) {
    // The Allow/Deny dialog box is closed.
  }
});

Der Verlag hat eine accessAllowed Eigenschaft, die angibt, ob ein Client (true) oder nicht (false) hat den Zugriff auf die Kamera und das Mikrofon gewährt.

Einstellung der vom Herausgeber verwendeten Kamera und des Mikrofons

Sie können (optional) ein Audio- und Videoeingabegerät angeben, das der Herausgeber verwenden soll. Wenn Sie den OT.initPublisher() Methode können Sie (optional) die audioSource und videoSource Eigenschaften der properties Objekt, das an die OT.initPublisher() Methode.

Verwenden Sie zunächst die OT.getDevices() Methode, um die verfügbaren Geräte aufzuzählen. Das Array der Geräte wird als devices Parameter des callback Funktion, die an die OT.getDevices() Methode. Der folgende Code ruft zum Beispiel eine Liste von Audio- und Videoeingabegeräten ab:

var audioInputDevices;
var videoInputDevices;
OT.getDevices(function(error, devices) {
  audioInputDevices = devices.filter(function(element) {
    return element.kind == "audioInput";
  });
  videoInputDevices = devices.filter(function(element) {
    return element.kind == "videoInput";
  });
  for (var i = 0; i < audioInputDevices.length; i++) {
    console.log("audio input device: ", audioInputDevices[i].deviceId);
  }
  for (i = 0; i < videoInputDevices.length; i++) {
    console.log("video input device: ", videoInputDevices[i].deviceId);
  }
});

Jedes Gerät, das von OT.getDevices() hat eine eindeutige Geräte-ID, die als deviceId Eigenschaft. Sie können diese Geräte-ID-Werte als die audioSource und videoSource Eigenschaften der properties Objekt, das an OT.initPublisher():

var pubOptions =
  {
    audioSource: audioInputDevices[0].deviceId,
    videoSource: videoInputDevices[0].deviceId
  };
var publisher = OT.initPublisher(null, pubOptions, function(error) {
  console.log("OT.initPublisher error: ", error);
});

Setzen Sie die videoSource Eigenschaft zu null oder false in einer reinen Sprachsitzung (siehe Veröffentlichung in einer Sprachsitzung).

Die OpenTok-Hardware-Einrichtungskomponente bietet eine Benutzeroberfläche, über die die Kunden die zu verwendende Kamera und das Mikrofon auswählen können. Sie wurde unter Verwendung der OT.getDevices() Methode.

Beachten Sie, dass Sie auch einen Screen-Sharing-Stream veröffentlichen können, bei dem die Quelle der Bildschirm des Clients und nicht eine Kamera ist. Für Details siehe Bildschirmfreigabe.

Sie können auch die vom Herausgeber verwendete Kamera ändern, oder stellen Sie es so ein, dass es die Front- oder Rückkamera (sofern diese Option verfügbar ist).

Sie können auch die vom Herausgeber verwendete Audioquelle ändern.

Verwendung der Front- oder Rückkamera

Wenn Sie einen Publisher initialisieren, können Sie die facingMode Eigenschaft des Options-Objekts, das Sie an die OT.initPublisher(). Sie können die Eigenschaft beispielsweise auf "user" (Frontkamera) oder "environment" (Rückfahrkamera), sofern diese Option auf dem System des Kunden verfügbar ist. (In der Regel sind diese Optionen nur auf Mobilgeräten verfügbar.)

Wenn Sie die Einstellung facingMode Option, dann nicht setzen die videoSource Eigentum.

Speichern der Kamera- und Mikrofonauswahl

Aus Sicherheitsgründen fordern alle Browser den Nutzer bei über HTTP geladenen Seiten stets auf, die Kamera und das Mikrofon auszuwählen, die für die Übertragung eines Streams verwendet werden sollen.

Bei Seiten, die in Chrome über HTTPS geladen werden, werden die vom Nutzer getroffenen Einstellungen für Kamera und Mikrofon gespeichert und bei späteren Besuchen einer Seite, die von derselben HTTPS-Domäne geladen wird, wiederverwendet.

Auf Seiten, die in Firefox über HTTPS geladen werden, hat der Nutzer bei der Auswahl der Geräte die Möglichkeit, die Kamera und das Mikrofon zu speichern (für spätere Besuche einer Seite, die von derselben HTTPS-Domain geladen wird).

Bei Seiten, die im Internet Explorer über HTTPS geladen werden, können Sie die zuvor vom Benutzer getroffene Auswahl für Kamera und Mikrofon aus früheren Aufrufen derselben HTTPS-Domäne (sofern vorhanden) verwenden, indem Sie die usePreviousDeviceSelection Eigenschaft zu true in den Optionen, die Sie in der OT.initPublisher() Methode:

var pubOptions = {usePreviousDeviceSelection: true};
var publisher = OT.initPublisher(null, pubOptions, function(error) {
  console.log("OT.initPublisher error: ", error);
});

Um den Benutzer aufzufordern, die im IE zu verwendende Kamera und das Mikrofon auszuwählen (und frühere Geräteauswahlen zu ignorieren), führen Sie folgenden Befehl aus: nicht setzen die usePreviousDevices Eigenschaft in den Optionen, die Sie in der OT.initPublisher() Methode (oder setzen Sie sie auf false(die Standardeinstellung).

Deaktivieren der standardmäßigen Verwaltung von Audio-Eingabegeräten

Standardmäßig übernimmt das SDK automatisch die Umschaltung des Audio-Eingabegeräts, wenn ein neues angeschlossen wird. Dies ist möglicherweise nicht das gewünschte Verhalten für einige Endnutzer, die ihr aktuelles Mikrofon weiterhin verwenden möchten.

Als fortgeschrittener Nutzer des SDK können Sie die automatische Verwaltung der Audio-Eingabegeräte deaktivieren. Dazu müssen Sie die disableAudioInputDeviceManagement Eigenschaft zu den Optionen, die in der OT.initPublisher() Methode:

var pubOptions = {disableAudioInputDeviceManagement: true};
var publisher = OT.initPublisher(null, pubOptions, function(error) {
  console.log("Publishing a stream");
});

Anmerkung: Dies ist eine erweiterte Funktion. Wenn Sie diese aktivieren, wird das vom SDK verwendete Audio-Eingabegerät wird nicht aktualisiert werden, wenn der Endbenutzer sein Mikrofon wechselt.

Veröffentlichen eines Streams

Sobald Sie ein Publisher-Objekt erstellt haben (siehe Initialisierung eines Publishers), können Sie es an die publish() Methode eines Session-Objekts, um einen Stream in der Session zu veröffentlichen:

    publisher = OT.initPublisher('replacementElementId');
    session.publish(publisher, function(error) {
      if (error) {
        console.log(error);
      } else {
        console.log('Publishing a stream.');
      }
    });

Der zweite Parameter ist eine Abschlusshandlerfunktion, der ein Fehlerobjekt übergeben wird, wenn die Veröffentlichung fehlschlägt. Andernfalls wird die Beendigungshandlerfunktion aufgerufen, ohne dass ein Fehler übergeben wird.

Dieser Code geht davon aus, dass session ein Session-Objekt ist und dass der Client eine Verbindung zur Session aufgebaut hat. Für weitere Informationen, siehe Beitritt zu einer Sitzung.

Das Publish-Objekt sendet eine streamCreated Ereignis, wenn das Streaming in die Sitzung beginnt:

var publisher = OT.initPublisher();
session.publish(publisher, function(error) {
  if (error) {
    console.log(error);
  } else {
    console.log('Publishing a stream.');
  }
});
publisher.on('streamCreated', function (event) {
    console.log('The publisher started streaming.');
});

Das Publisher-Objekt hat eine element die auf das HTML-DOM-Element gesetzt wird, das sie enthält.

Verhindern, dass ein Publisher Daten an eine Sitzung überträgt

Sie können das Streaming des Publishers in die Sitzung unterbinden, indem Sie die Funktion unpublish() Methode des Session-Objekts:

    session.unpublish(publisher);

Beachten Sie, dass Sie die Übertragung von Video oder Audio einzeln unterbrechen können (während die Veröffentlichung weiterhin läuft). Weitere Informationen finden Sie unter Einstellen von Audio und Video.

Erkennen, wenn ein veröffentlichter Stream eine Sitzung verlässt

Das Publisher-Objekt versendet eine streamDestroyed Ereignis, wenn das Streaming in die Sitzung beendet wird:

var publisher = OT.initPublisher();
session.publish(publisher);
publisher.on("streamDestroyed", function (event) {
  console.log("The publisher stopped streaming. Reason: "
    + event.reason);
});

Die streamDestroyed Ereignis wird durch die Klasse StreamEvent definiert. Das Ereignis enthält eine reason die angibt, warum der Stream beendet wurde. Diese Gründe umfassen "clientDisconnected", "forceDisconnected", "forceUnpublished", oder "networkDisconnected". Für Einzelheiten siehe StreamEvent.

Standardmäßig, wenn ein Publisher die streamDestroyed Ereignis wird der Publisher zerstört und aus dem HTML-DOM entfernt. Sie können dieses Standardverhalten verhindern, indem Sie die preventDefault() Methode des StreamEvent-Objekts:

publisher.on("streamDestroyed", function (event) {
    event.preventDefault();
    console.log("The publisher stopped streaming.");
});

Sie können das Standardverhalten verhindern und den Publisher beibehalten, wenn Sie das Publisher-Objekt wiederverwenden möchten, um erneut in der Sitzung zu veröffentlichen.

Der Verlag versendet außerdem eine destroyed Ereignis, wenn das Objekt aus dem HTML-DOM entfernt wurde. Als Reaktion auf dieses Ereignis können Sie DOM-Elemente anpassen (oder entfernen), die sich auf den entfernten Verlag beziehen.

Einstellen der Videoauflösung eines Streams

Um eine empfohlene Videoauflösung für einen veröffentlichten Stream festzulegen, setzen Sie die resolution Eigenschaft der properties Parameter, den Sie an die OT.initPublisher() Methode:

var publisherProperties = {resolution: '1280x720'};
var publisher = OT.initPublisher(targetElement,
                                 publisherProperties);
publisher.on('streamCreated', function(event) {
   console.log('Stream resolution: ' +
     event.stream.videoDimensions.width +
     'x' + event.stream.videoDimensions.height);
});

Diese resolution ist ein String, der die gewünschte Auflösung des Videos angibt. Das Format des Strings ist "_width_x_height_"wobei die Breite und Höhe in Pixeln angegeben werden. Gültige Werte sind "1920x1080", "1280x720", "640x480"und "320x240".

Die gewünschte Auflösung eines Videostreams wird als videoDimensions.width und videoDimensions.height Eigenschaften des Stream-Objekts.

Die Standardauflösung für einen Stream (wenn Sie keine Auflösung angeben) ist 640x480 Pixel. Wenn das Client-System die von Ihnen angeforderte Auflösung nicht unterstützt, wird der Stream die nächstgrößere unterstützte Einstellung verwenden.

Die videoHeight() und videoWidth() Methoden geben die konfigurierte Auflösung des Publisher-Objekts zurück. Die tatsächliche Auflösung eines Subscriber-Videostreams wird von der Methode videoWidth() und videoHeight() Methoden des Subscriber-Objekts. Diese können sich von den Werten der resolution Eigenschaft, die als properties Eigenschaft der OT.initPublisher() Methode, falls der Browser die angeforderte Auflösung nicht unterstützt.

Anmerkung: Siehe die 1080p-Entwicklerhandbuch für Überlegungen zur Verwendung der 1080p-Auflösung.

Einstellen der Bildrate eines Streams

Um eine empfohlene Bildrate für einen veröffentlichten Stream festzulegen, setzen Sie die frameRate Eigenschaft der properties Parameter, den Sie an die OT.initPublisher() Methode:

var publisherProperties = {frameRate: 7};
var publisher = OT.initPublisher(targetElement,
                                 publisherProperties);
publisher.on('streamCreated', function(event) {
   console.log('Frame rate: ' + event.stream.frameRate);
});

Stellen Sie den Wert auf die gewünschte Bildrate des Videos in Bildern pro Sekunde ein. Gültige Werte sind 30, 15, 7 und 1.

Wenn der Herausgeber eine Bildrate angibt, wird die tatsächliche Bildrate des Video-Streams als frameRate Eigenschaft des Stream-Objekts, obwohl die tatsächliche Bildrate je nach den sich ändernden Netzwerk- und Systembedingungen variiert. Wenn Sie keine Bildrate angeben, wenn Sie OT.initPublisherist diese Eigenschaft undefiniert.

Für Sitzungen, bei denen der OpenTok Media Router verwendet wird (Sitzungen mit dem Medienbetrieb (auf „routed“ gesetzt), führt eine proportionale Verringerung der Bildrate zu einer entsprechenden Verringerung der maximalen Bandbreite, die der Stream nutzen kann. In einer Sitzung mit dem Medienbetrieb auf "Relayed" eingestellt ist, wird durch die Verringerung der Bildrate die Bandbreite des Streams nicht verringert.

Sie können außerdem die Bildrate des Videostreams eines Abonnenten begrenzen. Weitere Informationen finden Sie unter Einschränkung der Bildrate eines abonnierten Streams.

Einstellung der maximalen Bitrate für einen Stream

Sie können die maximale Bitrate für einen veröffentlichten Stream festlegen. Die Festlegung der maximalen Bitrate kann dazu beitragen, den Bandbreitenverbrauch zu reduzieren, wenn ein Nutzer über eine gebührenpflichtige Verbindung zugreift. Siehe diese Dokumentation.

Einen Herausgeber löschen

Sie können einen Publisher löschen, indem Sie seine destroy() Methode:

    publisher.destroy();

Aufrufen der destroy() Die Methode löscht das Publisher-Objekt und entfernt es aus dem HTML-DOM.

Abrufen von Statistiken über den Stream eines Verlegers

Die Publisher.getStats() Die Methode liefert Ihnen ein Array von Objekten, die die aktuellen Audio- und Videostatistiken für den Publisher definieren. Für einen Publisher in einer gerouteten Sitzung (d. h. einer, die die OpenTok Media Router), enthält dieses Array ein Objekt, das die Statistiken für den einzelnen Audio-Video-Stream definiert, der an den OpenTok Media Router gesendet wird. In einer weitergeleiteten Sitzung enthält das Array ein Objekt für jeden Abonnenten des veröffentlichten Streams.

Um detaillierte Low-Level-Statistiken zu Peer-Verbindungen zu erhalten, verwenden Sie den Befehl Publisher.getRtcStatsReport() Methode. Sie gibt ein Versprechen zurück, das im Erfolgsfall mit einem Array von RtcStatsReport Objekte.

Siehe das Handbuch für Entwickler von Client Observability für detaillierte Informationen.

Testen des Streams eines Verlegers

Sie können einen Teststream veröffentlichen und dessen Audio- und Videostatistiken überprüfen, um die Art des Streams (z. B. hochauflösend oder nur Audio) zu ermitteln, die von Ihrer Verbindung unterstützt wird.

Um Statistiken für einen vom lokalen Client veröffentlichten Stream zu erhalten, müssen Sie eine Sitzung verwenden, die den OpenTok Media Router nutzt (Sitzungen mit der Option Medienbetrieb auf geroutet gesetzt), und Sie müssen die testNetwork Eigenschaft zu true im options Objekt, das Sie an die Session.subscribe() Methode. Sie können dann die getStats() Methode des „Subscriber“-Objekts, um Audio- und Videostatistiken für den von Ihnen veröffentlichten Stream abzurufen. Siehe dieses Thema für weitere Informationen.

Die opentok-Netzwerk-Test Repo enthält Beispielcode, der zeigt, wie die Statistiken eines Teststreams vor der Veröffentlichung in einer Sitzung verwendet werden können.

Video von einer anderen Quelle als einer Kamera oder einem Bildschirm veröffentlichen

Sie können die Videoquelle für einen Publisher auf ein Video festlegen MediaStreamTrack Objekt. Damit haben Sie folgende Möglichkeiten:

  • Veröffentlichen Sie das Video, indem Sie ein HTML-Canvas-Element als Video verwenden. Sie können die captureStream() Methode der HTMLCanvasElement Objekt und rufen Sie die getVideoTracks() Verfahren des daraus resultierenden CanvasCaptureMediaStream Objekt, um ein „MediaStreamTrack“-Objekt für ein Video abzurufen. Ein einfaches Beispiel finden Sie im Beispiel „Publish-Canvas“. opentok-web-samples repo auf GitHub.

  • Video aus einem Video-Element veröffentlichen. Rufen Sie die captureStream() Methode eines HTMLVideoElement Objekt, um ein MediaStream-Objekt zu erhalten. Das getVideoTracks() Die Methode des MediaStream-Objekts gibt ein Array von Audio-MediaStreamTrack-Objekten zurück (in der Regel nur eines). Das MediaStreamTrack-Objekt können Sie dann als audioSource Eigenschaft der options Objekt, das Sie an die OT.initPublisher() Methode. Ein einfaches Beispiel finden Sie im Beispiel „Publish-Video“ opentok-web-samples repo auf GitHub.

Sie können ein MediaStreamTrack-Videoobjekt als videoSource Eigenschaft der options Objekt, das Sie an die OT.initPublisher() Methode. Dadurch wird das durch das MediaStreamTrack-Objekt dargestellte Video zur Videoquelle für den veröffentlichten Stream.

Wiedergabe von Audio aus einer anderen Audioquelle als einem Mikrofon

Sie können die Audioquelle für einen Publisher auf eine Audiodatei festlegen MediaStreamTrack Objekt. Damit haben Sie folgende Möglichkeiten:

  • Audio aus einem Audio- oder Video-Element veröffentlichen. Rufen Sie die captureStream() Methode eines HTMLAudioElement Objekt oder ein HTMLVideoElement Objekt, um ein MediaStream-Objekt zu erhalten. Das getAudioTracks() Die Methode des MediaStream-Objekts ist ein Array von Audio-MediaStreamTrack-Objekten (in der Regel nur eines). Sie können das MediaStreamTrack-Objekt dann als audioSource Eigenschaft der options Objekt, das Sie an die OT.initPublisher() Methode.
  • Audio aus einem „MediaStreamTrack“-Objekt veröffentlichen. Sie können zum Beispiel die AudioKontext Objekt und das Web-Audio-API um Audio dynamisch zu erzeugen. Anschließend können Sie createMediaStreamDestination().stream.getAudioTracks()[0] auf das AudioContext-Objekt, um das Audio-MediaStreamTrack-Objekt zu erhalten, das als audioSource Eigenschaft der options Objekt, das Sie an die OT.initPublisher() Methode. Ein einfaches Beispiel finden Sie im Beispiel „Stereo-Audio“ opentok-web-samples repo auf GitHub.

Filter und Effekte auf veröffentlichte Audio- und Videodateien anwenden

Sie können Filter und Effekte wie Hintergrundersetzung oder Hintergrundunschärfe auf Audio- oder Videomaterial anwenden, das von einem Mikrofon oder einer Kamera stammt, die als Audio- oder Videoquelle für einen veröffentlichten Stream verwendet werden – siehe dieses Thema.

Einstellen von Hinweisen zu Videoinhalten zur Verbesserung der Videoleistung in bestimmten Situationen

Sie können einen Hinweis auf den Videoinhalt einstellen, um die Qualität und Leistung eines veröffentlichten Videos zu verbessern. Dies kann in bestimmten Situationen nützlich sein:

  • Bei der Veröffentlichung von Videos zur Bildschirmfreigabe, die in erster Linie entweder Text- oder Videoinhalte enthalten.
  • Wenn Sie eine Kamera als Videoquelle verwenden und lieber die Bildrate reduzieren, aber die Auflösung beibehalten möchten, können Sie den Inhaltshinweis auf „text“ oder „detail“ setzen. In einer weitergeleiteten Sitzung, sofern der Publisher die Verwendung von skalierbares Video, sendet er einen Stream in voller Auflösung mit niedriger Bildrate und – sofern die Netzwerkbedingungen dies zulassen – einen Stream in voller Auflösung mit normaler Bildrate. Der OpenTok Media Router leitet einen dieser Streams an die Teilnehmer weiter.

Dadurch wird der Browser angewiesen, Kodierungs- oder Verarbeitungsmethoden zu verwenden, die für den von Ihnen angegebenen Inhaltstyp besser geeignet sind.

Legen Sie den anfänglichen Hinweis auf den Videoinhalt für einen Stream fest, indem Sie den videoContentHint Eigenschaft der Optionen, die Sie in der OT.initPublisher() Methode:

var publisherOptions = {
  videoContentHint: "text",
  // other options, such as videoSource: "screen"
};
var publisher = OT.initPublisher(targetElement, publisherOptions, callbackFunction);

Sie können den Hinweis auf den Videoinhalt dynamisch ändern, indem Sie die setVideoContentHint() Methode eines Publisher-Objekts:

publisher.setVideoContentHint("motion");

Sie können den Hinweis auf den Videoinhalt auf einen der folgenden Werte setzen:

  • "" - Es wird kein Hinweis gegeben (Standardeinstellung). Der Veröffentlichungs-Client schätzt nach bestem Wissen und Gewissen, wie Videoinhalte behandelt werden sollten.
  • "motion" - Die Spur sollte so behandelt werden, als ob sie Video enthält, bei dem Bewegung wichtig ist. Sie können diese Einstellung z. B. für einen Video-Stream zur Bildschirmfreigabe verwenden, der Video enthält.
  • "detail" - Die Spur sollte so behandelt werden, als ob die Videodetails besonders wichtig wären. Sie können diese Einstellung z. B. für einen Videostream zur Bildschirmfreigabe verwenden, der Textinhalte, Bilder oder Strichzeichnungen enthält.
  • "text" - Die Spur sollte so behandelt werden, als ob Textdetails besonders wichtig wären. Sie können diese Einstellung z. B. für einen Videostream zur Bildschirmfreigabe verwenden, der Textinhalte enthält.

Bei den Inhaltshinweisen "Text" und "Detailliert" versucht der Browser, eine hohe Auflösung beizubehalten, auch wenn er die Videobildrate reduzieren muss. Bei dem Inhaltshinweis "Bewegung" reduziert der Browser die Auflösung, um zu verhindern, dass die Bildrate einbricht.

Weitere Informationen zu diesen Optionen finden Sie in der W3C-Arbeitsentwurf.

Chrome 60+, Safari 12.1+, Edge 79+, Opera 47+, aktuelle Versionen von Samsung Internet, WebView unter Android 70+ sowie WebView unter iOS 12.2+ unterstützen Hinweise zu Videoinhalten. In anderen Browsern wird diese Einstellung ignoriert.

Wenn Sie sich mit einer niedrigen Bildrate abfinden können, könnten Sie auch Folgendes in Betracht ziehen: Begrenzung der Bildrate von abonnierten Streams um die Qualität zu verbessern.

Audio-Ausweichoption des Herausgebers

Weitere Informationen finden Sie im Entwicklerhandbuch unter Audio-Fallback . Die Audio-Fallback-Funktion des Herausgebers bietet eine verbesserte Überwachung von Bandbreite und Qualität, um die Kommunikation zu optimieren.

Andere Audio- und Videooptionen

Weitere Informationen finden Sie im Entwicklerhandbuch unter Einstellen von Audio und Video.

Bewährte Praktiken bei der Veröffentlichung

Dieser Abschnitt enthält Tipps für die erfolgreiche Veröffentlichung von Streams.

Zugriff auf das Gerät zulassen

Es hat sich bewährt, Ihre Nutzer darauf hinzuweisen, dass sie aufgefordert werden, den Zugriff auf ihre Kamera und ihr Mikrofon zu erlauben. Wir haben festgestellt, dass die mit Abstand meisten Fehler bei der Veröffentlichung darauf zurückzuführen sind, dass Nutzer auf die Schaltfläche „Ablehnen“ klicken oder gar nicht auf die Schaltfläche „Zulassen“ klicken. Wir stellen Ihnen alle Ereignisse zur Verfügung, die Sie benötigen, um Ihre Nutzer durch diesen Vorgang zu führen:

publisher.on({
  accessDialogOpened: function (event) {
    // Show allow camera message
    pleaseAllowCamera.style.display = 'block';
  },
  accessDialogClosed: function (event) {
    // Hide allow camera message
    pleaseAllowCamera.style.display = 'none';
  }
});

Es ist auch eine gute Idee, Ihre Website über SSL bereitzustellen. Der Grund dafür ist, dass Chrome von den Nutzern nur einmal pro Domain verlangt, den Zugriff auf Geräte zu erlauben, wenn diese Domain über SSL bereitgestellt wird. Das bedeutet, dass Ihre Nutzer (wenn sie Chrome verwenden) nicht jedes Mal, wenn sie die Seite laden, mit dem lästigen Dialogfeld "Zulassen/Ablehnen" konfrontiert werden.

OT.initPublisher() und Session.publish() aufteilen

Außerdem empfehlen wir die Aufteilung der OT.initPublisher() und Session.publish() Schritte. Dadurch wird die anfängliche Verbindungszeit verkürzt, da Sie eine Verbindung zur Sitzung herstellen, während Sie darauf warten, dass der Benutzer auf die Schaltfläche "Zulassen" klickt. Also statt:

session.connect(token, function (err) {
{... your error handling code ...}
if (!err) {
    var publisher = OT.initPublisher();
    session.publish(publisher);
  }
});

Bewegen Sie die OT.initPublisher() bevor Sie eine Verbindung herstellen, wie im Folgenden beschrieben:

var publisher = OT.initPublisher();
session.connect(token, function (err) {
{... your error handling code ...}
  if (!err) {
    session.publish(publisher);
  }
});

Auflösung und Bildrate

Sie können die Auflösung und die Bildrate des Publishers bei der Initialisierung einstellen:

OT.initPublisher(divId, {
  resolution: '320x240',
  frameRate: 15
});

Standardmäßig ist die Auflösung eines Publishers 640x480, aber Sie können sie auch auf 1920x1080, 1280x720 oder 320x240 einstellen. Am besten versuchen Sie, die Auflösung an die Größe anzupassen, in der das Video angezeigt werden soll. Wenn Sie das Video nur mit 320x240 Pixeln anzeigen, macht es keinen Sinn, mit 1280x720 oder 1920x1080 zu streamen. Durch die Verringerung der Auflösung können Sie Bandbreite sparen und Überlastungen und Verbindungsabbrüche vermeiden.

Standardmäßig beträgt die Bildrate des Videos 30 Bilder pro Sekunde, aber Sie können sie auch auf 15, 7 oder 1 einstellen. Durch die Verringerung der Bildrate kann die erforderliche Bandbreite reduziert werden. Videos mit geringerer Auflösung können eine niedrigere Bildrate haben, ohne dass der Benutzer einen großen Unterschied bemerkt. Wenn Sie also eine niedrige Auflösung verwenden, sollten Sie auch eine niedrige Bildrate in Betracht ziehen.

Weitere Informationen finden Sie in der Dokumentation zu OT.initPublisher().

Fehlersuche

Befolgen Sie die Tipps in diesem Abschnitt, um Verbindungsprobleme beim Veröffentlichen zu vermeiden. Allgemeine Informationen zur Fehlerbehebung finden Sie unter Fehlerbehebung – Web.

Umgang mit Fehlern

Es gibt Callback-Methoden für beide Session.publish() und OT.initPublisher(). Wir empfehlen, die Fehlerantworten auf diese beiden Methoden zu behandeln. Wie bereits erwähnt, ist es am besten, diese Schritte aufzuteilen und die OT.initPublisher() bevor Sie mit der Verbindung zu Ihrer Sitzung begonnen haben. Es erleichtert auch die Fehlerbehandlung, wenn Sie nicht beide Methoden gleichzeitig aufrufen. Der Grund dafür ist, dass beide Fehlerbehandlungsmethoden ausgelöst werden, wenn ein Fehler veröffentlicht wird. Es ist am besten, zu warten, bis OT.initPublisher() zu vervollständigen und Session.connect() zu vervollständigen, und rufen Sie dann Session.publish(). Auf diese Weise können Sie alle hardwarebezogenen Probleme in der OT.initPublisher() Rückruf und alle netzbezogenen Fragen in der Session.publish() Rückruf.

var connected = false,
  publisherInitialized = false;

var publisher = OT.initPublisher(function(err) {
  if (err) {
    // handle error
  } else {
    publisherInitialized = true;
    publish();
  }
});

var publish = function() {
  if (connected && publisherInitialized) {
    session.publish(publisher);
  }
};

session.connect(token, function(err) {
  if (err) {
    // handle error
  } else {
    connected = true;
    publish();
  }
});

Zugang verweigert

Die höchste Anzahl von Misserfolgen bei OT.initPublisher() sind darauf zurückzuführen, dass der Endnutzer den Zugang zu Kamera und Mikrofon verweigert. Dies kann entweder durch Abhören des accessDenied Ereignis oder durch Abwarten einer Fehlerantwort auf die Methode OT.initPublisher() mit einer code Eigenschaft auf 1500 gesetzt und eine message Eigenschaft auf "Publisher Access Denied:" gesetzt. Wir empfehlen, dass Sie diesen Fall behandeln und dem Benutzer eine Meldung anzeigen, dass er versuchen sollte, erneut zu veröffentlichen und den Zugriff auf die Kamera zu erlauben.

publisher.on({
  'accessDenied': function() {
    showMessage('Please allow access to the Camera and Microphone and try publishing again.');
  }
});

Zugang zum Gerät

Ein weiterer Grund für OT.initPublisher() Wenn OpenTok nicht auf eine Kamera oder ein Mikrofon zugreifen kann, schlägt das Programm fehl. Dies kann passieren, wenn keine Kamera oder kein Mikrofon an den Rechner angeschlossen ist, wenn etwas mit dem Treiber für die Kamera oder das Mikrofon nicht stimmt oder wenn eine andere Anwendung die Kamera oder das Mikrofon verwendet (dies geschieht nur unter Windows). Sie können versuchen, das Auftreten dieser Probleme zu minimieren, indem Sie unsere Hardware-Setup-Komponente verwenden oder die Funktion OT.getDevices() Methode direkt. Sie sollten jedoch auch jeden Fehler behandeln, wenn Sie OT.initPublisher() denn es kann immer noch etwas schief gehen. Zum Beispiel könnte der Benutzer den Zugriff auf die Kamera oder das Mikrofon verweigert haben. In diesem Fall muss die error.name Eigenschaft wird auf "OT_USER_MEDIA_ACCESS_DENIED":

publisher = OT.initPublisher('publisher', {}, function (err) {
  if (err) {
    if (err.name === 'OT_USER_MEDIA_ACCESS_DENIED') {
      // Access denied can also be handled by the accessDenied event
      showMessage('Please allow access to the Camera and Microphone and try publishing again.');
    } else {
      showMessage('Failed to get access to your camera or microphone. Please check that your webcam'
        + ' is connected and not being used by another application and try again.');
    }
    publisher.destroy();
    publisher = null;
  }
});

Netzwerk-Fehler

Die anderen Gründe für Fehler bei der Veröffentlichung sind in der Regel auf eine Art von Netzwerkfehler zurückzuführen. Wir behandeln diese in dem Callback zu Session.publish(). Wenn der Benutzer nicht mit dem Netz verbunden ist, wird der Callback-Funktion ein Fehlerobjekt mit dem name Eigenschaft eingestellt auf "OT_NOT_CONNECTED". Befindet sich der Nutzer in einem sehr restriktiven Netzwerk, das keine WebRTC-Verbindungen zulässt, kann der Publisher keine Verbindung herstellen, und das Publisher-Element zeigt lediglich ein sich drehendes Rad an. Dieser Fehler hat einen name Eigenschaft eingestellt auf "OT_CREATE_PEER_CONNECTION_FAILED". In diesem Fall empfiehlt es sich, dem Benutzer eine Nachricht zu übermitteln, die ihn darauf hinweist, dass die Veröffentlichung fehlgeschlagen ist und dass er seine Netzwerkverbindung überprüfen sollte. Die Behandlung dieser Fehler sieht folgendermaßen aus:

session.publish(publisher, function(err) {
  if (err) {
    switch (err.name) {
      case "OT_NOT_CONNECTED":
        showMessage("Publishing your video failed. You are not connected to the internet.");
        break;
      case "OT_CREATE_PEER_CONNECTION_FAILED":
        showMessage("Publishing your video failed. This could be due to a restrictive firewall.");
        break;
      default:
        showMessage("An unknown error occurred while trying to publish your video. Please try again later.");
    }
    publisher.destroy();
    publisher = null;
  }
});

Verlust der Konnektivität

Ihr Publisher kann auch die Verbindung verlieren, nachdem er bereits eine Verbindung hergestellt hat. In den meisten Fällen führt dies dazu, dass auch die Sitzung ihre Verbindung verliert, aber das ist nicht immer der Fall. Sie können das Trennen der Verbindung des Publishers behandeln, indem Sie auf die streamDestroyed Ereignis mit einer reason Eigenschaft auf "networkDisconnected" wie folgt eingestellt:

publisher.on({
  streamDestroyed: function (event) {
    if (event.reason === 'networkDisconnected') {
      showMessage('Your publisher lost its connection. Please check your internet connection and try publishing again.');
    }
  }
});

Alles zusammenfügen

Der folgende Code erstellt einen Verleger, stellt eine Verbindung zu einer Sitzung her (siehe Grundlagen zu Sitzungen), veröffentlicht einen Stream in der Sitzung, wenn sich der Client mit der Sitzung verbindet, und erkennt, wann der Verleger das Streaming beginnt und beendet:

var session;
var publisher;

// Replace with the replacement element ID:
publisher = OT.initPublisher(replacementElementId);
publisher.on({
  streamCreated: function (event) {
    console.log("Publisher started streaming.");
  },
  streamDestroyed: function (event) {
    console.log("Publisher stopped streaming. Reason: "
      + event.reason);
  }
});

// Replace apiKey and sessionID with your own values:
session = OT.initSession(apiKey, sessionID);
// Replace token with your own value:
session.connect(token, function (error) {
  if (session.capabilities.publish == 1) {
    session.publish(publisher);
  } else {
    console.log("You cannot publish an audio-video stream.");
  }
});

Implementierung von Wiederholungsversuchen bei der Veröffentlichung von Sitzungen

Vorübergehende Fehler beim Veröffentlichen sind ein bekanntes und wiederkehrendes Problem im Video API-JS-SDK, insbesondere in mobilen Browsern. Wenn session.publish() Schlägt der Vorgang fehl, gibt das SDK über den Callback des Completion-Handlers einen Fehler zurück. Es wird empfohlen, auf Anwendungsebene eine Wiederholungslogik mit einer Verzögerung zwischen den Versuchen zu implementieren.

Anmerkung: Integrierte Unterstützung für Wiederholungsversuche bei session.publish() steht auf der SDK-Roadmap. Bis es verfügbar ist, müssen Sie dies selbst implementieren.

Wie session.publish() Werke

session.publish() kann auf zwei Arten aufgerufen werden:

  • Bei einem vorinitialisierten Publisher: session.publish(publisher, callback) — du rufst an OT.initPublisher() zuerst, dann übergebe die resultierende Publisher-Instanz an session.publish(). Das ist die empfohlene Vorgehensweise da es die Medienerfassung von der Stream-Erstellung trennt und so die Fehlerbehandlung übersichtlicher gestaltet.
  • Ohne Publisher-Instanz: session.publish(targetElement, options, callback) — das SDK ruft intern auf OT.initPublisher() für Sie. In diesem Fall treten sowohl Fehler bei der Medienerfassung als auch Fehler bei der Stream-Erstellung über die einzige session.publish() Rückruf.

Bewährte Vorgehensweise: Split OT.initPublisher() und session.publish() in einzelne Schritte. Auf diese Weise können Sie Hardware- oder Medienfehler in der OT.initPublisher() Callback- und Netzwerk-/Signalisierungsfehler in der session.publish() Callback – dadurch wird die Logik für Wiederholungsversuche deutlich einfacher und zielgerichteter.

// Recommended: split initialization from publishing
let publisherReady = false;
let sessionConnected = false;

const publisher = OT.initPublisher('publisher-container', publisherOptions, (err) => {
  if (err) {
    handleInitPublisherError(err); // hardware/media errors — see OT.initPublisher() errors below
    return;
  }
  publisherReady = true;
  maybePublish();
});

session.connect(token, (err) => {
  if (err) { /* handle connection error */ return; }
  sessionConnected = true;
  maybePublish();
});

function maybePublish() {
  if (sessionConnected && publisherReady) {
    publishWithRetry(session, publisher);
  }
}

Warum es zu Veröffentlichungsfehlern kommt

Die häufigsten Ursachen für vorübergehende Veröffentlichungsfehler sind:

  • Zeitüberschreitungen bei „StreamCreateRequest“ (Fehler 1500): Der Publisher konnte die Stream-Erstellung nicht innerhalb einer angemessenen Zeitspanne abschließen – dies wird in der Regel durch Netzwerkverzögerungen während der ICE-/SDP-Verhandlung verursacht.
  • mediaStopped Ereignisse während des Veröffentlichungsablaufs, wo der Zugriff auf Mediengeräte unterbrochen werden kann.
  • Wiederverwendung von Publisher-Objekten ohne ordnungsgemäße Bereinigung — Wiederverwendung einer Publisher-Instanz, die mit anderen Einschränkungen initialisiert wurde, ohne den Aufruf unpublish und neu zu initialisieren.
  • OT_NOT_CONNECTED — Versuch, etwas zu veröffentlichen, bevor die Sitzung vollständig hergestellt ist.
  • OT_PERMISSION_DENIED — Das Token verfügt nicht über die Rolle „publish“ (kein erneuter Versuch möglich).

Fehler aus OT.initPublisher()

Wenn Sie einen Publisher mit OT.initPublisher(), werden alle Hardware- und Medienerfassungsfehler an den Abschluss-Handler weitergeleitet — vor session.publish() aufgerufen wird. Behandeln Sie diese in diesem Callback mithilfe der unten aufgeführten Maßnahmen für die einzelnen Fehler: Einige erfordern eine Benutzeraktion oder eine Code-Korrektur, während vorübergehende Medienfehler durch eine Neuinitialisierung des Publishers behoben werden können.

Anmerkung: Wenn Sie anrufen session.publish() Ohne einen vorab initialisierten Publisher treten dieselben Fehler über die session.publish() stattdessen einen Callback.

error.name Beschreibung Empfohlene Maßnahme
OT_HARDWARE_UNAVAILABLE Die Hardware ist vorhanden, konnte jedoch nicht abgerufen werden (z. B. weil sie von einer anderen Application genutzt wird). Fordern Sie den Benutzer auf, andere auf dem Gerät ausgeführte Applications zu schließen, und rufen Sie dann OT.initPublisher() wieder.
OT_INVALID_PARAMETER Ein oder mehrere Parameter, die an OT.initPublisher() waren ungültig. Das an OT.initPublisher().
OT_MEDIA_ENDED Die ended Ereignis des Video-Elements, das während der Initialisierung ausgelöst wird. Initialisieren Sie den Publisher neu.
OT_MEDIA_ERR_ABORTED Das Abrufen des Streams für das Video-Element wurde abgebrochen. Initialisieren Sie den Publisher nach einer kurzen Verzögerung erneut.
OT_MEDIA_ERR_DECODE Beim Versuch, den Stream im Video-Element abzuspielen, ist ein Dekodierungsfehler aufgetreten. Initialisieren Sie den Publisher nach einer kurzen Verzögerung erneut.
OT_MEDIA_ERR_NETWORK Aufgrund eines Netzwerkfehlers wurde der Abruf des Streams unterbrochen. Initialisieren Sie den Publisher nach einer kurzen Verzögerung erneut.
OT_MEDIA_ERR_SRC_NOT_SUPPORTED Der Stream wurde als für die Wiedergabe ungeeignet erkannt. Überprüfen Sie die Konfiguration der Video-/Audioquelle des Publishers und führen Sie eine Neuinitialisierung durch.
OT_NOT_SUPPORTED Ein Element der Medienanforderung des Benutzers wird vom Browser nicht unterstützt. Den Benutzer informieren und keinen erneuten Versuch unternehmen.
OT_NO_DEVICES_FOUND Es wurden keine Audio- oder Video-Eingabegeräte gefunden. Fordern Sie den Benutzer auf, ein Gerät anzuschließen, bevor Sie es erneut versuchen.
OT_NO_VALID_CONSTRAINTS Sowohl Video als auch Audio waren deaktiviert – mindestens eines davon muss aktiviert sein. Sicherstellen publishAudio oder publishVideo ist true in den Publisher-Optionen.
OT_PROXY_URL_ALREADY_SET_ERROR Die proxyUrl wurde bereits festgelegt. Eine erneute Festlegung hat keine Auswirkungen. Legen Sie die Proxy-URL nur einmal fest, und zwar bevor Sie ein Session- oder Publisher-Objekt initialisieren.
OT_REQUESTED_DEVICE_PERMISSION_DENIED Für das angeforderte Audiogerät liegt keine Berechtigung zur Nutzung vor. Den Benutzer auffordern, die Geräteberechtigungen zu erteilen.
OT_USER_MEDIA_ACCESS_DENIED Der Nutzer hat den Zugriff auf die Kamera, das Mikrofon oder den Bildschirm verweigert. Den Benutzer auffordern, den Zugriff in den Browsereinstellungen zuzulassen; keinen automatischen Wiederholungsversuch durchführen.
OT_SCREEN_SHARING_NOT_SUPPORTED Die Bildschirmfreigabe wird in diesem Browser nicht unterstützt. Den Benutzer informieren und keinen erneuten Versuch unternehmen.
OT_UNABLE_TO_CAPTURE_SCREEN Die Bildschirmfreigabe wurde angefordert, wird jedoch nicht unterstützt (z. B. videoSource eingestellt auf "screen", "application", oder "window"). Rufen Sie an. OT.checkScreenSharingCapability() vor der Initialisierung eines Bildschirmfreigabe-Publishers.
OT_SCREEN_SHARING_EXTENSION_NOT_REGISTERED Für die Bildschirmfreigabe ist eine Browser-Erweiterung erforderlich, es wurde jedoch noch keine registriert. Registrieren Sie die Erweiterung, bevor Sie den Aufruf ausführen OT.initPublisher().
OT_SCREEN_SHARING_EXTENSION_NOT_INSTALLED Für die Bildschirmfreigabe ist eine Browser-Erweiterung erforderlich, diese ist jedoch nicht installiert. Weisen Sie den Benutzer an, die erforderliche Erweiterung zu installieren.
const publisher = OT.initPublisher('publisher-container', publisherOptions, (err) => {
  if (!err) {
    publisherReady = true;
    maybePublish();
    return;
  }

  // Hardware/media errors — handle before session.publish() is called
  switch (err.name) {
    case 'OT_REQUESTED_DEVICE_PERMISSION_DENIED':
      showMessage('Please allow access to your camera and microphone and try again.');
      break;
    case 'OT_HARDWARE_UNAVAILABLE':
    case 'OT_NO_DEVICES_FOUND':
      showMessage('Could not access your camera or microphone. Please check your devices.');
      break;
    case 'OT_SCREEN_SHARING_NOT_SUPPORTED':
    case 'OT_UNABLE_TO_CAPTURE_SCREEN':
    case 'OT_SCREEN_SHARING_EXTENSION_NOT_REGISTERED':
    case 'OT_SCREEN_SHARING_EXTENSION_NOT_INSTALLED':
      showMessage('Screen sharing is not available. Please check your browser settings.');
      break;
    default:
      showMessage('Could not initialize the publisher. Please try again.');
  }

  publisher.destroy();
});

Behebbare vs. nicht behebbare Fehler aus session.publish()

Nicht alle session.publish() Fehler sind nicht alle gleich. Vor der Implementierung einer Wiederholungslogik ist es unerlässlich, Fehler korrekt zu klassifizieren – der erneute Versuch bei einem nicht behebbaren Fehler verschwendet Zeit, verschlechtert das Benutzererlebnis und kann echte Fehler verschleiern, die eine andere Reaktion erfordern.

Anmerkung: Fehlercode 1500 ist als Klassifizierungsmechanismus veraltet. Verwenden Sie stets das error.name Eigenschaft zur programmgesteuerten Fehlererkennung, da sie dem jeweiligen Fehlerszenario zugeordnet ist.

Anmerkung: Wenn session.publish() heißt ohne ein vorab initialisierter Publisher, Fehler bei der Medienerfassung aus OT.initPublisher() (oben aufgeführt) können auch durch die session.publish() Callback. In diesem Fall sind sie als nicht wiederholbar zu behandeln und es gilt die oben beschriebene Vorgehensweise.

Unbehebbare Fehler – Nicht erneut versuchen

Diese Fehler sind auf Programmierfehler, strenge Berechtigungsbeschränkungen oder einen ungültigen Aufrufkontext zurückzuführen. Ein erneuter Versuch führt nicht zur Behebung dieser Fehler. Zeigen Sie dem Benutzer stattdessen eine aussagekräftige Meldung an oder korrigieren Sie die Anwendungslogik.

error.name Beschreibung Empfohlene Maßnahme
OT_NOT_CONNECTED session.publish() wurde aufgerufen, bevor die Sitzung hergestellt wurde. Sicherstellen session.connect() vor der Veröffentlichung erfolgreich abgeschlossen wurde.
OT_PERMISSION_DENIED Die Rolle des Tokens erlaubt keine Veröffentlichung (muss publisher oder moderator). Teilen Sie dem Benutzer mit, dass er keine Veröffentlichungsberechtigungen hat. Versuchen Sie es nicht erneut – generieren Sie ein Token mit der richtigen Rolle.
OT_INVALID_PARAMETER Der übergebene Publisher ist ungültig, wurde bereits veröffentlicht oder ist bereits einer anderen Sitzung zugeordnet. Anwendungslogik korrigieren: Aufruf session.unpublish(publisher) vor der erneuten Veröffentlichung oder einen neuen Herausgeber anlegen.
OT_USER_MEDIA_ACCESS_DENIED Dem Nutzer wurde der Zugriff auf die Kamera oder das Mikrofon (bzw. auf den Bildschirm bei Streams mit Bildschirmfreigabe) verweigert. Fordern Sie den Benutzer auf, den Zugriff auf das Gerät in seinen Browsereinstellungen zuzulassen, und versuchen Sie es erneut. Führen Sie keinen automatischen Wiederholungsversuch durch.
OT_CHROME_MICROPHONE_ACQUISITION_ERROR Aufgrund eines bekannten Browserfehlers konnte der Browser keinen Zugriff auf das Mikrofon herstellen. Der Benutzer muss den Browser neu starten und die Seite neu laden, um das Problem zu beheben. Den Benutzer informieren und keinen erneuten Versuch unternehmen.
OT_SCREEN_SHARING_NOT_SUPPORTED Die Bildschirmfreigabe wird in diesem Browser nicht unterstützt. Den Benutzer informieren und keinen erneuten Versuch unternehmen.
OT_SCREEN_SHARING_EXTENSION_NOT_REGISTERED Für die Bildschirmfreigabe ist eine Browser-Erweiterung erforderlich, es wurde jedoch noch keine registriert. Registrieren Sie die Erweiterung, bevor Sie versuchen, einen Bildschirmfreigabestream zu veröffentlichen.
OT_SCREEN_SHARING_EXTENSION_NOT_INSTALLED Für die Bildschirmfreigabe ist eine Browser-Erweiterung erforderlich, diese ist jedoch nicht installiert. Weisen Sie den Benutzer an, die erforderliche Erweiterung zu installieren.
OT_CONSTRAINTS_NOT_SATISFIED Die angeforderten Medienanforderungen (Auflösung, Bildfrequenz, Gerät) konnten vom Browser nicht erfüllt werden. Passen Sie die Publisher-Einschränkungen an und führen Sie eine Neuinitialisierung durch.
OT_NO_VALID_CONSTRAINTS Sowohl Video als auch Audio waren deaktiviert – mindestens eines davon muss aktiviert sein. Sicherstellen publishAudio oder publishVideo ist true vor dem Aufruf session.publish().
OT_NOT_SUPPORTED Ein Element der Medienanforderung des Benutzers wird vom Browser nicht unterstützt. Den Benutzer informieren und keinen erneuten Versuch unternehmen.
OT_STREAM_CREATE_FAILED Der Benutzer hat versucht, in einer Sitzung mit End-to-End-Verschlüsselung (E2EE) zu veröffentlichen, ohne einen Verschlüsselungsschlüssel anzugeben; oder der Stream konnte im Servermodell nicht erstellt werden. Stellen Sie bei E2EE-Sitzungen sicher, dass ein Verschlüsselungsschlüssel über session.setEncryptionSecret() vor der Veröffentlichung.
OT_INVALID_AUDIO_OUTPUT_SOURCE Es wurde eine ungültige ID für ein Audioausgabegerät angegeben. Verify that the device ID is a valid audio output device before trying it again.
OT_UNABLE_TO_CAPTURE_MEDIA Medien können nicht erfasst werden – es ist ein unbekannter Fehler aufgetreten. Informieren Sie den Benutzer und fordern Sie ihn auf, die Verfügbarkeit des Geräts zu prüfen.

Behebbare Fehler – Wiederholung des Versuchs ist unbedenklich

Diese Fehler werden in der Regel durch vorübergehende Netzwerkstörungen, Zeitüberschreitungen bei der Signalübertragung oder eine vorübergehende Nichtverfügbarkeit der Plattform verursacht. Sie sind das Hauptziel der Wiederholungslogik.

error.name Beschreibung Empfohlene Maßnahme
OT_TIMEOUT (Code 1500) session.publish() Zeitüberschreitung – das StreamCreateRequest wurde nicht rechtzeitig abgeschlossen. Dies wird meist durch Verzögerungen bei der ICE/SDP-Aushandlung verursacht oder mediaStopped Veranstaltungen. Erneuter Versuch mit exponentiellem Backoff (bis zu 3 Versuche). Die gleiche Publisher-Instanz wiederverwenden, sofern sie nicht zerstört wurde.
OT_ICE_WORKFLOW_FAILED Die ICE-Verhandlung ist fehlgeschlagen – die Peer-Verbindung konnte nicht hergestellt werden. Tritt häufig vorübergehend in Netzwerken mit Einschränkungen auf. Versuchen Sie es erneut. Sollte das Problem nach allen Versuchen weiterhin bestehen, weisen Sie den Benutzer auf ein mögliches Netzwerk- oder Firewall-Problem hin.
OT_CREATE_PEER_CONNECTION_FAILED Die WebRTC-Peer-Verbindung konnte nicht hergestellt werden. Dies kann auf eine restriktive Firewall oder ein vorübergehendes Plattformproblem hindeuten. Versuchen Sie es erneut. Sollte das Problem weiterhin bestehen, zeigen Sie eine Meldung an, in der der Benutzer aufgefordert wird, seine Netzwerkverbindung zu überprüfen.
OT_MEDIA_ERR_ABORTED / OT_MEDIA_ERR_NETWORK Die Medienübertragung wurde aufgrund eines Netzwerkfehlers abgebrochen oder unterbrochen. Versuchen Sie es nach einer kurzen Pause erneut.
OT_MEDIA_ERR_DECODE Beim Versuch, den Stream im Video-Element abzuspielen, ist ein Dekodierungsfehler aufgetreten. Versuchen Sie es nach einer kurzen Wartezeit erneut. Sollte das Problem weiterhin bestehen, ist das Medienformat möglicherweise nicht kompatibel.
OT_MEDIA_ERR_SRC_NOT_SUPPORTED Der Stream wurde als für die Wiedergabe ungeeignet erkannt. Versuchen Sie es noch einmal. Sollte das Problem weiterhin bestehen, überprüfen Sie die Konfiguration der Video-/Audioquelle des Anbieters.
OT_SET_REMOTE_DESCRIPTION_FAILED Die WebRTC-Verbindung ist während setRemoteDescription. In der Regel handelt es sich um ein vorübergehendes Problem bei der Signalübertragung. Versuche es erneut mit einer Wartezeit. Sollte das Problem nach allen Versuchen weiterhin bestehen, weise den Benutzer auf ein mögliches Netzwerkproblem hin.
OT_UNEXPECTED_SERVER_RESPONSE Vom Server wurde ein unerwarteter Fehler zurückgegeben. Versuchen Sie es nach einer kurzen Wartezeit erneut. Sollte das Problem weiterhin bestehen, protokollieren Sie den Fehler und informieren Sie den Benutzer.

Fehler, die eine andere Maßnahme erfordern (keinen einfachen erneuten Versuch)

Manche Fehler lassen sich weder durch einen einfachen erneuten Versuch noch durch einen vollständigen Abbruch beheben – sie erfordern eine bestimmte Korrekturmaßnahme, bevor ein erneuter Versuch unternommen werden kann.

error.name Beschreibung Empfohlene Maßnahme
OT_HARDWARE_UNAVAILABLE Die Kamera oder das Mikrofon ist nicht verfügbar (z. B. wird es gerade von einer anderen Anwendung genutzt oder ist nicht angeschlossen). Fordern Sie den Benutzer auf, andere auf dem Gerät geöffnete Applications zu schließen, und initialisieren Sie den Publisher anschließend neu mit OT.initPublisher() bevor Sie es erneut versuchen.
OT_NO_DEVICES_FOUND Es wurden keine Audio- oder Video-Eingabegeräte gefunden. Fordern Sie den Benutzer auf, ein Gerät anzuschließen. Versuchen Sie es erst erneut, wenn der Benutzer bestätigt hat, dass ein Gerät verfügbar ist.

Zusammenfassung: Empfohlenes Wiederholungsmuster mit Fehlerklassifizierung

async function publishWithRetry(session, publisher, attempt = 1) {
  const MAX_RETRIES = 3;
  const RETRY_DELAY_MS = 2000;

  const error = await new Promise((resolve) => {
    session.publish(publisher, resolve);
  });

  if (!error) {
    console.log('Publishing started successfully.');
    return;
  }

  // Non-recoverable: programmer error or hard permission constraint
  const nonRetryable = [
    'OT_NOT_CONNECTED',
    'OT_PERMISSION_DENIED',
    'OT_INVALID_PARAMETER',
    'OT_USER_MEDIA_ACCESS_DENIED',
    'OT_CHROME_MICROPHONE_ACQUISITION_ERROR',
    'OT_SCREEN_SHARING_NOT_SUPPORTED',
    'OT_SCREEN_SHARING_EXTENSION_NOT_REGISTERED',
    'OT_SCREEN_SHARING_EXTENSION_NOT_INSTALLED',
    'OT_CONSTRAINTS_NOT_SATISFIED',
    'OT_NO_VALID_CONSTRAINTS',
    'OT_NOT_SUPPORTED',
    'OT_STREAM_CREATE_FAILED',
    'OT_INVALID_AUDIO_OUTPUT_SOURCE',
    'OT_UNABLE_TO_CAPTURE_MEDIA',
  ];

  // Requires corrective action before retrying
  const requiresAction = [
    'OT_HARDWARE_UNAVAILABLE',
    'OT_NO_DEVICES_FOUND',
  ];

  if (nonRetryable.includes(error.name)) {
    console.error('Non-retryable error — user action or code fix required:', error.name);
    handleNonRecoverableError(error);
    return;
  }

  if (requiresAction.includes(error.name)) {
    console.warn('Device error — prompting user before retrying:', error.name);
    handleDeviceError(error);
    return;
  }

  // Recoverable: retry with backoff
  if (attempt < MAX_RETRIES) {
    console.warn(`Publish attempt ${attempt} failed (${error.name}), retrying...`);
    await delay(RETRY_DELAY_MS * attempt);
    await publishWithRetry(session, publisher, attempt + 1);
  } else {
    console.error('All publish attempts failed. Disconnecting user.');
    handlePublishFailure(session);
  }
}

function handleNonRecoverableError(error) {
  // Surface a meaningful message to the user based on error.name
  // e.g. for OT_USER_MEDIA_ACCESS_DENIED: "Please allow camera/mic access"
}

function handleDeviceError(error) {
  // Prompt the user to check their device, then allow them to retry manually
}

function handlePublishFailure(session) {
  session.disconnect();
}

Verwendung:

const publisher = OT.initPublisher('publisher-container', publisherOptions);

// Wait for session to be connected before publishing
session.connect(token, (err) => {
  if (err) { /* handle connection error */ return; }
  publishWithRetry(session, publisher);
});

Wichtig: Bereinigung der Publisher vor einem erneuten Versuch

In den meisten Ausfallszenarien – einschließlich OT_TIMEOUT / OT_ICE_WORKFLOW_FAILED — die Publisher-Instanz kann wiederverwendet werden direkt für das nächste session.publish() Aufruf. Sie müssen es nicht neu initialisieren.

Wenn ein Veröffentlichungsversuch fehlschlägt, bricht das SDK den Stream ab, den es zu erstellen versuchte, und gibt eine streamDestroyed Ereignis beim Herausgeber mit reason: "reset". Dies ist eine erwartete Bereinigung und führt dazu, dass nicht erfordert eine erneute Initialisierung des Publishers – Sie können es mit derselben Instanz erneut versuchen. Beachten Sie, dass "reset" ist ein allgemeiner Grund vom Typ „Der Stream des Publishers wurde abgebrochen“ (er wird auch ausgegeben, wenn man publisher.destroy()), betrachten Sie es daher eher als Signal zur Bereinigung denn als eigenständigen Indikator für einen Veröffentlichungsfehler; verwenden Sie die error.name von der session.publish() Callback, um zu entscheiden, ob ein erneuter Versuch unternommen werden soll.

Das SDK tut Folgendes: nicht automatisch erneut versuchen session.publish() In Ihrem Namen – Die Logik für Wiederholungsversuche muss, wie oben gezeigt, auf Anwendungsebene implementiert werden.

Der einzige Fall, in dem Sie den Publisher mit OT.initPublisher() Bevor ein erneuter Versuch unternommen wird, ist der Zeitpunkt, zu dem der Herausgeber selbst destroyed Das Ereignis wird ausgelöst. Dieses Ereignis ist endgültig und zeigt an, dass das Publisher-Objekt selbst nicht mehr verwendbar ist.

publisher.on('destroyed', () => {
  // Publisher object is no longer usable — reinitialize before retrying
  publisher = OT.initPublisher('publisher-container', publisherOptions);
});

// A streamDestroyed event with reason 'reset' is emitted by the SDK when it tears
// down the stream (during a failed publish attempt, or when you call publisher.destroy()).
// A 'reset' during a failed publish does NOT require reinitializing the publisher.
publisher.on('streamDestroyed', (event) => {
  if (event.reason === 'reset') {
    // Expected cleanup — reuse the same publisher instance
    return;
  }
  // Handle other streamDestroyed reasons as appropriate for your application
});

Was man NICHT tun sollte

  • Do nicht aufrufen OT.initPublisher() zweimal auf dasselbe Publisher-Objekt mit unterschiedlichen Einschränkungen, ohne vorher die Daten zu bereinigen (session.unpublish() → warten, bis streamDestroyed → dann neu initialisieren).
  • Do nicht Erneut versuchen OT_PERMISSION_DENIED (Benutzer hat den Zugriff auf Kamera/Mikrofon verweigert) – Hier ist ein Eingriff des Benutzers erforderlich, kein erneuter Versuch.
  • Do nicht Erneut versuchen OT_NOT_CONNECTED — Vergewissern Sie sich vor der Veröffentlichung, dass die Sitzung verbunden ist.
  • Do nicht Unbegrenzt oft wiederholen – auf maximal 3 Versuche begrenzen und den Fehler ordnungsgemäß behandeln.

Umgang mit dem mediaStopped Veranstaltung

Der Medien-Track kann während der Veröffentlichung angehalten werden. Warten Sie auf dieses Ereignis und behandeln Sie es als Auslöser für einen erneuten Versuch:

publisher.on('mediaStopped', async () => {
  console.warn('Media stopped during publish — retrying...');
  // Unpublish if already publishing, then retry
  try { session.unpublish(publisher); } catch (e) { /* ignore */ }
  await delay(2000);
  publishWithRetry(session, publisher);
});

Zusammenfassung der empfohlenen Parameter

Parameter Empfohlener Wert Anmerkungen
Maximale Anzahl von Wiederholungsversuchen 3 Schafft einen Ausgleich zwischen Ausfallsicherheit und Wartezeit für den Nutzer
Wartezeit bis zum erneuten Versuch 2 s × Versuch (2 s, 4 s, 6 s) Gibt der Plattform Zeit, sich zu erholen
Bei allen Wiederholungsversuchen scheitern Benutzer abmelden Verhindert den Zustand eines „Geisterteilnehmers“
Fehler, die nicht erneut versucht werden können OT_NOT_CONNECTED, OT_PERMISSION_DENIED Probiert das schnell aus

Behebung von Problemen bei der Audioaufnahme: audioAcquisitionProblem und audioAcquisitionProblemResolved

Abgesehen von Wiederholungsversuchen auf Veröffentlichungsebene gibt es eine separate Kategorie von Audio-Problemen, die einen aktiven Publisher beeinträchtigen können: Das Audiogerät des Clients liefert möglicherweise auch nach einer erfolgreichen Veröffentlichung keine Audiodaten. Die Video API JS SDK stellt speziell für dieses Szenario zwei Ereignisse bereit.

Häufige Ursachen

Die audioAcquisitionProblem Das Ereignis wird ausgelöst, wenn das SDK – anhand der Publisher-Statistiken – feststellt, dass die Audiospur keine Bytes mehr an die Peer-Verbindung überträgt, obwohl getUserMedia Der Vorgang war erfolgreich, und der Herausgeber scheint aktiv zu sein. Die häufigsten Ursachen sind:

  • Bluetooth-Audiogerät wurde während der Sitzung verbunden oder getrennt: Wenn ein Benutzer während einer aktiven Sitzung Kopfhörer anschließt oder abzieht oder Bluetooth-Kopfhörer (z. B. AirPods) verbindet, wechselt das Betriebssystem möglicherweise das Standard-Audiogerät. Die Audio-Pipeline des Browsers kann das Mikrofon des neuen Geräts möglicherweise nicht erneut erkennen, was dazu führt, dass keine Audio-Bytes gesendet werden.
  • Wechsel des Audiogeräts zu Beginn der Sitzung: Ein Wechsel des Audioeingangs sehr früh in der Sitzung – innerhalb der ersten 1–2 Sekunden nach der Veröffentlichung – führt besonders häufig zu diesem Problem.
  • Die Audiospur wurde vom Browser oder vom Betriebssystem beendet (trackEndedEvent): Der Browser kann die zugrunde liegende Audiospur unabhängig von jeglicher Benutzeraktion beenden. Das SDK erkennt dies über ein track.ended Ereignis und löst aus audioAcquisitionProblem mit method: trackEndedEvent.
  • Statistikbasierte Erkennung (keine Audio-Bytes werden übertragen): Sobald die Peer-Verbindung den Status „verbunden“ erreicht hat, fragt das SDK etwa alle paar Sekunden die Publisher-Statistiken ab. Wenn der ausgehende Datenstrom der Audiospur bytesSent steigt zwischen aufeinanderfolgenden Umfragen nicht an, audioAcquisitionProblem wird ausgelöst (mit method: getStats). Wenn bytesSent steigt wieder an, audioAcquisitionProblemResolved wird erhoben.

Anmerkung: Dieses Ereignis deutet nicht immer auf einen schwerwiegenden Fehler hin. In manchen Sitzungen stellt sich der Ton von selbst wieder her (und audioAcquisitionProblemResolved ausgelöst wird); in anderen Fällen erholt sich der Audiostream nie wieder, und nachgeschaltete Teilnehmer können schließlich ein Timeout erhalten.

Die Veranstaltungen

Diese Ereignisse werden von der Publisher-Instanz ausgelöst:

  • audioAcquisitionProblem — wird ausgelöst, wenn das SDK feststellt, dass der Publisher die Audioübertragung eingestellt hat (basierend auf den Publisher-Statistiken), oder wenn die zugrunde liegende Audiospur ein ended Ereignis. Das bedeutet nicht zwangsläufig, dass der Stream fehlschlägt, ist jedoch ein Hinweis darauf, dass die Audioaufnahme unterbrochen wurde.
  • audioAcquisitionProblemResolved — wird ausgelöst, wenn die Audioübertragung nach einer vorherigen Unterbrechung wiederhergestellt ist audioAcquisitionProblem. Wenn dieses Ereignis ausgelöst wird, sind keine Korrekturmaßnahmen erforderlich.

Anmerkung: Diese Veranstaltungen finden derzeit statt ist nicht Teil der dokumentierten/definierten öffentlichen API (sie sind in den TypeScript-Definitionen des SDKs nicht deklariert). Behandeln Sie sie als Signale, die nach bestem Bemühen bereitgestellt werden und sich von Version zu Version ändern können, und Verify die Verfügbarkeit anhand Ihrer SDK-Version, bevor Sie sich in der Produktion darauf verlassen. Wenn sie vom Publisher ausgegeben werden, enthalten sie einen method Eigenschaft, die angibt, wie das Problem erkannt wurde ('getStats' oder 'trackEndedEvent').

Anmerkung: Die Überprüfungen der Audioerfassung basieren auf den Statistiken des Anbieters, daher kann es zu einer kurzen Verzögerung zwischen der tatsächlichen Unterbrechung der Audioübertragung und der Auslösung des Ereignisses kommen.

Empfohlenes Wiederherstellungsmuster

Bei Empfang einen kurzen Timer starten audioAcquisitionProblem. Wenn audioAcquisitionProblemResolved Wenn der Timer abläuft, bevor Störungen auftreten, hat sich der Ton von selbst wieder normalisiert und es sind keine Maßnahmen erforderlich. Läuft der Timer ab, ohne dass sich das Problem behoben hat, wechseln Sie als Abhilfemaßnahme die Audioquelle.

publisher.on('audioAcquisitionProblem', () => {
  // Start a 3-second timer
  const timeout = setTimeout(() => {
    // Problem not resolved — attempt recovery by switching audio source
    publisher.setAudioSource(newDeviceId);
  }, 3000);

  publisher.on('audioAcquisitionProblemResolved', () => {
    // Audio recovered — clear the timer, no action needed
    clearTimeout(timeout);
  });
});

Wichtige Überlegungen

  • Kein garantierter Hinweis auf einen Ausfall: audioAcquisitionProblem führt nicht immer zu einem Abonnementfehler. Betrachten Sie dies als frühes Warnsignal, um die Situation zu überwachen und gegebenenfalls Maßnahmen zu ergreifen, nicht als endgültigen Fehler.
  • Audio-Statistiken des Herausgebers überwachen: Nach Erhalt audioAcquisitionProblem, können Sie auch die Audio-Statistiken des Herausgebers einsehen (z. B. über publisher.getStats()), um zu überprüfen, ob die Audioübertragung tatsächlich beendet ist, bevor Sie Maßnahmen ergreifen.
  • Maßnahmen zur Wiederherstellung: Aufruf von publisher.setAudioSource(newDeviceId) ist der primäre Wiederherstellungsmechanismus. Dadurch wird das Audio-Eingabegerät umgeschaltet, ohne dass ein vollständiger Zyklus aus „Veröffentlichung aufheben“ und „erneut veröffentlichen“ erforderlich ist.
  • Zusammenhang mit Zeitüberschreitungen bei Abonnements: Wenn der Ton nicht wiederhergestellt wird und der Sender weiterhin keine Audiopakete sendet, kann es vorkommen, dass Abonnenten schließlich auf OT_TIMEOUT (1501). Proaktiver Umgang mit audioAcquisitionProblem kann dazu beitragen, diesen Ausfall im weiteren Verlauf zu vermeiden.