Publishing und Subscribing - Amazon IVS

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Publishing und Subscribing

Konzepte

Drei Kernkonzepte liegen der Echtzeit-Funktionalität zugrunde: Stage, Strategie und Renderer. Das Designziel besteht in der Minimierung der Menge an clientseitiger Logik, die für die Entwicklung eines funktionierenden Produkts erforderlich ist.

Stufe

Die Klasse IVSStage ist der Hauptinteraktionspunkt zwischen der Hostanwendung und dem SDK. Die Klasse stellt die Bühne selbst dar und dient dazu, der Bühne beizutreten und sie zu verlassen. Für das Erstellen einer Bühne oder das Beitreten ist eine gültige, noch nicht abgelaufene Token-Zeichenfolge aus der Steuerebene erforderlich (dargestellt als token). Einer Bühne beizutreten und sie zu verlassen, ist ganz einfach.

let stage = try IVSStage(token: token, strategy: self) try stage.join() stage.leave()

In der Klasse IVSStage erfolgt auch das Anhängen des IVSStageRenderer und IVSErrorDelegate:

let stage = try IVSStage(token: token, strategy: self) stage.errorDelegate = self stage.addRenderer(self) // multiple renderers can be added

Strategie

Über das Protokoll IVSStageStrategy kann die Hostanwendung dem SDK den gewünschten Status der Bühne mitteilen. Drei Funktionen müssen implementiert werden: shouldSubscribeToParticipant, shouldPublishParticipant und streamsToPublishForParticipant. Alle werden im Folgenden behandelt.

Abonnieren von Teilnehmern

func stage(_ stage: IVSStage, shouldSubscribeToParticipant participant: IVSParticipantInfo) -> IVSStageSubscribeType

Wenn ein Remote-Teilnehmer einer Bühne beitritt, fragt das SDK die Hostanwendung nach dessen gewünschtem Abonnementstatus. Die Optionen lauten .none, .audioOnly und .audioVideo. Wenn ein Wert für diese Funktion zurückgegeben wird, muss sich die Hostanwendung nicht um den Veröffentlichungs-, den aktuellen Abonnement- oder den Verbindungsstatus des Bühne kümmern. Bei Rückgabe von .audioVideo wartet das SDK mit dem Abonnieren, bis der Remote-Teilnehmer etwas veröffentlicht. Außerdem aktualisiert das SDK die Hostanwendung während des gesamten Prozesses über den Renderer.

Hier folgt ein Beispiel für eine Implementierung:

func stage(_ stage: IVSStage, shouldSubscribeToParticipant participant: IVSParticipantInfo) -> IVSStageSubscribeType { return .audioVideo }

Hierbei handelt es sich um die vollständige Implementierung dieser Funktion für eine Hostanwendung, bei der sich alle Teilnehmer stets gegenseitig sehen sollen; z. B. eine Video-Chat-Anwendung.

Weitergehende Implementierungen sind ebenfalls möglich. Nutzen Sie die Eigenschaft attributes für IVSParticipantInfo, um Teilnehmer anhand der vom Server bereitgestellten Attribute selektiv zu abonnieren:

func stage(_ stage: IVSStage, shouldSubscribeToParticipant participant: IVSParticipantInfo) -> IVSStageSubscribeType { switch participant.attributes["role"] { case "moderator": return .none case "guest": return .audioVideo default: return .none } }

Hiermit kann eine Bühne erstellt werden, auf der Moderatoren alle Gäste überwachen können, ohne selbst gesehen oder gehört zu werden. Die Hostanwendung könnte eine zusätzliche Geschäftslogik nutzen, damit Moderatoren sich gegenseitig sehen können, für Gäste aber unsichtbar bleiben.

Veröffentlichen

func stage(_ stage: IVSStage, shouldPublishParticipant participant: IVSParticipantInfo) -> Bool

Sobald die Verbindung zur Bühne hergestellt ist, überprüft das SDK per Anfrage an die Hostanwendung, ob ein bestimmter Teilnehmer etwas veröffentlichen soll. Dies wird nur bei lokalen Teilnehmern aufgerufen, die auf Grundlage des bereitgestellten Tokens zur Veröffentlichung berechtigt sind.

Hier folgt ein Beispiel für eine Implementierung:

func stage(_ stage: IVSStage, shouldPublishParticipant participant: IVSParticipantInfo) -> Bool { return true }

Sie ist für eine normale Video-Chat-Anwendung gedacht, bei der Benutzer immer etwas veröffentlichen möchten. Sie können die Audio- und Videowiedergabe stummschalten und die Stummschaltung aufheben, um umgehend ausgeblendet oder gesehen/gehört zu werden. (Sie können auch „Veröffentlichen/Veröffentlichung aufheben“ verwenden, was aber viel langsamer ist. „Stummschalten/Stummschalten aufheben“ ist für Anwendungsfälle vorzuziehen, in denen eine häufige Änderung der Sichtbarkeit wünschenswert ist.)

Auswählen von Streams zur Veröffentlichung

func stage(_ stage: IVSStage, streamsToPublishForParticipant participant: IVSParticipantInfo) -> [IVSLocalStageStream]

Beim Veröffentlichen wird hiermit bestimmt, welche Audio- und Videostreams veröffentlicht werden sollen. Dieser Punkt wird später unter Veröffentlichen eines Medienstreams ausführlicher behandelt.

Aktualisieren der Strategie

Die Strategie soll dynamisch sein: Die von einer der oben genannten Funktionen zurückgegebenen Werte lassen sich jederzeit ändern. Wenn die Hostanwendung beispielsweise erst veröffentlichen soll, wenn der Endbenutzer auf eine Schaltfläche tippt, können Sie eine Variable aus shouldPublishParticipant zurückgeben (zum Beispiel hasUserTappedPublishButton). Wenn sich diese Variable aufgrund einer Interaktion des Endbenutzers ändert, signalisieren Sie dem SDK per Aufruf von stage.refreshStrategy(), dass es die Strategie nach den neuesten Werten abfragen und nur Dinge anwenden soll, die sich geändert haben. Wenn das SDK feststellt, dass sich der Wert shouldPublishParticipant geändert hat, startet es den Veröffentlichungsprozess. Wenn alle Funktionen bei einer SDK-Abfrage den gleichen Wert zurückgeben wie zuvor, werden mit dem Aufruf von refreshStrategy keine Änderungen an der Bühne durchgeführt.

Ändert sich der Rückgabewert von shouldSubscribeToParticipant von .audioVideo in .audioOnly, wird der Videostream für alle Teilnehmer mit geänderten Rückgabewerten entfernt, sofern zuvor ein Videostream vorhanden war.

Im Allgemeinen nutzt die Bühne die Strategie, um den Unterschied zwischen der vorherigen und der aktuellen Strategie am effizientesten anzuwenden. Dabei muss sich die Hostanwendung nicht um die ganzen Status kümmern, die für eine ordnungsgemäße Verwaltung erforderlich sind. Stellen Sie sich den Aufruf von stage.refreshStrategy() daher als einen ressourcenschonenden Vorgang vor, da nur bei einer Änderung der Strategie etwas unternommen wird.

Renderer

Das Protokoll IVSStageRenderer teilt der Hostanwendung den Status der Bühne mit. Aktualisierungen in der Benutzeroberfläche der Hostanwendung können in der Regel vollständig über die vom Renderer bereitgestellten Ereignisse gesteuert werden. Der Renderer stellt die folgenden Funktionen bereit:

func stage(_ stage: IVSStage, participantDidJoin participant: IVSParticipantInfo) func stage(_ stage: IVSStage, participantDidLeave participant: IVSParticipantInfo) func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didChange publishState: IVSParticipantPublishState) func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didChange subscribeState: IVSParticipantSubscribeState) func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didAdd streams: [IVSStageStream]) func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didRemove streams: [IVSStageStream]) func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didChangeMutedStreams streams: [IVSStageStream]) func stage(_ stage: IVSStage, didChange connectionState: IVSStageConnectionState, withError error: Error?)

Es wird nicht erwartet, dass sich die vom Renderer bereitgestellten Informationen auf die Rückgabewerte der Strategie auswirken. Es wird beispielsweise nicht erwartet, dass sich der Rückgabewert von shouldSubscribeToParticipant beim Aufruf von participant:didChangePublishState ändert. Wenn die Hostanwendung einen bestimmten Teilnehmer abonnieren möchte, muss sie unabhängig von dessen Veröffentlichungsstatus den gewünschten Abonnementtyp zurückgeben. Das SDK muss dafür sorgen, dass entsprechend dem Status der Bühne und dem gewünschten Status der Strategie zum richtigen Zeitpunkt gehandelt wird.

Hinweis: Nur veröffentlichende Teilnehmer lösen participantDidJoin aus. Wenn Teilnehmer die Veröffentlichung beenden oder die Bühnensitzung verlassen, wird participantDidLeave ausgelöst.

Veröffentlichen eines Medienstreams

Lokale Geräte wie eingebaute Mikrofone und Kameras werden über IVSDeviceDiscovery erkannt. Hier folgt ein Beispiel für die Auswahl der nach vorne gerichteten Kamera und des Standardmikrofons und deren anschließende Rückgabe als IVSLocalStageStreams zur Veröffentlichung durch das SDK:

let devices = IVSDeviceDiscovery.listLocalDevices() // Find the camera virtual device, choose the front source, and create a stream let camera = devices.compactMap({ $0 as? IVSCamera }).first! let frontSource = camera.listAvailableInputSources().first(where: { $0.position == .front })! camera.setPreferredInputSource(frontSource) let cameraStream = IVSLocalStageStream(device: camera) // Find the microphone virtual device, enable echo cancellation, and create a stream let microphone = devices.compactMap({ $0 as? IVSMicrophone }).first! microphone.isEchoCancellationEnabled = true let microphoneStream = IVSLocalStageStream(device: microphone) // This is a function on IVSStageStrategy func stage(_ stage: IVSStage, streamsToPublishForParticipant participant: IVSParticipantInfo) -> [IVSLocalStageStream] { return [cameraStream, microphoneStream] }

Anzeigen und Entfernen von Teilnehmern

Nach Abschluss von Abonnements erhalten Sie über die Funktion didAddStreams des Renderers eine Reihe von IVSStageStream-Objekten. Um Statistiken des Audiolevels zu diesem Teilnehmer in der Vorschau anzuzeigen oder abzurufen, können Sie über den Stream auf das zugrunde liegende IVSDevice-Objekt zugreifen:

if let imageDevice = stream.device as? IVSImageDevice { let preview = imageDevice.previewView() /* attach this UIView subclass to your view */ } else if let audioDevice = stream.device as? IVSAudioDevice { audioDevice.setStatsCallback( { stats in /* process stats.peak and stats.rms */ }) }

Wenn ein Teilnehmer die Veröffentlichung beendet oder dessen Abonnement beendet wird, wird die Funktion didRemoveStreams mit den Streams aufgerufen, die entfernt wurden. Hostanwendungen sollten dies als Signal nutzen, um den Videostream des Teilnehmers aus der Ansichtshierarchie zu entfernen.

didRemoveStreams wird für alle Szenarien aufgerufen, in denen ein Stream entfernt werden könnte, darunter:

  • Der Remote-Teilnehmer beendet die Veröffentlichung.

  • Ein lokales Gerät beendet das Abonnement oder ändert das Abonnement von .audioVideo in .audioOnly.

  • Der Remote-Teilnehmer verlässt die Bühne.

  • Der lokale Teilnehmer verlässt die Bühne.

Da didRemoveStreams bei allen Szenarien aufgerufen wird, ist keine benutzerdefinierte Geschäftslogik erforderlich, um Teilnehmer beim remoten oder lokalen Verlassen aus der Benutzeroberfläche zu entfernen.

Stummschalten von Medienstreams und Aufheben der Stummschaltung

IVSLocalStageStream-Objekte verfügen über eine setMuted-Funktion, die das Stummschalten des Streams steuert. Diese Funktion kann für den Stream aufgerufen werden, bevor oder nachdem er von der Strategiefunktion streamsToPublishForParticipant zurückgegeben wird.

Wichtig: Wenn nach einem Aufruf von refreshStrategy eine neue IVSLocalStageStream-Objekt-Instance von streamsToPublishForParticipant zurückgegeben wird, wird der Stummschaltungsstatus des neuen Streamobjekts auf die Bühne angewendet. Seien Sie vorsichtig beim Erstellen neuer IVSLocalStageStream-Instances, um sicherzustellen, dass der erwartete Stummschaltungsstatus beibehalten wird.

Überwachen des Medien-Stummschaltungsstatus von Remote-Teilnehmern

Wenn ein Teilnehmer den Stummschaltungsstatus seines Video- oder Audiostreams ändert, wird die Funktion didChangeMutedStreams des Renderers mit einer Gruppe der Streams aufgerufen, die sich geändert haben. Verwenden Sie die Eigenschaft isMuted für IVSStageStream, um die Benutzeroberfläche entsprechend zu aktualisieren:

func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didChangeMutedStreams streams: [IVSStageStream]) { streams.forEach { stream in /* stream.isMuted */ } }

Erstellen einer Bühnenkonfiguration

Die Werte der Videokonfiguration einer Bühne passen Sie mit IVSLocalStageStreamVideoConfiguration an:

let config = IVSLocalStageStreamVideoConfiguration() try config.setMaxBitrate(900_000) try config.setMinBitrate(100_000) try config.setTargetFramerate(30) try config.setSize(CGSize(width: 360, height: 640)) config.degradationPreference = .balanced

Abrufen von WebRTC-Statistiken

Um die neuesten WebRTC-Statistiken für einen veröffentlichten oder abonnierten Stream abzurufen, verwenden Sie requestRTCStats für IVSStageStream. Nach Abschluss einer Erfassung erhalten Sie Statistiken über den IVSStageStreamDelegate, der für IVSStageStream eingestellt werden kann. Um WebRTC-Statistiken kontinuierlich zu erfassen, rufen Sie diese Funktion für einen Timer auf.

func stream(_ stream: IVSStageStream, didGenerateRTCStats stats: [String : [String : String]]) { for stat in stats { for member in stat.value { print("stat \(stat.key) has member \(member.key) with value \(member.value)") } } }

Abrufen von Teilnehmerattributen

Wenn Sie Attribute in der Endpunktanfrage CreateParticipantToken angeben, können Sie die Attribute in den Eigenschaften von IVSParticipantInfo einsehen:

func stage(_ stage: IVSStage, participantDidJoin participant: IVSParticipantInfo) { print("ID: \(participant.participantId)") for attribute in participant.attributes { print("attribute: \(attribute.key)=\(attribute.value)") } }

Fortsetzen der Sitzung im Hintergrund

Wenn die App in den Hintergrund wechselt, können Sie weiterhin auf der Bühne präsent sein, während Sie Remote-Ton hören. Es ist jedoch nicht möglich, das eigene Bild und den eigenen Ton weiterhin zu senden. Sie müssen die Implementierung Ihrer IVSStrategy aktualisieren, um die Veröffentlichung zu beenden und .audioOnly zu abonnieren (oder gegebenenfalls .none):

func stage(_ stage: IVSStage, shouldPublishParticipant participant: IVSParticipantInfo) -> Bool { return false } func stage(_ stage: IVSStage, shouldSubscribeToParticipant participant: IVSParticipantInfo) -> IVSStageSubscribeType { return .audioOnly }

Anschließend rufen Sie stage.refreshStrategy() auf.

Aktivieren/Deaktivieren der mehrschichtigen Kodierung mit Simulcast

Bei der Veröffentlichung eines Medienstreams überträgt das SDK Videostreams in hoher und niedriger Qualität, sodass externe Teilnehmer den Stream abonnieren können, auch wenn sie nur über eine begrenzte Downlink-Bandbreite verfügen. Die mehrschichtige Kodierung mit Simulcast ist standardmäßig aktiviert. Sie können es deaktivieren mit IVSSimulcastConfiguration:

// Disable Simulcast let config = IVSLocalStageStreamVideoConfiguration() config.simulcast.enabled = false let cameraStream = IVSLocalStageStream(device: camera, configuration: config) // Other Stage implementation code

Übertragung der Stage auf einen IVS-Kanal

Zum Übertragen einer Bühne erstellen Sie eine separate IVSBroadcastSession und folgen Sie dann den oben beschriebenen üblichen Anweisungen für die Übertragung mit dem SDK. Die Eigenschaft device für IVSStageStream ist entweder ein IVSImageDevice oder ein IVSAudioDevice, wie im obigen Snippet veranschaulicht. Diese können mit dem IVSBroadcastSession.mixer verbunden werden, um die gesamte Bühne in einem individuell anpassbaren Layout zu übertragen.

Optional können Sie eine Stage zusammenstellen und sie auf einen IVS-Kanal mit niedriger Latenz übertragen, um ein größeres Publikum zu erreichen. Sehen Sie Aktivierung mehrerer Hosts in einem Amazon-IVS-Stream im Benutzerhandbuch für IVS-Streaming mit niedriger Latenz.