

# IVS-Broadcast-SDK \$1 Streaming mit niedriger Latenz
<a name="broadcast"></a>

Das Amazon Interactive Video Services (IVS)-Broadcast-SDK ist für Entwickler bestimmt, die Anwendungen mit Amazon IVS erstellen. Dieses SDK wurde entwickelt, um die Amazon-IVS-Architektur zu nutzen und bietet neben Amazon IVS kontinuierliche Verbesserungen und neue Funktionen. Als natives Broadcast-SDK wurde es entwickelt, um die Leistungsauswirkungen auf Ihre Anwendung und auf die Geräte, mit denen Ihre Benutzer auf Ihre Anwendung zugreifen, zu minimieren.

Ihre Anwendung kann die wichtigsten Funktionen des Amazon-IVS-Broadcast-SDK nutzen:
+ **Hochqualitatives Streaming** – Das Broadcast-SDK unterstützt qualitativ hochwertiges Streaming. Nehmen Sie Videos von Ihrer Kamera auf und kodieren Sie es in einer Qualität von bis zu 1080p für ein hochwertiges Seherlebnis.
+ **Automatische Bitratenanpassungen** – Smartphone-Nutzer sind mobil, so dass sich ihre Netzwerkbedingungen im Laufe einer Sendung ändern können. Das Amazon-IVS-Broadcast-SDK passt die Videobitrate automatisch an sich ändernde Netzwerkbedingungen an.
+ **Hoch- und Quer-Support** – Unabhängig davon, wie Ihre Benutzer ihre Geräte halten, wird das Image mit der rechten Seite nach oben und richtig skaliert angezeigt. Das Broadcast-SDK unterstützt sowohl die Leinwandgröße im Hoch- als auch im Querformat. Es verwaltet automatisch das Seitenverhältnis, wenn die Benutzer ihr Gerät von der konfigurierten Ausrichtung weg drehen.
+ **Sicheres Streaming** – Die Übertragungen Ihrer Benutzer werden mit TLS verschlüsselt, sodass sie ihre Streams sicher halten können.
+ **Externe Audiogeräte** – Das Amazon-IVS-Broadcast-SDK unterstützt externe Audiobuchse, USB und Bluetooth-SCO-Mikrofone.

## Plattform-Anforderungen
<a name="broadcast-platform-requirements"></a>

### Native Plattformen
<a name="broadcast-native-platforms"></a>


| Plattform | Unterstützte Versionen | 
| --- | --- | 
| Android |  6.0 und höher  | 
| iOS |  14 und höher  Wenn Broadcasting für Ihre Anwendung unerlässlich ist, geben Sie Metal als Voraussetzung für das Herunterladen Ihrer App aus dem Apple App Store mithilfe von [UIRequiredDeviceCapabilities](https://developer.apple.com/documentation/bundleresources/information_property_list/uirequireddevicecapabilities) an.   | 

IVS unterstützt mindestens 4 Hauptversionen von iOS und 6 Hauptversionen von Android. Unsere aktuelle Versionsunterstützung kann über diese Mindestanforderungen hinausgehen. Kunden werden über SDK-Versionshinweise mindestens 3 Monate im Voraus benachrichtigt, wenn eine Hauptversion nicht mehr unterstützt wird.

### Desktop-Browser
<a name="browser-desktop"></a>


| Browser | Unterstützte Plattformen | Unterstützte Versionen | 
| --- | --- | --- | 
| Chrome | Windows, macOS | Zwei Hauptversionen (aktuelle und neueste Vorversion) | 
| Firefox | Windows, macOS | Zwei Hauptversionen (aktuelle und neueste Vorversion) | 
| Edge | Windows 8.1 und höher | Zwei Hauptversionen (aktuelle und neueste Vorversion) Schließt Edge Legacy aus | 
| Safari | macOS | Zwei Hauptversionen (aktuelle und neueste Vorversion) | 

### Mobile Browser
<a name="browser-mobile"></a>


| Browser | Unterstützte Versionen | 
| --- | --- | 
| Chrome für iOS, Safari für iOS |  Zwei Hauptversionen (aktuelle und neueste Vorversion)  | 
| Chrome für iPadOS, Safari für iPadOS |  Zwei Hauptversionen (aktuelle und neueste Vorversion)  | 
| Chrome für Android | Zwei Hauptversionen (aktuelle und neueste Vorversion)  | 

## Webansichten
<a name="broadcast-webviews"></a>

Das Web-Broadcast-SDK bietet keine Unterstützung für Webviews oder webähnliche Umgebungen (TV, Konsolen usw.). Informationen zu mobilen Implementierungen finden Sie im Handbuch für das Broadcast-SDK für Streaming mit niedriger Latenz in [Android](broadcast-android.md) und [iOS](broadcast-ios.md).

## Erforderlicher Gerätezugriff
<a name="broadcast-device-access"></a>

Das Broadcast-SDK erfordert Zugriff auf die Kameras und Mikrofone des Geräts, sowohl auf die im Gerät integrierten als auch auf die über Bluetooth, USB oder eine Audiobuchse angeschlossenen.

## Support
<a name="broadcast-support"></a>

Wenn bei Ihrem Stream ein Broadcast-Fehler oder ein anderes Problem auftritt, ermitteln Sie die eindeutige Kennung der Wiedergabesitzung über die Broadcast-API. 


| Für dieses Amazon-IVS-Broadcast-SDK: | Verwenden Sie dies: | 
| --- | --- | 
| Android | `getSessionId` Funktion an `BroadcastSession`  | 
| iOS | `sessionId` Eigenschaft von `IVSBroadcastSession`  | 
| Web | `getSessionId` Funktion | 

Teilen Sie diese Broadcastsitzungskennung mit AWS Support. So können sie Informationen erhalten, die Ihnen helfen, Ihr Problem zu beheben.

**Hinweis:** Das Broadcast-SDK wird ständig verbessert. Siehe [Versionshinweise zu Amazon IVS](release-notes.md) für verfügbare Versionen und behobene Probleme. Aktualisieren Sie gegebenenfalls Ihre Version des Broadcast-SDK, bevor Sie sich an den Support wenden und prüfen Sie, ob das Problem dadurch behoben wird.

### Versionsverwaltung
<a name="broadcast-support-versioning"></a>

Die Amazon-IVS-Broadcast-SDKs verwenden [Semantisches Versioning](https://semver.org/).

Nehmen Sie für diese Diskussion an:
+ Die neueste Version ist 4.1.3.
+ Die neueste Version der vorherigen Hauptversion ist 3.2.4.
+ Die neueste Version 1.x ist 1.5.6.

Rückwärtskompatible neue Funktionen werden als Nebenversionen der neuesten Version hinzugefügt. In diesem Fall wird der nächste Satz neuer Funktionen als Version 4.2.0 hinzugefügt.

Rückwärtskompatible, kleinere Fehlerbehebungen werden als Patch-Releases der neuesten Version hinzugefügt. Hier wird der nächste Satz von kleineren Fehlerbehebungen als Version 4.1.4 hinzugefügt.

Rückwärtskompatible, große Fehlerbehebungen werden unterschiedlich behandelt; diese werden zu mehreren Versionen hinzugefügt:
+ Patch-Version der neuesten Version. Hier ist das Version 4.1.4.
+ Patch-Version der vorherigen Nebenversion. Hier ist das Version 3.2.5.
+ Patch-Version der neuesten Version 1.x. Hier ist das Version 1.5.7.

Wichtige Fehlerbehebungen werden vom Amazon IVS-Produktteam definiert. Typische Beispiele sind kritische Sicherheitsupdates und ausgewählte andere Korrekturen, die für Kunden erforderlich sind.

**Hinweis:** In den obigen Beispielen werden freigegebene Versionen inkrementiert, ohne dass Zahlen übersprungen werden (z. B. von 4.1.3 auf 4.1.4). In Wirklichkeit können eine oder mehrere Patch-Nummern intern bleiben und nicht veröffentlicht werden, so dass die freigegebene Version von 4.1.3 auf, sagen wir, 4.1.6 steigen könnte.

# IVS-Broadcast-SDK: Web-Leitfaden \$1 Streaming mit niedriger Latenz
<a name="broadcast-web"></a>

Das Web-Broadcast-SDK von Amazon Interactive Video Service (IVS) gibt Entwicklern die Werkzeuge an die Hand, um interaktive Echtzeit-Erlebnisse im Web zu schaffen.

**Aktuelle Version des Web-Broadcast-SDK:** 1.33.0 ([Versionshinweise](https://docs.aws.amazon.com/ivs/latest/LowLatencyUserGuide/release-notes.html#mar12-25-broadcast-web-ll)) 

**Referenzdokumentation:** Informationen zu den wichtigsten Methoden, die im Amazon IVS Web Broadcast SDK verfügbar sind, finden Sie unter [https://aws.github.io/amazon-ivs-web-broadcast/docs/sdk-reference](https://aws.github.io/amazon-ivs-web-broadcast/docs/sdk-reference). Stellen Sie sicher, dass die neueste Version des SDK ausgewählt ist.

**Beispielcode**: Die folgenden Beispiele sind ein guter Ausgangspunkt, um schnell mit dem SDK loszulegen:
+ [Einzelübertragung auf einen IVS-Kanal (HTML und JavaScript)](https://codepen.io/amazon-ivs/pen/poLRoPp)
+ [Einzelübertragung mit Bildschirmübertragung auf einen IVS-Kanal](https://stream.ivs.rocks/) ([React Source Code](https://github.com/aws-samples/amazon-ivs-broadcast-web-demo))

**Plattformanforderungen**: Eine Liste der unterstützten Plattformen finden Sie unter [Amazon IVS Broadcast SDK](https://docs.aws.amazon.com//ivs/latest/LowLatencyUserGuide/broadcast.html).

# Erste Schritte mit dem IVS-Web-Broadcast-SDK \$1 Streaming mit niedriger Latenz
<a name="broadcast-web-getting-started"></a>

Dieses Dokument führt Sie durch die Schritte zum Einstieg in das Web-Broadcast-SDK für Amazon-IVS-Streaming mit niedriger Latenz.

## Installieren der Bibliothek
<a name="broadcast-web-install"></a>

Beachten Sie, dass der IVSBroadcastClient [reflect-metadata](https://www.npmjs.com/package/reflect-metadata) verwendet, wodurch das globale Reflect-Objekt erweitert wird. Das sollte zwar keine Konflikte hervorrufen, kann jedoch in seltenen Fällen unerwünschtes Verhalten verursachen.

### Verwenden eines Skript-Tags
<a name="broadcast-web-how-to-install-script"></a>

Das Web Broadcast SDK wird als JavaScript-Bibliothek verteilt und kann unter [https://web-broadcast.live-video.net/1.33.0/amazon-ivs-web-broadcast.js](https://web-broadcast.live-video.net/1.33.0/amazon-ivs-web-broadcast.js) abgerufen werden.

Wenn sie per `<script>`-Tag geladen wird, stellt die Bibliothek eine globale Variable im Fensterbereich namens `IVSBroadcastClient` bereit.

### Verwenden von npm
<a name="broadcast-web-how-to-install-npm"></a>

So installieren Sie das `npm`-Paket:

```
npm install amazon-ivs-web-broadcast
```

Sie können jetzt auf das Objekt `IVSBroadcastClient` zugreifen und andere Module und Konstanten wie `Errors` und `BASIC_LANDSCAPE` abrufen:

```
import IVSBroadcastClient, {
   Errors,
   BASIC_LANDSCAPE
} from 'amazon-ivs-web-broadcast';
```

## Beispiele
<a name="broadcast-web-samples"></a>

Um schnell loszulegen, sehen Sie sich die folgenden Beispiele an:
+ [Einzelübertragung auf einen IVS-Kanal (HTML und JavaScript)](https://codepen.io/amazon-ivs/pen/poLRoPp)
+ [Einzelübertragung mit Bildschirmübertragung auf einen IVS-Kanal](https://stream.ivs.rocks/) ([React Source Code](https://github.com/aws-samples/amazon-ivs-broadcast-web-demo))

## Erstellen einer Instance des AmazonIVSBroadcastClient
<a name="broadcast-web-instance"></a>

Zur Verwendung der Bibliothek müssen Sie eine Instance des Clients erstellen. Dazu rufen Sie die Methode `create` für `IVSBroadcastClient` mit dem Parameter `streamConfig` auf (unter Angabe von Einschränkungen für die Übertragung wie etwa Auflösung und Framerate). Den Ingest-Endpunkt können Sie beim Erstellen des Clients oder beim Starten eines Streams angeben.

Den Erfassungs-Endpunkt finden Sie in der AWS-Konsole. Alternativ kann er vom Vorgang CreateChannel zurückgegeben werden (z. B. UNIQUE\$1ID.global-contribute.live-video.net).

```
const client = IVSBroadcastClient.create({
   // Enter the desired stream configuration
   streamConfig: IVSBroadcastClient.BASIC_LANDSCAPE,
   // Enter the ingest endpoint from the AWS console or CreateChannel API
   ingestEndpoint: 'UNIQUE_ID.global-contribute.live-video.net',
});
```

Dies sind die gängigen unterstützten Stream-Konfigurationen. Die Voreinstellungen sind `BASIC` (mit bis zu 480p und einer Bitrate von bis zu 1,5 Mbit/s, BASIC Full HD mit bis zu 1080p und einer Bitrate von bis zu 3,5 Mbit/s und `STANDARD` (oder `ADVANCED`) mit bis zu 1080p und einer Bitrate von bis zu 8,5 Mbit/s. Sie können die Bitrate, Framerate und Auflösung bei Bedarf anpassen. Weitere Informationen finden Sie unter [BroadcastClientConfig](https://aws.github.io/amazon-ivs-web-broadcast/docs/sdk-reference/interfaces/BroadcastClientConfig).

```
IVSBroadcastClient.BASIC_LANDSCAPE;
IVSBroadcastClient.BASIC_FULL_HD_LANDSCAPE;
IVSBroadcastClient.STANDARD_LANDSCAPE;
IVSBroadcastClient.BASIC_PORTRAIT;
IVSBroadcastClient.BASIC_FULL_HD_PORTRAIT;
IVSBroadcastClient.STANDARD_PORTRAIT;
```

Bei Verwendung des `npm`-Pakets können Sie diese einzeln importieren.

Hinweis: Stellen Sie sicher, dass die clientseitige Konfiguration dem Kanaltyp des Backends entspricht. Wenn der Kanaltyp beispielsweise `STANDARD` lautet, muss `streamConfig` auf einen der `IVSBroadcastClient.STANDARD_*`-Werte eingestellt werden. Wenn der Kanaltyp `ADVANCED` lautet, müssen Sie die Konfiguration manuell festlegen, wie unten gezeigt (`ADVANCED_HD` wird als Beispiel verwendet):

```
const client = IVSBroadcastClient.create({
   // Enter the custom stream configuration
   streamConfig: {
      maxResolution: {
         width: 1080,
         height: 1920,
     },
     maxFramerate: 30,
     /**
      * maxBitrate is measured in kbps
      */
     maxBitrate: 3500,
   },
   // Other configuration . . .
});
```

## Berechtigungen anfordern
<a name="broadcast-web-request-permissions"></a>

Ihre App muss die Berechtigung für den Zugriff auf die Kamera und das Mikrofon des Benutzers anfordern und muss über HTTPS bereitgestellt werden. (Das gilt nicht nur für Amazon IVS, sondern für alle Websites, die Zugriff auf Kameras und Mikrofone benötigen.)

Die folgende Beispielfunktion zeigt, wie Sie Berechtigungen für Audio- und Videogeräte anfordern und erfassen können:

```
async function handlePermissions() {
   let permissions = {
       audio: false,
       video: false,
   };
   try {
       const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
       for (const track of stream.getTracks()) {
           track.stop();
       }
       permissions = { video: true, audio: true };
   } catch (err) {
       permissions = { video: false, audio: false };
       console.error(err.message);
   }
   // If we still don't have permissions after requesting them display the error message
   if (!permissions.video) {
       console.error('Failed to get video permissions.');
   } else if (!permissions.audio) {
       console.error('Failed to get audio permissions.');
   }
}
```

Weitere Informationen finden Sie in der [Berechtigungs-API](https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API) und unter [MediaDevices.getUserMedia()](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia).

## Einrichten einer Stream-Vorschau
<a name="broadcast-web-request-set-up-stream"></a>

Um eine Vorschau der Übertragung anzuzeigen, stellen Sie dem SDK ein `<canvas>`-Element zur Verfügung.

```
// where #preview is an existing <canvas> DOM element on your page
const previewEl = document.getElementById('preview');
client.attachPreview(previewEl);
```

## Auflisten der verfügbaren Geräte
<a name="broadcast-web-request-list-devices"></a>

Um festzustellen, welche Geräte für die Erfassung verfügbar sind, fragen Sie die Methode [MediaDevices.enumerateDevices()](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices) des Browsers ab:

```
const devices = await navigator.mediaDevices.enumerateDevices();
window.videoDevices = devices.filter((d) => d.kind === 'videoinput');
window.audioDevices = devices.filter((d) => d.kind === 'audioinput');
```

## Abrufen eines MediaStream von einem Gerät
<a name="broadcast-web-retrieve-mediastream"></a>

Nachdem Sie die Liste der verfügbaren Geräte erfasst haben, können Sie einen Stream von einer beliebigen Anzahl von Geräten abrufen. Sie können zum Beispiel mit der Methode `getUserMedia()` einen Stream von einer Kamera abrufen.

Wenn Sie angeben möchten, von welchem Gerät der Stream erfasst werden soll, können Sie die `deviceId` im Bereich `audio` oder `video` der Medieneinschränkungen explizit festlegen. Alternativ können Sie die `deviceId` weglassen und Benutzer ihre Geräte über die Eingabeaufforderung des Browsers auswählen lassen.

Zudem können Sie mithilfe der Einschränkungen `width` und `height` eine ideale Kameraauflösung angeben. (Mehr über diese Einschränkungen erfahren Sie [hier](https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints#properties_of_video_tracks).) Das SDK wendet automatisch die Einschränkungen für die Breite und Höhe an, die Ihrer maximalen Übertragungsauflösung entsprechen. Es empfiehlt sich jedoch, diese auch selbst anzuwenden, damit das Seitenverhältnis der Quelle nicht geändert wird, nachdem Sie sie dem SDK hinzugefügt haben.

```
const streamConfig = IVSBroadcastClient.BASIC_LANDSCAPE;
...
window.cameraStream = await navigator.mediaDevices.getUserMedia({
   video: {
       deviceId: window.videoDevices[0].deviceId,
       width: {
           ideal: streamConfig.maxResolution.width,
       },
       height: {
           ideal: streamConfig.maxResolution.height,
       },
   },
});
window.microphoneStream = await navigator.mediaDevices.getUserMedia({
   audio: { deviceId: window.audioDevices[0].deviceId },
});
```

## Hinzufügen eines Geräts zu einem Stream
<a name="broadcast-web-add-device"></a>

Nach Erfassung des Streams können Sie dem Layout Geräte hinzufügen, indem Sie einen eindeutigen Namen (unten lautet er `camera1`) und eine Bildposition (für Videos) angeben. Durch Angabe einer Webcam können Sie zum Beispiel eine Webcam-Videoquelle zum übertragenen Stream hinzufügen.

Bei Angabe des Videoeingabegeräts müssen Sie den Index angeben, der die „Ebene“ darstellt, auf der die Übertragung erfolgen soll. Dies ist vergleichbar mit der Bildbearbeitung oder CSS, wo ein Z-Index die Reihenfolge der zu rendernden Ebenen angibt. Optional können Sie eine Position angeben, die die X/Y-Koordinaten (sowie die Größe) der Stream-Quelle definiert.

Einzelheiten zu Parametern finden Sie unter [VideoComposition](https://aws.github.io/amazon-ivs-web-broadcast/docs/sdk-reference/interfaces/VideoComposition).

```
client.addVideoInputDevice(window.cameraStream, 'camera1', { index: 0 }); // only 'index' is required for the position parameter
client.addAudioInputDevice(window.microphoneStream, 'mic1');
```

## Starten eines Broadcastings
<a name="broadcast-web-start-broadcast"></a>

Um eine Übertragung zu starten, geben Sie den Stream-Schlüssel für Ihren Amazon-IVS-Kanal ein:

```
client
   .startBroadcast(streamKey)
   .then((result) => {
       console.log('I am successfully broadcasting!');
   })
   .catch((error) => {
       console.error('Something drastically failed while broadcasting!', error);
   });
```

## Anhalten eines Broadcastings
<a name="broadcast-web-stop-broadcast"></a>

```
client.stopBroadcast();
```

## Wechseln von Videopositionen
<a name="broadcast-web-swap-video-positions"></a>

Der Client unterstützt das Wechseln der Bildpositionen von Videogeräten:

```
client.exchangeVideoDevicePositions('camera1', 'camera2');
```

## Mute Audio
<a name="broadcast-web-muting-audio"></a>

Zum Stummschalten entfernen Sie entweder das Audiogerät mit `removeAudioInputDevice` oder stellen Sie die Eigenschaft `enabled` für die Audiospur ein:

```
let audioStream = client.getAudioInputDevice(AUDIO_DEVICE_NAME);
audioStream.getAudioTracks()[0].enabled = false;
```

Dabei ist `AUDIO_DEVICE_NAME` der Name, der dem ursprünglichen Audiogerät beim Aufruf von `addAudioInputDevice()` gegeben wurde.

So heben Sie die Stummschaltung auf:

```
let audioStream = client.getAudioInputDevice(AUDIO_DEVICE_NAME);
audioStream.getAudioTracks()[0].enabled = true;
```

## Ausblenden eines Videos
<a name="broadcast-web-hiding-video"></a>

Um ein Video auszublenden, entfernen Sie entweder das Videogerät mit `removeVideoInputDevice` oder legen Sie die Eigenschaft `enabled` für die Videospur fest:

```
let videoStream = client.getVideoInputDevice(VIDEO_DEVICE_NAME).source;
videoStream.getVideoTracks()[0].enabled = false;
```

Dabei ist `VIDEO_DEVICE_NAME` der Name, der dem Videogerät beim ursprünglichen Aufruf von `addVideoInputDevice()` gegeben wurde.

So blenden Sie ein Video ein:

```
let videoStream = client.getVideoInputDevice(VIDEO_DEVICE_NAME).source;
videoStream.getVideoTracks()[0].enabled = true;
```

# Bekannte Probleme und Problemumgehungen im IVS-Web-Broadcast-SDK \$1 Streaming mit niedriger Latenz
<a name="broadcast-web-known-issues"></a>

In diesem Dokument werden bekannte Probleme aufgeführt, die bei der Verwendung des Web-Broadcast-SDK für Amazon-IVS-Streaming mit niedriger Latenz auftreten können, und es werden mögliche Problemumgehungen vorgeschlagen.
+ Beim Betrachten von Streams von Broadcastern, die Safari auf Intel-basierten Mac-Geräten verwenden, kann es zu grünen Artefakten oder unregelmäßigen Bildraten kommen.

  **Problemumgehung:** Leiten Sie Broadcaster auf Intel Mac-Geräten zum Broadcasten mit Chrome um.
+ Das Web-Broadcast-SDK erfordert, dass Port 4443 geöffnet ist. VPNs und Firewalls können Port 4443 blockieren und Sie am Streaming hindern.

  **Problemumgehung:** Deaktivieren Sie VPNs und/oder konfigurieren Sie Firewalls, um sicherzustellen, dass Port 4443 nicht blockiert wird. 
+ Das Umschalten vom Quer- zum Hochformat ist fehlerhaft.

  **Problemumgehung:** Keine.
+ Die im HLS-Manifest angegebene Auflösung ist falsch. Sie ist auf die ursprünglich empfangene Auflösung eingestellt, die in der Regel viel niedriger ist als möglich und keine Hochskalierung widerspiegelt, die während der WebRTC-Verbindung erfolgt.

  **Problemumgehung:** Keine.
+ Nachfolgende Client-Instances, die nach dem Laden der ersten Seite erstellt werden, reagieren möglicherweise nicht auf `maxFramerate`-Einstellungen, die sich von denen der ersten Client-Instance unterscheiden.

  **Problemumgehung:** Stellen Sie `StreamConfig` nur einmal über die Funktion `IVSBroadcastClient.create` ein, wenn die erste Client-Instance erstellt wird. 
+ Unter iOS wird die Erfassung mehrerer Videogerätequellen von WebKit nicht unterstützt.

  **Problemumgehung:** Folgen Sie [diesem Problem](https://bugs.webkit.org/show_bug.cgi?id=238492), um den Entwicklungsfortschritt zu verfolgen.
+ Wenn Sie unter iOS `getUserMedia()` bei bereits vorhandener Videoquelle aufrufen, werden keine weiteren Videoquellen über `getUserMedia()` abgerufen.

  **Problemumgehung:** Keine.
+ WebRTC wählt die beste Bitrate und Auflösung für die verfügbaren Ressourcen dynamisch aus. Wenn die Hardware oder das Netzwerk keine entsprechende Unterstützung bietet, werden Streams nicht in hoher Qualität übertragen. Die Qualität von Streams kann sich während der Übertragung mit der zu- oder abnehmenden Verfügbarkeit von Ressourcen ändern.

  **Problemumgehung:** Stellen Sie eine Upload-Geschwindigkeit von mindestens 200 Kbit/s bereit.
+ Wenn die automatische Aufzeichnung in Amazon S3 für einen Kanal aktiviert ist und das Web Broadcast SDK verwendet wird, funktioniert die Aufzeichnung mit demselben S3-Präfix möglicherweise nicht, da das Web Broadcast SDK Bitraten und die Qualität dynamisch ändert.

  **Problemumgehung:** Keine.
+ Bei der Verwendung von Next.js kann je nachdem, wie das SDK importiert wird, der Fehler `Uncaught ReferenceError: self is not defined` auftreten.

  **Problemumgehung:** [Importieren Sie die Bibliothek dynamisch](https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading), wenn Sie Next.js nutzen.
+ Möglicherweise lässt sich das Modul mit einem Skript-Tag vom Typ `module` (z. B. `<script type="module" src="..."\>`) nicht importieren.

  **Problemumgehung:** Die Bibliothek verfügt über keinen ES6-Build. Entfernen Sie das `type="module"` aus dem Skript-Tag.

## Einschränkungen von Safari
<a name="broadcast-web-safari-limitations"></a>
+ Wenn bei einer entsprechenden Aufforderung die Erteilung einer Berechtigung verweigert wird, muss die Berechtigung in den Einstellungen auf der Safari-Website auf Betriebssystemebene zurückgesetzt werden.
+ Safari erkennt nicht alle Geräte nativ so effektiv wie Firefox oder Chrome. OBS Virtual Camera wird beispielsweise nicht erkannt.

## Einschränkungen von Firefox
<a name="broadcast-web-firefox-limitations"></a>
+ Damit Firefox den Bildschirm freigeben kann, müssen Systemberechtigungen aktiviert sein. Nach deren Aktivierung muss Firefox neu gestartet werden, damit es ordnungsgemäß funktioniert. Andernfalls löst der Browser eine [NotFoundError](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia#exceptions)-Ausnahme aus, wenn Berechtigungen als gesperrt betrachtet werden.
+ Die Methode `getCapabilities` fehlt. Das bedeutet, dass Benutzer die Auflösung oder das Seitenverhältnis der Medienspur nicht abrufen können. Weitere Informationen finden Sie in diesem [Bugzilla-Thread](https://bugzilla.mozilla.org/show_bug.cgi?id=1179084).
+ Es fehlen mehrere `AudioContext`-Eigenschaften, z. B. die Latenz und die Kanalanzahl. Dies könnte für erfahrene Benutzer, die die Audiospuren bearbeiten möchten, ein Problem darstellen.
+ Kamera-Feeds von `getUserMedia` sind unter macOS auf ein Seitenverhältnis von 4:3 beschränkt. Weitere Informationen finden Sie im [Bugzilla-Thread 1](https://bugzilla.mozilla.org/show_bug.cgi?id=1193640) und im [Bugzilla-Thread 2](https://bugzilla.mozilla.org/show_bug.cgi?id=1306034).
+ Die Audioerfassung wird mit `getDisplayMedia` nicht unterstützt. Weitere Informationen finden Sie in diesem [Bugzilla-Thread](https://bugzilla.mozilla.org/show_bug.cgi?id=1541425).
+ Die Framerate bei der Bildschirmerfassung ist suboptimal (ungefähr 15 Bilder pro Sekunde?). Weitere Informationen finden Sie in diesem [Bugzilla-Thread](https://bugzilla.mozilla.org/show_bug.cgi?id=1703522).

# IVS-Broadcast-SDK: Android-Handbuch \$1 Streaming mit niedriger Latenz
<a name="broadcast-android"></a>

Das Android-Broadcast-SDK von IVS-Streaming mit niedriger Latenz bietet die für Broadcasting an IVS auf Android erforderlichen Schnittstellen.

Das Paket `com.amazonaws.ivs.broadcast` implementiert die in diesem Dokument beschriebene Schnittstelle. Folgende Operationen werden unterstützt: 
+ Richten Sie eine Broadcast ein (initialisieren). 
+ Broadcasting verwalten.
+ Eingabegeräte anfügen und trennen.
+ Eine Zusammensetzungssitzung verwalten. 
+ Empfangen von Ereignissen. 
+ Erhalten von Fehlermeldungen. 

**Aktuelle Version des Broadcast-SDK für Android:** 1.40.0 ([Versionshinweise](https://docs.aws.amazon.com/ivs/latest/LowLatencyUserGuide/release-notes.html#mar12-26-broadcast-android-ll)) 

Informationen zu den wichtigsten Methoden, die im Amazon-IVS-Android-Broadcast-SDK verfügbar sind, finden Sie in der **Referenzdokumentation** unter [https://aws.github.io/amazon-ivs-broadcast-docs/1.40.0/android/](https://aws.github.io/amazon-ivs-broadcast-docs/1.40.0/android/).

**Beispiel-Code:** Siehe die Android-Beispiel-Sammlung auf GitHub: [https://github.com/aws-samples/amazon-ivs-broadcast-android-sample](https://github.com/aws-samples/amazon-ivs-broadcast-android-sample).

**Plattformanforderungen:** Android 9.0 und höher

# Erste Schritte mit dem IVS-Android-Broadcast-SDK \$1 Streaming mit niedriger Latenz
<a name="broadcast-android-getting-started"></a>

Dieses Dokument führt Sie durch die Schritte zum Einstieg in das Android-Broadcast-SDK für Amazon-IVS-Streaming mit niedriger Latenz.

## Bibliothek installieren
<a name="broadcast-android-install"></a>

Wenn Sie der Android-Entwicklungsumgebung die Amazon-IVS-Android-Broadcast-Bibliothek hinzufügen möchten, fügen Sie die Bibliothek der `build.gradle` – wie hier gezeigt – (für die neueste Version des Amazon-IVS-Broadcast-SDK) zu Ihren Modulen hinzu:

```
repositories {
    mavenCentral()
}
dependencies {
     implementation 'com.amazonaws:ivs-broadcast:1.40.0'
}
```

Um das SDK manuell zu installieren, laden Sie alternativ die neueste Version von diesem Speicherort herunter:
+ [https://search.maven.org/artifact/com.amazonaws/ivs-broadcast](https://search.maven.org/artifact/com.amazonaws/ivs-broadcast)

## Verwenden des SDK mit Debug-Symbolen
<a name="broadcast-android-using-debug-symbols-ll"></a>

Wir veröffentlichen auch eine Version des Android-Broadcast-SDK, die Debug-Symbole enthält. Sie können diese Version verwenden, um die Qualität von Debug-Berichten (Stack-Traces) in Firebase Crashlytics zu verbessern, falls im IVS-Broadcast-SDK Abstürze auftreten, d. h. `libbroadcastcore.so`. Wenn Sie diese Abstürze dem SDK-Team von IVS melden, erleichtern die qualitativ hochwertigeren Stack-Traces die Behebung der Probleme.

Um diese Version des SDK zu verwenden, fügen Sie Folgendes in Ihre Gradle-Build-Dateien ein:

```
implementation "com.amazonaws:ivs-broadcast:$version:unstripped@aar"
```

Verwenden Sie die obige Zeile anstelle von:

```
implementation "com.amazonaws:ivs-broadcast:$version@aar"
```

### Hochladen von Symbolen zu Firebase Crashlytics
<a name="android-debug-symbols-ll-firebase-crashlytics"></a>

Stellen Sie sicher, dass Ihre Gradle-Build-Dateien für Firebase Crashlytics eingerichtet sind. Folgen Sie den Anweisungen von Google hier:

[https://firebase.google.com/docs/crashlytics/ndk-reports](https://firebase.google.com/docs/crashlytics/ndk-reports)

Achten Sie darauf, `com.google.firebase:firebase-crashlytics-ndk` als Abhängigkeit anzugeben.

Wenn Sie Ihre App für die Veröffentlichung erstellen, muss das Firebase-Crashlytics-Plugin Symbole automatisch hochladen. Führen Sie einen der folgenden Befehle aus, um Symbole manuell hochzuladen:

```
gradle uploadCrashlyticsSymbolFileRelease
```

```
./gradlew uploadCrashlyticsSymbolFileRelease
```

(Es schadet nicht, wenn Symbole zweimal hochgeladen werden, sowohl automatisch als auch manuell.)

### Verhindern, dass Ihre APK-Version größer wird
<a name="android-debug-symbols-ll-sizing-apk"></a>

Vor dem Verpacken der `.apk`-Release-Datei versucht das Android-Gradle-Plugin automatisch, Debug-Informationen aus gemeinsam genutzten Bibliotheken (einschließlich der `libbroadcastcore.so`-Bibliothek des IVS-Broadcast-SDK) zu entfernen. Manchmal geschieht dies jedoch nicht. Infolgedessen könnte Ihre `.apk`-Datei größer werden und Sie könnten vom Android-Gradle-Plugin eine Warnmeldung erhalten, dass es Debug-Symbole nicht entfernen kann und die `.so`-Dateien unverändert verpackt. Wenn dies passiert, gehen Sie wie folgt vor:
+ Installieren Sie ein Android-NDK. Jede aktuelle Version funktioniert.
+ Fügen Sie `ndkVersion <your_installed_ndk_version_number>` zur `build.gradle`-Datei Ihrer Anwendung hinzu. Tun Sie dies auch dann, wenn Ihre Anwendung selbst keinen nativen Code enthält.

Weitere Informationen finden Sie in diesem [Problembericht](https://issuetracker.google.com/issues/353554169).

## Erstellen Sie den Ereignis-Listener
<a name="broadcast-android-create-event-listener"></a>

Durch das Einrichten eines Ereignis-Listener können Sie Statusaktualisierungen, Geräteänderungsbenachrichtigungen, Fehler und Sitzungsaudio-Informationen erhalten.

```
BroadcastSession.Listener broadcastListener = 
          new BroadcastSession.Listener() {
    @Override
    public void onStateChanged(@NonNull BroadcastSession.State state) {
        Log.d(TAG, "State=" + state);
    }

    @Override
    public void onError(@NonNull BroadcastException exception) {
        Log.e(TAG, "Exception: " + exception);
    }
};
```

## Berechtigungen anfordern
<a name="broadcast-android-permissions"></a>

Ihre App muss die Berechtigung für den Zugriff auf die Kamera und das Mikrofon des Benutzers anfordern. (Dies ist nicht spezifisch für Amazon IVS; es ist für alle Anwendungen erforderlich, die Zugriff auf Kameras und Mikrofone benötigen.)

Hier prüfen wir, ob der Benutzer bereits Berechtigungen erteilt hat und fragen, wenn nicht, nach ihnen:

```
final String[] requiredPermissions =
         { Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO };

for (String permission : requiredPermissions) {
    if (ContextCompat.checkSelfPermission(this, permission) 
                != PackageManager.PERMISSION_GRANTED) {
        // If any permissions are missing we want to just request them all.
        ActivityCompat.requestPermissions(this, requiredPermissions, 0x100);
        break;
    }
}
```

Hier erhalten wir die Antwort des Benutzers:

```
@Override
public void onRequestPermissionsResult(int requestCode, 
                                      @NonNull String[] permissions,
                                      @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode,
               permissions, grantResults);
    if (requestCode == 0x100) {
        for (int result : grantResults) {
            if (result == PackageManager.PERMISSION_DENIED) {
                return;
            }
        }
        setupBroadcastSession();
    }
}
```

## Broadcast-Sitzung erstellen
<a name="broadcast-android-create-session"></a>

Die Broadcast-Schnittstelle ist `com.amazonaws.ivs.broadcast.BroadcastSession`. Initialisieren Sie sie mit einer Voreinstellung wie unten gezeigt. Wenn während der Initialisierung Fehler auftreten (z. B. ein Fehler bei der Konfiguration eines Codecs), wird Ihr `BroadcastListener` eine Fehlermeldung erhalten und `broadcastSession.isReady` wird `false` sein.

**Wichtig:** Alle Anrufe an das Amazon IVS Broadcast SDK for Android *müssen* auf dem Thread erstellt werden, auf dem das SDK instanziiert wird. *Ein Aufruf von einem anderen Thread führt dazu, dass das SDK einen schwerwiegenden Fehler auslöst und die Übertragung stoppt*.

```
// Create a broadcast-session instance and sign up to receive broadcast
// events and errors.
Context ctx = getApplicationContext();
broadcastSession = new BroadcastSession(ctx,
                       broadcastListener,
                       Presets.Configuration.STANDARD_PORTRAIT,
                       Presets.Devices.FRONT_CAMERA(ctx));
```

Lesen Sie auch [Erstellen der Broadcast-Sitzung (Advanced-Version)](broadcast-android-use-cases.md#broadcast-android-create-session-advanced) .

## Festlegen der ImagePreviewView für die Vorschau
<a name="broadcast-android-set-imagepreviewview"></a>

Wenn Sie eine Vorschau für ein aktives Kameragerät anzeigen möchten, fügen Sie die Vorschau `ImagePreviewView` für das Gerät zu Ihrer View-Hierarchie hinzu.

```
// awaitDeviceChanges will fire on the main thread after all pending devices 
// attachments have been completed
broadcastSession.awaitDeviceChanges(() -> {
    for(Device device: session.listAttachedDevices()) {
        // Find the camera we attached earlier
        if(device.getDescriptor().type == Device.Descriptor.DeviceType.CAMERA) {
            LinearLayout previewHolder = findViewById(R.id.previewHolder);
            ImagePreviewView preview = ((ImageDevice)device).getPreviewView();
            preview.setLayoutParams(new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.MATCH_PARENT));
            previewHolder.addView(preview);
        }
    }
});
```

## Starten eines Broadcastings
<a name="broadcast-android-start"></a>

Dem Hostnamen, den Sie im Antwortfeld `ingestEndpoint` des Vorgangs `GetChannel` erhalten, muss `rtmps://` vorangestellt und `/app` angehängt werden. Die vollständige URL sollte sich in folgendem Format sein: `rtmps://{{ ingestEndpoint }}/app`

```
broadcastSession.start(IVS_RTMPS_URL, IVS_STREAMKEY);
```

Das Android-Broadcast-SDK unterstützt nur RTMPS-Ingest (kein unsicheres RTMP-Ingest).

## Anhalten eines Broadcastings
<a name="broadcast-android-stop"></a>

```
broadcastSession.stop();
```

## Broadcast-Sitzung freigeben
<a name="broadcast-android-release-session"></a>

Die `broadcastSession.release()`-Methode *muss aufgerufen werden*, wenn der Player nicht mehr verwendet wird, um die Ressourcen freizugeben, die von der Bibliothek verwendet werden.

```
@Override
protected void onDestroy() {
    super.onDestroy();
    previewHolder.removeAllViews();
    broadcastSession.release();
}
```

# Fortgeschrittene Anwendungsfälle für das IVS-Android-Broadcast-SDK \$1 Streaming mit niedriger Latenz
<a name="broadcast-android-use-cases"></a>

Hier stellen wir einige fortschrittliche Anwendungsfälle vor. Beginnen Sie mit dem obigen Basis-Setup und fahren Sie hier fort. 

## Broadcast-Konfiguration erstellen
<a name="broadcast-android-create-configuration"></a>

Hier erstellen wir eine benutzerdefinierte Konfiguration mit zwei Mischersteckplätzen, die es uns erlauben, zwei Videoquellen an den Mischer zu binden. Eine (`custom`) ist Vollbild und hinter der anderen angelegt (`camera`), die kleiner und in der unteren rechten Ecke ist. Beachten Sie, dass wir für den `custom`-Slot keine Position, Größe oder Seitenverhältnis festlegen. Da wir diese Parameter nicht einstellen, verwendet der Slot die Videoeinstellungen für Größe und Position.

```
BroadcastConfiguration config = BroadcastConfiguration.with($ -> {
    $.audio.setBitrate(128_000);
    $.video.setMaxBitrate(3_500_000);
    $.video.setMinBitrate(500_000);
    $.video.setInitialBitrate(1_500_000);
    $.video.setSize(1280, 720);
    $.mixer.slots = new BroadcastConfiguration.Mixer.Slot[] {
            BroadcastConfiguration.Mixer.Slot.with(slot -> {
                // Do not automatically bind to a source
                slot.setPreferredAudioInput(
                           Device.Descriptor.DeviceType.UNKNOWN);
                // Bind to user image if unbound
                slot.setPreferredVideoInput(
                           Device.Descriptor.DeviceType.USER_IMAGE);
                slot.setName("custom");
                return slot;
            }),
            BroadcastConfiguration.Mixer.Slot.with(slot -> {
                slot.setzIndex(1);
                slot.setAspect(BroadcastConfiguration.AspectMode.FILL);
                slot.setSize(300, 300);
                slot.setPosition($.video.getSize().x - 350,
                        $.video.getSize().y - 350);
                slot.setName("camera");
                return slot;
            })
    };
    return $;
});
```

## Erstellen der Broadcast-Sitzung (Advanced-Version)
<a name="broadcast-android-create-session-advanced"></a>

Erstellen Sie eine `BroadcastSession` wie im [grundlegenden Beispiel](broadcast-android-getting-started.md#broadcast-android-create-session), geben Sie jedoch hier Ihre benutzerdefinierte Konfiguration an. Geben Sie auch `null` für das Gerätearray an, da wir diese manuell hinzufügen werden.

```
// Create a broadcast-session instance and sign up to receive broadcast
// events and errors.
Context ctx = getApplicationContext();
broadcastSession = new BroadcastSession(ctx,
                       broadcastListener,
                       config, // The configuration we created above
                       null); // We’ll manually attach devices after
```

## Iterieren und Anschließen eines Kamerageräts
<a name="broadcast-android-attach-camera"></a>

Hier iterieren wir durch Eingabegeräte, die das SDK erkannt hat. Auf Android 7 (Nougat) gibt dies nur Standard-Mikrofongeräte zurück, da das Amazon-IVS-Broadcast-SDK die Auswahl nicht standardmäßiger Geräte auf dieser Android-Version nicht unterstützt.

Sobald wir ein Gerät gefunden haben, das wir verwenden möchten, rufen wir `attachDevice` auf, um es anzuhängen. Eine Lambda-Funktion wird auf dem Hauptthread aufgerufen, wenn das Anhängen des Eingabegeräts abgeschlossen ist. Im Falle eines Fehlers erhalten Sie einen Fehler im Listener.

```
for(Device.Descriptor desc: BroadcastSession.listAvailableDevices(getApplicationContext())) {
    if(desc.type == Device.Descriptor.DeviceType.CAMERA &&
            desc.position == Device.Descriptor.Position.FRONT) {
        session.attachDevice(desc, device -> {
            LinearLayout previewHolder = findViewById(R.id.previewHolder);
            ImagePreviewView preview = ((ImageDevice)device).getPreviewView();
            preview.setLayoutParams(new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.MATCH_PARENT));
            previewHolder.addView(preview);
            // Bind the camera to the mixer slot we created above.
            session.getMixer().bind(device, "camera");
        });
        break;
    }
}
```

## Kameras austauschen
<a name="broadcast-android-swap-cameras"></a>

```
// This assumes you’ve kept a reference called "currentCamera" that points to
// a front facing camera
for(Device device: BroadcastSession.listAvailableDevices()) {
   if(device.type == Device.Descriptor.DeviceType.CAMERA &&
          Device.position != currentCamera.position) {
        // Remove the preview view for the old device.
        // setImagePreviewTextureView is an example function 
        // that handles your view hierarchy.
        setImagePreviewView(null);
        session.exchangeDevices(currentCamera, device, camera -> {
             // Set the preview view for the new device.
             setImagePreviewView(camera.getPreviewView());
             currentCamera = camera;
        });
        break;
   }
}
```

## Erstellen einer Eingabe-Oberfläche
<a name="broadcast-android-create-input-surface"></a>

Um Audio- oder Image-Daten einzugeben, die von Ihrer App generiert werden, verwenden Sie `createImageInputSource` oder `createAudioInputSource`. Beide Methoden erstellen und verbinden virtuelle Geräte, die wie jedes andere Gerät an den Mischer gebunden werden können.

Das von `createImageInputSource` zurückgegebene `SurfaceSource` hat eine `getInputSurface`-Methode, die Ihnen eine `Surface` gibt, die Sie mit der Camera2-API, OpenGL oder Vulkan oder allem anderen verwenden können, das auf ein Surface schreiben kann.

Das von `createAudioInputSource` zurückgegebene `AudioDevice` kann lineare PCM-Daten empfangen, die von AudioRecorder oder auf andere Weise generiert wurden.

```
SurfaceSource source = session.createImageInputSource();
Surface surface = source.getInputSurface();
session.getMixer().bind(source, “custom”);
```

## Trennen eines Geräts
<a name="broadcast-android-detach-device"></a>

Wenn Sie ein Gerät trennen und nicht ersetzen möchten, trennen Sie es mit `Device` oder `Device.Descriptor`.

```
session.detachDevice(currentCamera);
```

## Bildschirm- und System-Audioaufnahme
<a name="broadcast-android-screen-audio-capture"></a>

Das Amazon IVS Broadcast SDK for Android enthält einige Helfer, die die Erfassung des Bildschirms des Geräts (Android 6 und höher) und des Systemaudio (Android 10 und höher) vereinfachen. Wenn Sie diese manuell verwalten möchten, können Sie eine benutzerdefinierte Image-Eingabequelle und eine benutzerdefinierte Audioeingangsquelle erstellen.

Um eine Bildschirm- und System-Audioaufnahme-Sitzung zu erstellen, müssen Sie zunächst eine Berechtigungsanforderungsabsicht erstellen:

```
public void startScreenCapture() {
    MediaProjectionManager manager =
                         (MediaProjectionManager) getApplicationContext()
                         .getSystemService(Context.MEDIA_PROJECTION_SERVICE);
    if(manager != null) {
        Intent intent = manager.createScreenCaptureIntent();
        startActivityIfNeeded(intent, SCREEN_CAPTURE_REQUEST_ID);
    }
}
```

Um dieses Feature zu verwenden, müssen Sie eine Klasse bereitstellen, die `com.amazonaws.ivs.broadcast.SystemCaptureService` erweitert. Sie müssen keine ihrer Methoden außer Kraft setzen, aber die Klasse muss da sein, um mögliche Kollisionen zwischen Services zu vermeiden.

Sie müssen auch ein paar Elemente zu Ihrem Android-Manifest hinzufügen:

```
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application ...>
    <service android:name=".ExampleSystemCaptureService"
         android:foregroundServiceType="mediaProjection" 
         android:isolatedProcess="false" />
</application>
...
```

Ihre Klasse, die `SystemCaptureService` erweitert, muss im `<service>`-Element benannt werden. Unter Android 9 und höher muss `foregroundServiceType` eine `mediaProjection` sein.

Sobald die Berechtigungsabsicht zurückgegeben wurde, können Sie mit der Erstellung des Bildschirms und der Audioaufnahmesitzung des Systems fortfahren. Unter Android 8 und höher müssen Sie eine Benachrichtigung bereitstellen, die im Benachrichtigungsbereich Ihres Benutzers angezeigt wird. Das Amazon IVS Broadcast SDK for Android bietet die bequeme Methode `createServiceNotificationBuilder`. Alternativ können Sie Ihre eigene Benachrichtigung mitteilen. 

```
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode != SCREEN_CAPTURE_REQUEST_ID
       || Activity.RESULT_OK != resultCode) {
        return;
    }
    Notification notification = null;
    if(Build.VERSION.SDK_INT >= 26) {
        Intent intent = new Intent(getApplicationContext(),
                                   NotificationActivity.class);
        notification = session
                         .createServiceNotificationBuilder("example",
                                            "example channel", intent)
                         .build();
    }
    session.createSystemCaptureSources(data,
                  ExampleSystemCaptureService.class,
                  Notification,
                  devices -> {
        // This step is optional if the mixer slots have been given preferred
        // input device types SCREEN and SYSTEM_AUDIO
        for (Device device : devices) {
            session.getMixer().bind(device, "game");
        }
    });
}
```

## Empfohlene Broadcast-Einstellungen erhalten
<a name="broadcast-android-recommended-settings"></a>

Um die Verbindung Ihres Benutzers vor dem Starten einer Übertragung zu bewerten, verwenden Sie die `recommendedVideoSettings`-Methode, um einen kurzen Test durchzuführen. Während der Test läuft, erhalten Sie mehrere Empfehlungen, die von den meisten bis am wenigsten empfohlen bestellt werden. In dieser Version des SDK ist es nicht möglich, die aktuelle `BroadcastSession` neu zu konfigurieren, daher müssen Sie sie `release()` und dann eine neue mit den empfohlenen Einstellungen erstellen. Sie erhalten weiterhin `BroadcastSessionTest.Results` bis `Result.status` `SUCCESS` ist oder `ERROR`. Sie können den Fortschritt mit überprüfen `Result.progress`.

Amazon IVS unterstützt eine maximale Bitrate von 8,5 Mbit/s (für Kanäle, deren `type` `STANDARD` oder `ADVANCED` ist), so dass die `maximumBitrate`, die von dieser Methode zurückgegeben wird, nie 8,5 Mbps überschreitet. Um kleine Schwankungen der Netzwerkleistung zu berücksichtigen, ist die von dieser Methode empfohlene `initialBitrate` etwas niedriger als die im Test gemessene tatsächliche Bitrate. (Die Verwendung von 100 % der verfügbaren Bandbreite ist in der Regel nicht ratsam.)

```
void runBroadcastTest() {
    this.test = session.recommendedVideoSettings(RTMPS_ENDPOINT, RTMPS_STREAMKEY,
        result -> {
            if (result.status == BroadcastSessionTest.Status.SUCCESS) {
                this.recommendation = result.recommendations[0];
            }
        });
}
```

## Verwenden der automatischen Wiederverbindung
<a name="broadcast-android-auto-reconnect"></a>

IVS unterstützt die automatische Wiederverbindung mit einem Broadcast, falls der Broadcast unerwartet beendet wird, ohne die `stop`-API aufzurufen, z. B. bei einem vorübergehenden Verlust der Netzwerkkonnektivität. Rufen Sie `setEnabled(true)` für `BroadcastConfiguration.autoReconnect` auf, um die automatische Wiederverbindung zu aktivieren.

Wenn der Stream aus irgendeinem Grund unerwartet beendet wird, versucht das SDK die Wiederverbindung bis zu fünf Mal. Dabei folgt es einer linearen Backoff-Strategie. Es benachrichtigt Ihre Anwendung mithilfe der Methode `BroadcastSession.Listener.onRetryStateChanged` über den Status der erneuten Versuche.

Die automatische Wiederverbindung nutzt im Hintergrund die IVS-Funktion für die [Stream-Übernahme](streaming-config.md#streaming-config-stream-takeover), indem eine Prioritätsnummer, beginnend mit 1, an das Ende des bereitgestellten Stream-Schlüssels angehängt wird. Für die Dauer der `BroadcastSession`-Instance wird diese Zahl bei jedem erneuten Verbindungsversuch um 1 erhöht. Das bedeutet Folgendes: Wenn die Verbindung des Geräts während eines Broadcasts viermal unterbrochen wird und für jede Unterbrechung 1–4 Wiederholungsversuche erforderlich sind, kann die Priorität des letzten Streamups zwischen 5 und 17 liegen. Aus diesem Grund *empfehlen wir, die IVS-Stream-Übernahme von einem anderen Gerät nicht zu verwenden, solange die automatische Wiederverbindung im SDK für denselben Kanal aktiviert ist*. Es gibt keine Garantie dafür, welche Priorität das SDK zu diesem Zeitpunkt verwendet, und das SDK versucht, die Verbindung mit einer höheren Priorität wiederherzustellen, wenn ein anderes Gerät den Stream übernimmt.

## Verwenden von Bluetooth-Mikrofonen
<a name="broadcast-android-bluetooth-microphones"></a>

Um mit Bluetooth-Mikrofongeräten zu senden, müssen Sie eine Bluetooth-SCO-Verbindung herstellen:

```
Bluetooth.startBluetoothSco(context);
// Now bluetooth microphones can be used
…
// Must also stop bluetooth SCO
Bluetooth.stopBluetoothSco(context);
```

# Bekannte Probleme und Problemumgehungen im IVS-Android-Broadcast-SDK \$1 Streaming mit niedriger Latenz
<a name="broadcast-android-issues"></a>

In diesem Dokument werden bekannte Probleme aufgeführt, die bei der Verwendung des Android-Broadcast-SDK für Amazon-IVS-Streaming mit niedriger Latenz auftreten können, und es werden mögliche Problemumgehungen vorgeschlagen.
+ Die Verwendung eines externen Mikrofons, das über Bluetooth verbunden ist, kann instabil sein. Wenn ein Bluetooth-Gerät während einer Broadcast-Sitzung verbunden oder getrennt wird, funktioniert die Mikrofoneingabe möglicherweise nicht mehr, bis das Gerät explizit getrennt und wieder angeschlossen ist.

  **Problemumgehung:** Wenn Sie ein Bluetooth-Headset verwenden möchten, verbinden Sie es, bevor Sie das Broadcasting starten und lassen Sie es während des gesamten Broadcastings verbunden.
+ Das Broadcast-SDK unterstützt keinen Zugriff auf externe Kameras, die über USB verbunden sind.

  **Problemumgehung:** Verwenden Sie keine externen Kameras, die über USB verbunden sind. 
+ Das Absenden von Audiodaten schneller als in Echtzeit (mit einer benutzerdefinierten Audioquelle) führt zu einer Audiodrift.

  **Problemumgehung:** Senden Sie Audiodaten nicht schneller als in Echtzeit ab. 
+ Geräte mit Android 6 und 7 können die Callbacks `onDeviceAdded` und `onDeviceRemoved` des Broadcast-SDK für Mikrofone nicht empfangen, da diese Android-Versionen nur das Standardmikrofon des Systems zulassen.

  **Workaround:** Für diese Geräte verwendet das Broadcast-SDK das Standardmikrofon des Systems.
+ Wenn eine `ImagePreviewView` in einem übergeordneten Element entfernt wird (`removeView()` wird z. B. im übergeordneten Element aufgerufen), wird die `ImagePreviewView` sofort freigegeben. Die `ImagePreviewView` zeigt keine Frames an, wenn sie einer anderen übergeordneten Ansicht hinzugefügt wird.

  **Problemumgehung:** Fordern Sie mit `getPreview` eine andere Vorschau an.
+ Einige Android-Videoencoder können nicht mit einer Videogröße von weniger als 176 × 176 konfiguriert werden. Die Konfiguration einer kleineren Größe verursacht einen Fehler und verhindert das Streaming.

  **Problemumgehung:** Konfigurieren Sie die Videogröße nicht auf weniger als 176 × 176.
+ Die Aktivierung von B-Frames kann die Komprimierungsqualität verbessern. Einige Encoder bieten jedoch bei aktivierten B-Frames eine weniger präzise Steuerung der Bitrate, was bei Netzwerkschwankungen zu Problemen führen kann.

  **Problemumgehung:** Wenn für Ihren Anwendungsfall die Einhaltung einer konstanten Bitrate wichtiger ist als die Effizienz der Komprimierung, sollten Sie B-Frames deaktivieren.

# IVS-Broadcast-SDK: iOS-Leitfaden \$1 Streaming mit niedriger Latenz
<a name="broadcast-ios"></a>

Das iOS-Broadcast-SDK von IVS Streaming mit niedriger Latenz bietet die für Broadcasting an Amazon IVS in iOS erforderlichen Schnittstellen.

Das Modul `AmazonIVSBroadcast` implementiert die in diesem Dokument beschriebene Schnittstelle. Folgende Operationen werden unterstützt:
+ Richten Sie eine Broadcast ein (initialisieren). 
+ Broadcasting verwalten.
+ Eingabegeräte anfügen und trennen.
+ Eine Zusammensetzungssitzung verwalten. 
+ Empfangen von Ereignissen. 
+ Erhalten von Fehlermeldungen. 

**Aktuelle Version des Broadcast-SDK für iOS:** 1.40.0 ([Versionshinweise](https://docs.aws.amazon.com/ivs/latest/LowLatencyUserGuide/release-notes.html#mar12-26-broadcast-mobile-ll)) 

Informationen zu den wichtigsten Methoden, die im Amazon-IVS-iOs-Broadcast-SDK verfügbar sind, finden Sie in der **Referenzdokumentation** unter [https://aws.github.io/amazon-ivs-broadcast-docs/1.40.0/ios/](https://aws.github.io/amazon-ivs-broadcast-docs/1.40.0/ios/).

**Beispiel-Code:** Siehe das iOS-Beispiel-Repository auf GitHub: [https://github.com/aws-samples/amazon-ivs-broadcast-ios-sample](https://github.com/aws-samples/amazon-ivs-broadcast-ios-sample).

**Plattformanforderungen:** iOS 14 und höher

## So wählt iOS Kameraauflösung und Bildrate
<a name="ios-publish-subscribe-resolution-framerate"></a>

Die vom Broadcast-SDK verwaltete Kamera optimiert ihre Auflösung und Bildrate (Bilder pro Sekunde oder FPS), um die Wärmeentwicklung und den Energieverbrauch zu minimieren. In diesem Abschnitt wird erläutert, wie Auflösung und Bildrate ausgewählt werden, um Hostanwendungen bei der Optimierung für ihre Anwendungsfälle zu unterstützen.

Wenn eine `IVSCamera` an eine `IVSBroadcastSession` angeschlossen wird, ist die Kamera für eine Bildrate von `IVSVideoConfiguration.targetFramerate` und eine Auflösung von `IVSVideoConfiguration.size` optimiert. Diese Werte werden `IVSBroadcastSession` bei der Initialisierung zur Verfügung gestellt. 

# Erste Schritte mit dem IVS-Broadcast-SDK für iOS \$1 Streaming mit niedriger Latenz
<a name="broadcast-ios-getting-started"></a>

Dieses Dokument führt Sie durch die Schritte zum Einstieg in das iOS-Broadcast-SDK für Amazon-IVS-Streaming mit niedriger Latenz.

## Bibliothek installieren
<a name="broadcast-ios-install"></a>

Wir empfehlen Ihnen, das SDK über Swift Package Manager zu integrieren. (Alternativ können Sie die Framework manuell zu Ihrem Projekt hinzufügen.)

### Empfohlen: Integrieren Sie das Broadcast-SDK (Swift Package Manager)
<a name="broadcast-ios-install-swift"></a>

1. Laden Sie die Datei Package.swift von [https://broadcast.live-video.net/1.40.0/Package.swift](https://broadcast.live-video.net/1.40.0/Package.swift) herunter.

1. Erstellen Sie in Ihrem Projekt ein neues Verzeichnis mit dem Namen AmazonIVSBroadcast und fügen Sie es der Versionskontrolle hinzu.

1. Platzieren Sie die heruntergeladene Datei Package.swift im neuen Verzeichnis.

1. Gehen Sie in Xcode zu **Datei > Paketabhängigkeiten hinzufügen** und wählen Sie **Lokal hinzufügen …**

1. Navigieren Sie zu dem von Ihnen erstellten AmazonIVSBroadcast-Verzeichnis, wählen Sie es aus und wählen Sie **Paket hinzufügen** aus.

1. Wenn Sie aufgefordert werden, **Paketprodukte für AmazonIVSBroadcast** auszuwählen, wählen Sie **AmazonIVSBroadcast** als Ihr **Paketprodukt** aus, indem Sie Ihr Anwendungsziel im Abschnitt **Zum Ziel hinzufügen** festlegen.

1. Wählen Sie **Paket hinzufügen** aus.

### Manuelles Installieren der Framework
<a name="broadcast-ios-install-manual"></a>

1. Laden Sie die neueste Version von [https://broadcast.live-video.net/1.40.0/AmazonIVSBroadcast.xcframework.zip](https://broadcast.live-video.net/1.40.0/AmazonIVSBroadcast.xcframework.zip) herunter.

1. Extrahieren Sie den Inhalt des Archivs. `AmazonIVSBroadcast.xcframework` enthält das SDK für Gerät und Simulator.

1. Betten Sie `AmazonIVSBroadcast.xcframework` ein, indem Sie es in den Abschnitt **Frameworks, Bibliotheken und eingebettete Inhalte** auf der Registerkarte **Allgemein** für Ihr Anwendungsziel ziehen.  
![\[Der Abschnitt Rahmenbedingungen, Bibliotheken und eingebettete Inhalte auf der Registerkarte Allgemein für Ihr Anwendungsziel.\]](http://docs.aws.amazon.com/de_de/ivs/latest/LowLatencyUserGuide/images/iOS_Broadcast_SDK_Guide_xcframework.png)

## Implementieren von IVSBroadcastSession.Delegate
<a name="broadcast-ios-implement-ivsbroadcastsessiondelegate"></a>

Implementieren von `IVSBroadcastSession.Delegate`, mit dem Sie Statusaktualisierungen und Geräteänderungsbenachrichtigungen erhalten können:

```
extension ViewController : IVSBroadcastSession.Delegate {
   func broadcastSession(_ session: IVSBroadcastSession,
                         didChange state: IVSBroadcastSession.State) {
      print("IVSBroadcastSession did change state \(state)")
   }

   func broadcastSession(_ session: IVSBroadcastSession,
                         didEmitError error: Error) {
      print("IVSBroadcastSession did emit error \(error)")
   }
}
```

## Berechtigungen anfordern
<a name="broadcast-ios-permissions"></a>

Ihre App muss die Berechtigung für den Zugriff auf die Kamera und das Mikrofon des Benutzers anfordern. (Dies ist nicht spezifisch für Amazon IVS; es ist für jede Anwendung erforderlich, die Zugriff auf Kameras und Mikrofone benötigt.)

Hier prüfen wir, ob der Benutzer bereits Berechtigungen erteilt hat und wenn nicht, fragen wir nach ihnen:

```
switch AVCaptureDevice.authorizationStatus(for: .video) {
case .authorized: // permission already granted.
case .notDetermined:
   AVCaptureDevice.requestAccess(for: .video) { granted in
       // permission granted based on granted bool.
   }
case .denied, .restricted: // permission denied.
@unknown default: // permissions unknown.
}
```

Sie müssen dies sowohl für `.video`- als auch für `.audio`-Medientypen tun, wenn Sie auf Kameras bzw. Mikrofone zugreifen möchten.

Sie müssen außerdem Einträge für `NSCameraUsageDescription` und `NSMicrophoneUsageDescription` zu Ihrem `Info.plist` hinzufügen. Andernfalls stürzt Ihre App ab, wenn Sie versuchen, Berechtigungen anzufordern.

## Deaktivieren des Idle-Timers der Anwendung
<a name="broadcast-ios-disable-idle-timer"></a>

Dies ist zwar optional, wird aber empfohlen. Es verhindert, dass Ihr Gerät in den Ruhezustand versetzt, während Sie das Broadcast-SDK verwenden, was die Übertragung unterbrechen würde.

```
override func viewDidAppear(_ animated: Bool) {
   super.viewDidAppear(animated)
   UIApplication.shared.isIdleTimerDisabled = true
}
override func viewDidDisappear(_ animated: Bool) {
   super.viewDidDisappear(animated)
   UIApplication.shared.isIdleTimerDisabled = false
}
```

## (Optional) Einrichten von AVAudioSession
<a name="broadcast-ios-setup-avaudiosession"></a>

Standardmäßig richtet das Broadcast-SDK die Ihrer Anwendung ein `AVAudioSession`. Wenn Sie dies selbst verwalten möchten, setzen Sie `IVSBroadcastSession.applicationAudioSessionStrategy` auf `noAction`. Ohne Kontrolle über das `AVAudioSession` kann das Broadcast-SDK Mikrofone nicht intern verwalten. Zur Verwendung von Mikrofonen mit der Option `noAction` können Sie eine `IVSCustomAudioSource` erstellen und Ihre eigenen Proben über ein `AVCaptureSession`, `AVAudioEngine` oder ein anderes Tool einspielen, das PCM-Hörbeispiele bereitstellt.

Wenn Sie Ihre `AVAudioSession` manuell einrichten, müssen Sie mindestens die Kategorie als `.record` oder `.playbackAndRecord` und auf `active` festlegen. Wenn Sie Audio von Bluetooth-Geräten aufzeichnen möchten, müssen Sie die `.allowBluetooth`-Option auch angeben:

```
do {
   try AVAudioSession.sharedInstance().setCategory(.record, options: .allowBluetooth)
   try AVAudioSession.sharedInstance().setActive(true)
} catch {
   print("Error configuring AVAudioSession")
}
```

Wir empfehlen, dass Sie das SDK dies für Sie handhaben lassen. Wenn Sie andernfalls zwischen verschiedenen Audiogeräten wählen möchten, müssen Sie die Ports manuell verwalten.

## Broadcast-Sitzung erstellen
<a name="broadcast-ios-create-session"></a>

Die Broadcast-Schnittstelle ist `IVSBroadcastSession`. Initialisieren Sie es wie unten gezeigt:

```
let broadcastSession = try IVSBroadcastSession(
   configuration: IVSPresets.configurations().standardLandscape(),
   descriptors: IVSPresets.devices().frontCamera(),
   delegate: self)
```

Lesen Sie auch [Erstellen der Broadcast-Sitzung (Advanced-Version)](broadcast-ios-use-cases.md#broadcast-ios-create-session-advanced)

## Legen Sie die IVSImagePreviewView für die Vorschau fest
<a name="broadcast-ios-set-imagepreviewview"></a>

Wenn Sie eine Vorschau für ein aktives Kameragerät anzeigen möchten, fügen Sie die Vorschau `IVSImagePreviewView` für das Gerät zu Ihrer View-Hierarchie hinzu:

```
// If the session was just created, execute the following 
// code in the callback of IVSBroadcastSession.awaitDeviceChanges 
// to ensure all devices have been attached.
if let devicePreview = try broadcastSession.listAttachedDevices()
   .compactMap({ $0 as? IVSImageDevice })
   .first?
   .previewView()
{
   previewView.addSubview(devicePreview)
}
```

## Starten eines Broadcastings
<a name="broadcast-ios-start"></a>

Dem Hostnamen, den Sie im Antwortfeld `ingestEndpoint` des Vorgangs `GetChannel` erhalten, muss `rtmps://` vorangestellt und `/app` angehängt werden. Die vollständige URL sollte sich in folgendem Format sein: `rtmps://{{ ingestEndpoint }}/app`

```
try broadcastSession.start(with: IVS_RTMPS_URL, streamKey: IVS_STREAMKEY)
```

 Das iOS-Broadcast-SDK unterstützt nur RTMPS-Ingest (kein unsicheres RTMP-Ingest). 

## Anhalten eines Broadcastings
<a name="broadcast-ios-stop"></a>

```
broadcastSession.stop()
```

## Lebenszyklus-Ereignisse verwalten
<a name="broadcast-ios-lifecycle-events"></a>

### Audiounterbrechungen
<a name="broadcast-ios-audio-interruptions"></a>

Es gibt mehrere Szenarien, in denen das Broadcast-SDK keinen exklusiven Zugriff auf Audio-Eingabehardware hat. Einige Beispielszenarien, die Sie verarbeiten müssen, sind:
+ Benutzer erhält einen Anruf oder FaceTime-Anruf
+ Benutzer aktiviert Siri

Apple macht es einfach, auf diese Ereignisse zu reagieren, indem es abonniert `AVAudioSession.interruptionNotification`:

```
NotificationCenter.default.addObserver(
   self,
   selector: #selector(audioSessionInterrupted(_:)),
   name: AVAudioSession.interruptionNotification,
   object: nil)
```

Dann können Sie das Ereignis mit etwas wie diesem behandeln:

```
// This assumes you have a variable `isRunning` which tracks if the broadcast is currently live, and another variable `wasRunningBeforeInterruption` which tracks whether the broadcast was active before this interruption to determine if it should resume after the interruption has ended.

@objc
private func audioSessionInterrupted(_ notification: Notification) {
   guard let userInfo = notification.userInfo,
         let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt,
         let type = AVAudioSession.InterruptionType(rawValue: typeValue)
   else {
      return
   }
   switch type {
   case .began:
      wasRunningBeforeInterruption = isRunning
      if isRunning {
         broadcastSession.stop()
      }
   case .ended:
      defer {
         wasRunningBeforeInterruption = false
      }
      guard let optionsValue = userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else { return }
      let options = AVAudioSession.InterruptionOptions(rawValue: optionsValue)
      if options.contains(.shouldResume) && wasRunningBeforeInterruption {
         try broadcastSession.start(
            with: IVS_RTMPS_URL,
            streamKey: IVS_STREAMKEY)
      }
   @unknown default: break
   }
}
```

### App geht in den Hintergrund
<a name="broadcast-ios-app-to-background"></a>

Standardanwendungen auf iOS dürfen keine Kameras im Hintergrund verwenden. Es gibt auch Einschränkungen bei der Videocodierung im Hintergrund: Da Hardware-Encoder begrenzt sind, haben nur Vordergrundanwendungen Zugriff. Aus diesem Grund beendet das Broadcast-SDK automatisch seine Sitzung und setzt seine `isReady`-Eigenschaft auf `false`. Wenn Ihre Anwendung erneut in den Vordergrund tritt, fügt das Broadcast-SDK alle Geräte wieder an ihre ursprünglichen `IVSMixerSlotConfiguration`-Einträge hinzu.

Das Broadcast-SDK tut dies, indem es auf `UIApplication.didEnterBackgroundNotification` und `UIApplication.willEnterForegroundNotification` antwortet.

Wenn Sie benutzerdefinierte Image-Quellen bereitstellen, sollten Sie bereit sein, diese Benachrichtigungen zu behandeln. Möglicherweise müssen Sie zusätzliche Schritte unternehmen, um sie zu schliessen, bevor der Stream beendet wird.

Für eine Problemumgehung, die Streaming ermöglicht, während sich Ihre Anwendung im Hintergrund befindet, siehe [Hintergrundvideo verwenden](broadcast-ios-use-cases.md#broadcast-ios-background-video).

### Medienservices verloren
<a name="broadcast-ios-media-services-lost"></a>

In sehr seltenen Fällen stürzt das gesamte Medien-Subsystem auf einem iOS-Gerät ab. In diesem Szenario können wir nicht mehr broadcasten. Es liegt an Ihrer Anwendung, auf diese Benachrichtigungen angemessen zu reagieren. Abonnieren Sie mindestens diese Benachrichtigungen:
+ [MediaServiceWerelostNotification](https://developer.apple.com/documentation/avfaudio/avaudiosession/1616457-mediaserviceswerelostnotificatio) – Reagieren Sie, indem Sie Ihr Broadcasting stoppen und Ihre `IVSBroadcastSession` vollständig freigeben. Alle internen Komponenten, die von der Broadcast-Sitzung verwendet werden, werden ungültig.
+ [MediaServiceServiceServiceSetNotification](https://developer.apple.com/documentation/avfaudio/avaudiosession/1616540-mediaserviceswereresetnotificati) – Reagieren Sie, indem Sie Ihre Benutzer darüber informieren, dass sie erneut übertragen können. Abhängig vom Anwendungsfall können Sie möglicherweise an dieser Stelle automatisch wieder senden.

# Fortgeschrittene Anwendungsfälle für das IVS-iOS-Broadcast-SDK \$1 Streaming mit niedriger Latenz
<a name="broadcast-ios-use-cases"></a>

Hier stellen wir einige fortschrittliche Anwendungsfälle vor. Beginnen Sie mit dem obigen Basis-Setup und fahren Sie hier fort.

## Broadcast-Konfiguration erstellen
<a name="broadcast-ios-create-configuration"></a>

Hier erstellen wir eine benutzerdefinierte Konfiguration mit zwei Mischersteckplätzen, die es uns erlauben, zwei Videoquellen an den Mischer zu binden. Eine (`custom`) ist Vollbild und hinter der anderen angelegt (`camera`), die kleiner und in der unteren rechten Ecke ist. Beachten Sie, dass wir für den `custom`-Slot keine Position, Größe oder Seitenverhältnis festlegen. Da wir diese Parameter nicht einstellen, verwendet der Slot die Videoeinstellungen für Größe und Position.

```
let config = IVSBroadcastConfiguration()
try config.audio.setBitrate(128_000)
try config.video.setMaxBitrate(3_500_000)
try config.video.setMinBitrate(500_000)
try config.video.setInitialBitrate(1_500_000)
try config.video.setSize(CGSize(width: 1280, height: 720))
config.video.defaultAspectMode = .fit
config.mixer.slots = [
    try {
        let slot = IVSMixerSlotConfiguration()
        // Do not automatically bind to a source
        slot.preferredAudioInput = .unknown
        // Bind to user image if unbound
        slot.preferredVideoInput = .userImage
        try slot.setName("custom")
        return slot
    }(),
    try {
        let slot = IVSMixerSlotConfiguration()
        slot.zIndex = 1
        slot.aspect = .fill
        slot.size = CGSize(width: 300, height: 300)
        slot.position = CGPoint(x: config.video.size.width - 400, y: config.video.size.height - 400)
        try slot.setName("camera")
        return slot
    }()
]
```

## Erstellen der Broadcast-Sitzung (Advanced-Version)
<a name="broadcast-ios-create-session-advanced"></a>

Erstellen Sie eine `IVSBroadcastSession` wie im [grundlegenden Beispiel](broadcast-ios-getting-started.md#broadcast-ios-create-session), geben Sie jedoch hier Ihre benutzerdefinierte Konfiguration an. Geben Sie auch `nil` für das Gerätearray an, da wir diese manuell hinzufügen werden.

```
let broadcastSession = try IVSBroadcastSession(
   configuration: config, // The configuration we created above
   descriptors: nil, // We’ll manually attach devices after
   delegate: self)
```

## Iterieren und Anschließen eines Kamerageräts
<a name="broadcast-ios-attach-camera"></a>

Hier iterieren wir durch Eingabegeräte, die das SDK erkannt hat. Das SDK gibt nur integrierte Geräte auf iOS zurück. Selbst wenn Bluetooth-Audiogeräte angeschlossen sind, werden sie als integriertes Gerät angezeigt. Weitere Informationen finden Sie unter [Bekannte Probleme und Problemumgehungen im IVS-iOS-Broadcast-SDK \$1 Streaming mit niedriger Latenz](broadcast-ios-issues.md).

Sobald wir ein Gerät gefunden haben, das wir verwenden möchten, rufen wir `attachDevice` auf, um es anzuhängen:

```
let frontCamera = IVSBroadcastSession.listAvailableDevices()
    .filter { $0.type == .camera && $0.position == .front }
    .first
if let camera = frontCamera {
    broadcastSession.attach(camera, toSlotWithName: "camera") { device, error in
        // check error
    }
}
```

## Kameras austauschen
<a name="broadcast-ios-swap-cameras"></a>

```
// This assumes you’ve kept a reference called `currentCamera` that points to the current camera.
let wants: IVSDevicePosition = (currentCamera.descriptor().position == .front) ? .back : .front
// Remove the current preview view since the device will be changing.
previewView.subviews.forEach { $0.removeFromSuperview() }
let foundCamera = IVSBroadcastSession
        .listAvailableDevices()
        .first { $0.type == .camera && $0.position == wants }
guard let newCamera = foundCamera else { return }
broadcastSession.exchangeOldDevice(currentCamera, withNewDevice: newCamera) { newDevice, _ in
    currentCamera = newDevice
    if let camera = newDevice as? IVSImageDevice {
        do {
            previewView.addSubview(try finalCamera.previewView())
        } catch {
            print("Error creating preview view \(error)")
        }
    }
}
```

## Erstellen einer benutzerdefinierten Eingabequelle
<a name="broadcast-ios-create-input-source"></a>

Um Audio- oder Image-Daten einzugeben, die von Ihrer App generiert werden, verwenden Sie `createImageSource` oder `createAudioSource`. Beide Methoden erstellen virtuelle Geräte (`IVSCustomImageSource` and `IVSCustomAudioSource`), die wie jedes andere Gerät an den Mischer gebunden werden können.

Die Geräte, die von beiden diesen Methoden zurückgegeben werden, akzeptieren `CMSampleBuffer` durch die `onSampleBuffer`-Funktion:
+ Bei Videoquellen muss das Pixelformat `kCVPixelFormatType_32BGRA`, `420YpCbCr8BiPlanarFullRange`, oder `420YpCbCr8BiPlanarVideoRange` sein.
+ Bei Audioquellen muss der Puffer lineare PCM-Daten enthalten.

Sie können ein `AVCaptureSession` mit Kameraeingang nicht verwenden, um eine benutzerdefinierte Image-Quelle zu füllen, während Sie gleichzeitig ein Kameragerät verwenden, das vom Broadcast-SDK bereitgestellt wird. Wenn Sie mehrere Kameras gleichzeitig verwenden möchten, verwenden Sie `AVCaptureMultiCamSession` und stellen Sie zwei benutzerdefinierte Image-Quellen bereit.

Benutzerdefinierte Image-Quellen sollten in erster Linie mit statischen Inhalten wie Bildern oder mit Videoinhalten verwendet werden:

```
let customImageSource = broadcastSession.createImageSource(withName: "video")
try broadcastSession.attach(customImageSource, toSlotWithName: "custom")
```

## Überwachen der Netzwerkverbindung
<a name="broadcast-ios-network-connection"></a>

Es ist üblich, dass mobile Geräte vorübergehend verlieren und die Netzwerkverbindung wiedererlangen, während sie unterwegs sind. Aus diesem Grund ist es wichtig, die Netzwerkkonnektivität Ihrer App zu überwachen und entsprechend zu reagieren, wenn sich Dinge ändern. 

Wenn die Verbindung des Broadcasters unterbrochen wird, ändert sich der Status des Broadcast-SDK in `error` und dann `disconnected`. Sie werden über diese Änderungen über die benachrichtigt `IVSBroadcastSessionDelegate`. Wenn Sie diese Statusänderungen erhalten:

1. Überwachen Sie den Verbindungsstatus Ihrer Broadcast-App und rufen Sie `start` mit Ihrem Endpunkt und Streamschlüssel auf, sobald Ihre Verbindung wiederhergestellt wurde.

1. **Wichtig:** Überwachen Sie den Rückruf des Zustandsdelegaten und stellen Sie sicher, dass sich der Status nach dem Aufruf `start` zu `connected` ändert.

## Trennen eines Geräts
<a name="broadcast-ios-detach-device"></a>

Wenn Sie ein Gerät trennen und nicht ersetzen möchten, trennen Sie es mit `IVSDevice` oder `IVSDeviceDescriptor`:

```
broadcastSession.detachDevice(currentCamera)
```

## ReplayKit-Integration
<a name="broadcast-ios-replaykit"></a>

Um den Bildschirm und das Systemaudio des Geräts auf iOS zu streamen, müssen Sie [ReplayKit](https://developer.apple.com/documentation/replaykit?language=objc) integrieren. Das Amazon IVS-Broadcast-SDK erleichtert die Integration von ReplayKit mit `IVSReplayKitBroadcastSession`. In Ihrer `RPBroadcastSampleHandler`-Unterklasse erstellen Sie eine Instance von `IVSReplayKitBroadcastSession`, dann:
+ Starten Sie die Sitzung in `broadcastStarted`
+ Beenden Sie die Sitzung in `broadcastFinished`

Das Sitzungsobjekt verfügt über drei benutzerdefinierte Quellen für Bildschirm-Images, App-Audio und Mikrofonaudio. Übergeben Sie das in `processSampleBuffer` angegebene `CMSampleBuffers` an diese benutzerdefinierten Quellen.

Um die Geräteausrichtung zu verarbeiten, müssen Sie Replaykit-spezifische Metadaten aus dem Beispielpuffer extrahieren. Verwenden Sie folgenden Code:

```
let imageSource = session.systemImageSource;
if let orientationAttachment = CMGetAttachment(sampleBuffer, key: RPVideoSampleOrientationKey as CFString, attachmentModeOut: nil) as? NSNumber,
    let orientation = CGImagePropertyOrientation(rawValue: orientationAttachment.uint32Value) {
    switch orientation {
    case .up, .upMirrored:
        imageSource.setHandsetRotation(0)
    case .down, .downMirrored:
        imageSource.setHandsetRotation(Float.pi)
    case .right, .rightMirrored:
        imageSource.setHandsetRotation(-(Float.pi / 2))
    case .left, .leftMirrored:
        imageSource.setHandsetRotation((Float.pi / 2))
    }
}
```

Es ist möglich, ReplayKit mit `IVSBroadcastSession` anstelle von `IVSReplayKitBroadcastSession` zu integrieren. Die ReplayKit-spezifische Variante weist jedoch mehrere Modifikationen auf, um den internen Speicherbedarf zu reduzieren, um innerhalb der Speicherobergrenze von Apple für Broadcast-Erweiterungen zu bleiben.

## Empfohlene Broadcast-Einstellungen erhalten
<a name="broadcast-ios-recommended-settings"></a>

Um die Verbindung Ihres Benutzers vor dem Starten einer Übertragung zu bewerten, verwenden Sie `IVSBroadcastSession.recommendedVideoSettings`, um einen kurzen Test durchzuführen. Während der Testläufe erhalten Sie mehrere Empfehlungen, geordnet von den am meisten empfohlenen zu den am wenigsten empfohlenen. In dieser Version des SDK ist es nicht möglich, die aktuelle `IVSBroadcastSession` neu zu konfigurieren, daher müssen Sie sie freigeben und dann eine neue mit den empfohlenen Einstellungen erstellen. Sie erhalten weiterhin `IVSBroadcastSessionTestResults` bis `result.status` `Success` ist oder `Error`. Sie können den Fortschritt mit überprüfen `result.progress`.

Amazon IVS unterstützt eine maximale Bitrate von 8,5 Mbit/s (für Kanäle, deren `type` `STANDARD` oder `ADVANCED` ist), so dass die `maximumBitrate`, die von dieser Methode zurückgegeben wird, nie 8,5 Mbps überschreitet. Um kleine Schwankungen der Netzwerkleistung zu berücksichtigen, ist die von dieser Methode empfohlene `initialBitrate` etwas niedriger als die im Test gemessene tatsächliche Bitrate. (Die Verwendung von 100 % der verfügbaren Bandbreite ist in der Regel nicht ratsam.)

```
func runBroadcastTest() {
    self.test = session.recommendedVideoSettings(with: IVS_RTMPS_URL, streamKey: IVS_STREAMKEY) { [weak self] result in
        if result.status == .success {
            self?.recommendation = result.recommendations[0];
        }
    }
}
```

## Verwenden der automatischen Wiederverbindung
<a name="broadcast-ios-auto-reconnect"></a>

IVS unterstützt die automatische Wiederverbindung mit einem Broadcast, falls der Broadcast unerwartet beendet wird, ohne die `stop`-API aufzurufen, z. B. bei einem vorübergehenden Verlust der Netzwerkkonnektivität. Legen Sie zum Aktivieren der automatischen Wiederverbindung die Eigenschaft `enabled` für `IVSBroadcastConfiguration.autoReconnect` auf `true` fest.

Wenn der Stream aus irgendeinem Grund unerwartet beendet wird, versucht das SDK die Wiederverbindung bis zu fünf Mal. Dabei folgt es einer linearen Backoff-Strategie. Es benachrichtigt Ihre Anwendung mithilfe der Funktion `IVSBroadcastSessionDelegate.didChangeRetryState` über den Status der erneuten Versuche.

Die automatische Wiederverbindung nutzt im Hintergrund die IVS-Funktion für die [Stream-Übernahme](streaming-config.md#streaming-config-stream-takeover), indem eine Prioritätsnummer, beginnend mit 1, an das Ende des bereitgestellten Stream-Schlüssels angehängt wird. Für die Dauer der `IVSBroadcastSession`-Instance wird diese Zahl bei jedem erneuten Verbindungsversuch um 1 erhöht. Das bedeutet Folgendes: Wenn die Verbindung des Geräts während eines Broadcasts viermal unterbrochen wird und für jede Unterbrechung 1–4 Wiederholungsversuche erforderlich sind, kann die Priorität des letzten Streamups zwischen 5 und 17 liegen. Aus diesem Grund *empfehlen wir, die IVS-Stream-Übernahme von einem anderen Gerät nicht zu verwenden, solange die automatische Wiederverbindung im SDK für denselben Kanal aktiviert ist*. Es gibt keine Garantie dafür, welche Priorität das SDK zu diesem Zeitpunkt verwendet, und das SDK versucht, die Verbindung mit einer höheren Priorität wiederherzustellen, wenn ein anderes Gerät den Stream übernimmt.

## Hintergrundvideo verwenden
<a name="broadcast-ios-background-video"></a>

Sie können eine Nicht-Relaykit-Sendung fortsetzen, auch wenn Ihre Anwendung im Hintergrund liegt.

Um Strom zu sparen und Vordergrundanwendungen aktiv zu halten, gewährt iOS jeweils nur einer Anwendung Zugriff auf die GPU. Das Amazon IVS-Broadcast-SDK verwendet die GPU in mehreren Stages der Videopipeline, einschließlich der Zusammenstellung mehrerer Eingangsquellen, der Skalierung und der Kodierung des Images. Während sich die Sendeanwendung im Hintergrund befindet, gibt es keine Garantie dafür, dass das SDK eine dieser Aktionen ausführen kann.

Verwenden Sie dazu die `createAppBackgroundImageSource`-Methode. So kann das SDK im Hintergrund weiterhin sowohl Video als auch Audio übertragen. Es gibt eine `IVSBackgroundImageSource` als normale `IVSCustomImageSource` mit einer zusätzlichen `finish`-Funktion zurück. Jede zur Hintergrundbildquelle zur Verfügung gestellte `CMSampleBuffer` wird mit der Image-Rate codiert, die von Ihrer Original-`IVSVideoConfiguration` bereitgestellt wird. Zeitstempel auf der `CMSampleBuffer` werden ignoriert.

Das SDK skaliert und codiert diese Bilder dann und speichert sie im Cache, wobei dieser Feed automatisch durchläuft, wenn Ihre Anwendung in den Hintergrund geht. Wenn Ihre Anwendung in den Vordergrund zurückkehrt, werden die angeschlossenen Image-Geräte wieder aktiv und die Schleife des vorkodierten Streams stoppt.

Um diesen Vorgang rückgängig zu machen, verwenden Sie `removeImageSourceOnAppBackgrounded`. Sie müssen dies nicht aufrufen, es sei denn, Sie möchten das Hintergrundverhalten des SDK explizit rückgängig machen, andernfalls wird es bei Beendigung der automatisch bereinigt `IVSBroadcastSession`.

**Hinweise:** *Wir empfehlen dringend, diese Methode im Rahmen der Konfiguration der Broadcast-Sitzung aufzurufen, bevor die Sitzung live geht.* Die Methode ist teuer (sie kodiert Video), daher kann die Leistung einer Live-Übertragung während der Ausführung dieser Methode beeinträchtigt werden.

### Beispiel: Generieren eines statischen Images für Hintergrundvideo
<a name="background-video-example-static-image"></a>

Wenn Sie der Hintergrundquelle ein einzelnes Image bereitstellen, wird eine vollständige GOP dieses statischen Images generiert.

Hier finden Sie ein Beispiel mit CiImage:

```
// Create the background image source
guard let source = session.createAppBackgroundImageSource(withAttemptTrim: true, onComplete: { error in
    print("Background Video Generation Done - Error: \(error.debugDescription)")
}) else {
    return
}

// Create a CIImage of the color red.
let ciImage = CIImage(color: .red)

// Convert the CIImage to a CVPixelBuffer
let attrs = [
    kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue,
    kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue,
    kCVPixelBufferMetalCompatibilityKey: kCFBooleanTrue,
] as CFDictionary

var pixelBuffer: CVPixelBuffer!
CVPixelBufferCreate(kCFAllocatorDefault,
                    videoConfig.width,
                    videoConfig.height,
                    kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,
                    attrs,
                    &pixelBuffer)

let context = CIContext()
context.render(ciImage, to: pixelBuffer)

// Submit to CVPixelBuffer and finish the source
source.add(pixelBuffer)
source.finish()
```

Anstatt ein CiImage in einer Volltonfarbe zu erstellen, können Sie alternativ gebündelte Bilder verwenden. Der einzige hier gezeigte Code ist zur Konvertierung eines UIImage in ein CiImage, um es mit dem vorherigen Beispiel zu verwenden:

```
// Load the pre-bundled image and get it’s CGImage
guard let cgImage = UIImage(named: "image")?.cgImage else {
    return
}

// Create a CIImage from the CGImage
let ciImage = CIImage(cgImage: cgImage)
```

### Beispiel: Video mit AvasseTimageGenerator
<a name="background-video-example-avassetimagegenerator"></a>

Sie können einen `AVAssetImageGenerator` verwenden, um `CMSampleBuffers` aus einem `AVAsset` zu generieren (obwohl kein HLS-Stream-`AVAsset`):

```
// Create the background image source
guard let source = session.createAppBackgroundImageSource(withAttemptTrim: true, onComplete: { error in
    print("Background Video Generation Done - Error: \(error.debugDescription)")
}) else {
    return
}

// Find the URL for the pre-bundled MP4 file
guard let url = Bundle.main.url(forResource: "sample-clip", withExtension: "mp4") else {
    return
}
// Create an image generator from an asset created from the URL.
let generator = AVAssetImageGenerator(asset: AVAsset(url: url))
// It is important to specify a very small time tolerance.
generator.requestedTimeToleranceAfter = .zero
generator.requestedTimeToleranceBefore = .zero

// At 30 fps, this will generate 4 seconds worth of samples.
let times: [NSValue] = (0...120).map { NSValue(time: CMTime(value: $0, timescale: CMTimeScale(config.video.targetFramerate))) }
var completed = 0

let context = CIContext(options: [.workingColorSpace: NSNull()])

// Create a pixel buffer pool to efficiently feed the source
let attrs = [
    kCVPixelBufferPixelFormatTypeKey: kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,
    kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue,
    kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue,
    kCVPixelBufferMetalCompatibilityKey: kCFBooleanTrue,
    kCVPixelBufferWidthKey: videoConfig.width,
    kCVPixelBufferHeightKey: videoConfig.height,
] as CFDictionary
var pool: CVPixelBufferPool!
CVPixelBufferPoolCreate(kCFAllocatorDefault, nil, attrs, &pool)

generator.generateCGImagesAsynchronously(forTimes: times) { requestTime, image, actualTime, result, error in
    if let image = image {
        // convert to CIImage then CVpixelBuffer
        let ciImage = CIImage(cgImage: image)
        var pixelBuffer: CVPixelBuffer!
        CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, pool, &pixelBuffer)
        context.render(ciImage, to: pixelBuffer)
        source.add(pixelBuffer)
    }
    completed += 1
    if completed == times.count {
        // Mark the source finished when all images have been processed
        source.finish()
    }
}
```

Es kann ein `CVPixelBuffers` durch Nutzung eines `AVPlayer` und `AVPlayerItemVideoOutput` erstellt werden. Dies erfordert jedoch die Verwendung eines `CADisplayLink` und kommt näher an Echtzeit heran, während `AVAssetImageGenerator` die Frames viel schneller verarbeiten kann.

### Einschränkungen
<a name="background-video-limitations"></a>

Ihre Anwendung benötigt [Hintergrund-Audio-Berechtigung](https://developer.apple.com/documentation/xcode/configuring-background-execution-modes), um zu vermeiden, dass sie nach dem Gang in den Hintergrund suspendiert wird.

`createAppBackgroundImageSource` kann nur aufgerufen werden, solange Ihre Anwendung im Vordergrund ist, da sie zum Abschluss Zugriff auf die GPU benötigt.

`createAppBackgroundImageSource` kodiert immer zu einer vollständigen GOP. Wenn Sie beispielsweise ein Keyframe-Intervall von 2 Sekunden haben (Standardeinstellung) und mit 30 fps oeprieren, wird ein Vielfaches von 60 Frames kodiert.
+ Wenn weniger als 60 Frames bereitgestellt werden, wird unabhängig vom Wert der Trimmoption das letzte Frame wiederholt, bis 60 Frames erreicht sind.
+ Wenn mehr als 60 Frames vorhanden sind und die Trimmoption `true` gewählt ist, werden die letzten n Frames gelöscht, wobei n der Rest der Gesamtzahl der übermittelten Frames geteilt durch 60 ist.
+ Wenn mehr als 60 Frames vorhanden sind und die Trimmoption `false` gewählt ist, wird das letzte Frame wiederholt, bis das nächste Vielfache von 60 Frames erreicht ist.

# Bekannte Probleme und Problemumgehungen im IVS-iOS-Broadcast-SDK \$1 Streaming mit niedriger Latenz
<a name="broadcast-ios-issues"></a>

In diesem Dokument werden bekannte Probleme aufgeführt, die bei der Verwendung des iOS-Broadcast-SDK für Amazon-IVS-Streaming mit niedriger Latenz auftreten können, und es werden mögliche Problemumgehungen vorgeschlagen.
+ Ein Fehler in ReplayKit verursacht ein schnelles Speicherwachstum, wenn ein kabelgebundenes Headset während eines Streams angeschlossen wird.

  **Problemumgehung:** Starten Sie den Stream, wenn das verkabelte Headset bereits angeschlossen ist, verwenden Sie ein Bluetooth-Headset oder verwenden Sie kein externes Mikrofon.
+ Wenn Sie zu irgendeinem Zeitpunkt während eines ReplayKit-Streams das Mikrofon aktivieren und dann die Audiositzung unterbrechen (z. B. mit einem Anruf oder durch Aktivierung von Siri), funktioniert das Systemaudio nicht mehr. Dies ist ein ReplayKit-Fehler, den wir mit Apple lösen.

  **Problemumgehung:** Beenden Sie bei einer Audiounterbrechung die Übertragung und warnen Sie den Benutzer.
+ AirPods zeichnen keine Audiosignale auf, wenn die `AVAudioSession`-Kategorie auf `record` festgelegt ist. Standardmäßig verwendet das SDK `playAndRecord`, daher tritt dieses Problem nur auf, wenn die Kategorie in `record` geändert wird.

  **Problemumgehung:** Wenn die Möglichkeit besteht, dass AirPods zum Aufzeichnen von Audio verwendet werden, verwenden Sie `playAndRecord`, auch wenn Ihre Anwendung keine Medien wiedergibt. 
+ Wenn AirPods an ein iOS-12-Gerät angeschlossen sind, kann kein anderes Mikrofon zur Aufnahme von Audio verwendet werden. Der Versuch, zu einem internen Mikrofon zu wechseln, kehrt sofort zu den AirPods zurück.

  **Problemumgehung:** Keine. Wenn AirPods mit iOS 12 verbunden sind, sind sie das einzige Gerät, das Audio aufnehmen kann.
+ Das Absenden von Audiodaten schneller als in Echtzeit (mit einer benutzerdefinierten Audioquelle) führt zu einer Audiodrift.

  **Problemumgehung:** Senden Sie Audiodaten nicht schneller als in Echtzeit ab. 
+ Audio-Artefakte können bei Bitraten unter 68 Kbit/s auftreten, wenn eine hohe Abtastrate (44100 Hz oder höher) mit zwei Kanälen verwendet wird.

  **Problemumgehung:** Erhöhen Sie die Bitrate auf 68 Kbit/s oder höher, verringern Sie die Abtastrate auf 24000 Hz oder niedriger oder stellen Sie die Kanäle auf 1 ein.
+ Wenn die Echounterdrückung auf `IVSMicrophone`-Geräten aktiviert ist, wird von der Methode `listAvailableInputSources` nur eine einzige Mikrofonquelle zurückgegeben. 

  **Problemumgehung:** Keine. Dieses Verhalten wird von iOS gesteuert.
+ Das Ändern von Bluetooth-Audiorouten kann unvorhersehbar sein. Wenn Sie ein neues Gerät in der Mitte der Sitzung verbinden, kann iOS die Eingaberoute automatisch ändern oder nicht. Es ist auch nicht möglich, zwischen mehreren Bluetooth-Headsets zu wählen, die gleichzeitig verbunden sind. Dies geschieht sowohl bei normalen Broadcast- als auch bei Stagesitzungen.

  **Problemumgehung:** Wenn Sie ein Bluetooth-Headset verwenden möchten, verbinden Sie es, bevor Sie den Broadcast oder die Stage starten und lassen Sie es während der gesamten Sitzung verbunden.
+ iOS entfernt den Zugriff auf die Kamera, wenn das AirPods-Popup nach dem Öffnen einer gekoppelten AirPods-Hülle angezeigt wird, während die AirPods selbst in der Hülle belassen werden. Dies führt dazu, dass das Video für eine Übertragung oder Stage einfriert.

  **Problemumgehung:** Keine. iOS widerruft den Kamerazugriff vollständig, während das Popup gerendert wird, und es ist für Anwendungen von Drittanbietern unmöglich, das Popup zu verhindern.
+ Die Aktivierung von B-Frames kann die Komprimierungsqualität verbessern. Einige Encoder bieten jedoch bei aktivierten B-Frames eine weniger präzise Steuerung der Bitrate, was bei Netzwerkschwankungen zu Problemen führen kann.

  **Problemumgehung:** Wenn für Ihren Anwendungsfall die Einhaltung einer konstanten Bitrate wichtiger ist als die Effizienz der Komprimierung, sollten Sie B-Frames deaktivieren.

# IVS-Broadcast-SDK: Gemischte Geräte
<a name="broadcast-mixed-devices"></a>

Gemischte Geräte sind Audio- und Videogeräte, die mehrere Eingangsquellen auf einen einzigen Ausgang kombinieren. Geräte mischen ist ein leistungsstarkes Feature, mit dem Sie mehrere Bildschirmelemente (Video) und Audiospuren definieren und verwalten können. Sie können Video und Audio aus mehreren Quellen wie Kameras, Mikrofonen, Bildschirmaufnahmen sowie von Ihrer App generiertes Audio und Video kombinieren. Sie können mit Übergängen diese Quellen im Video, das Sie an IVS streamen, verschieben und während des Streamings Quellen hinzufügen oder entfernen.

Gemischte Geräte gibt es in Bild- und Audioausführungen. Um ein Gemischtes-Bild-Gerät zu erstellen, rufen Sie auf:

`DeviceDiscovery.createMixedImageDevice()` auf Android

`IVSDeviceDiscovery.createMixedImageDevice()` auf iOS

Das zurückgegebene Gerät kann wie jedes andere Gerät an eine `BroadcastSession` (Streaming mit niedriger Latenz) oder `Stage` (Echtzeit-Streaming) angeschlossen werden.

## Terminologie
<a name="broadcast-mixed-devices-terminology"></a>

![\[Terminologie für gemischte Geräte mit IVS-Broadcasting.\]](http://docs.aws.amazon.com/de_de/ivs/latest/LowLatencyUserGuide/images/Broadcast_SDK_Mixer_Glossary.png)



| Begriff | Beschreibung | 
| --- | --- | 
| Gerät | Eine Hardware- oder Softwarekomponente, die Audio- oder Bild-Eingaben produziert. Beispiele für Geräte sind Mikrofone, Kameras, Bluetooth-Headsets und virtuelle Geräte wie Bildschirmaufnahmen oder benutzerdefinierte Image-Eingänge. | 
| Gemischtes Gerät | Ein `Device`, das wie jedes andere `Device` an ein `BroadcastSession` angehängt werden kann, jedoch mit zusätzlichen APIs, die das Hinzufügen von `Source`-Objekten ermöglichen. Gemischte Geräte verfügen über interne Mischer, die Audio- oder Bilddateien zusammensetzen und so einen einzigen Audio- und Bildausgangsstream erzeugen. Gemischte Geräte gibt es in Bild- und Audioausführungen.  | 
| Konfiguration gemischter Geräte | Ein Konfigurationsobjekt für das gemischte Gerät. Bei gemischten Geräten mit Bildern werden dadurch Eigenschaften wie Abmessungen und Bildrate konfiguriert. Bei gemischten Geräten mit Audiodateien wird dadurch die Kanalanzahl konfiguriert. | 
|  Quelle | Ein Container, der die Position eines visuellen Elements auf dem Bildschirm und die Eigenschaften einer Audiospur im Audiomix definiert. Ein gemischtes Gerät kann mit null oder mehr Quellen konfiguriert werden. Quellen erhalten eine Konfiguration, die sich darauf auswirkt, wie die Medien der Quelle verwendet werden. Das obige Image zeigt vier Bildquellen: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/ivs/latest/LowLatencyUserGuide/broadcast-mixed-devices.html)  | 
| Konfiguration der Quelle |  Ein Konfigurationsobjekt für die Quelle, welche in ein gemischtes Gerät geht. Die vollständigen Konfigurationsobjekte werden unten beschrieben.   | 
| Übergang | Um einen Slot an eine neue Position zu verschieben oder einige seiner Eigenschaften zu ändern, verwenden Sie `MixedDevice.transitionToConfiguration()`. Diese Methode verwendet: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/ivs/latest/LowLatencyUserGuide/broadcast-mixed-devices.html) | 

## Gemischtes Audio-Gerät
<a name="broadcast-mixed-audio-device"></a>

### Konfiguration
<a name="broadcast-mixed-audio-device-configuration"></a>

`MixedAudioDeviceConfiguration` auf Android

`IVSMixedAudioDeviceConfiguration` auf iOS


| Name | Typ | Beschreibung | 
| --- | --- | --- | 
| `channels` | Ganzzahl | Anzahl der Ausgangskanäle des Audiomischers. Gültige Werte: 1 und 2. 1 ist Mono-Audio; 2 Stereo-Audio. Standard: 2 | 

### Konfiguration der Quelle
<a name="broadcast-mixed-audio-device-source-configuration"></a>

`MixedAudioDeviceSourceConfiguration` auf Android

`IVSMixedAudioDeviceSourceConfiguration` auf iOS


| Name | Typ | Beschreibung | 
| --- | --- | --- | 
| `gain` | Gleitkommazahl | Audio-Gain. Dies ist ein Multiplikator, daher erhöht jeder Wert über 1 den Gain; jeder Wert unter 1 verringert ihn. Zulässige Werte: 0 bis 2. Standard: 1  | 

## Gemischtes Bild-Gerät
<a name="broadcast-mixed-image-device"></a>

### Konfiguration
<a name="broadcast-mixed-image-device-configuration"></a>

`MixedImageDeviceConfiguration` auf Android

`IVSMixedImageDeviceConfiguration` auf iOS


| Name | Typ | Beschreibung | 
| --- | --- | --- | 
| `size` | Vec2 | Größe der Video-Bildfläche. | 
| `targetFramerate` | Ganzzahl | Anzahl der Ziel-Frames pro Sekunde für das gemischte Gerät. Im Durchschnitt sollte dieser Wert erreicht werden, aber das System kann unter bestimmten Umständen Frames auslassen (z. B. hohe CPU- oder GPU-Auslastung). | 
| `transparencyEnabled` | Boolesch | Dies ermöglicht das Mischen mithilfe der `alpha`-Eigenschaft in Bildquellenkonfigurationen. Wenn Sie diese Einstellung auf `true` einstellen, erhöht sich der Speicher- und CPU-Verbrauch. Standardwert: `false`. | 

### Konfiguration der Quelle
<a name="broadcast-mixed-image-device-source-configuration"></a>

`MixedImageDeviceSourceConfiguration` auf Android

`IVSMixedImageDeviceSourceConfiguration` auf iOS


| Name | Typ | Beschreibung | 
| --- | --- | --- | 
| `alpha` | Gleitkommazahl | Alpha des Slots. Dies ist multiplikativ mit allen Alpha-Werten im Image. Gültige Werte: 0 bis 1, wobei 0 vollständig undurchsichtig und 1 vollständig transparent ist. Standard: 1 | 
| `aspect` | AspectMode | Aspekt-Ratio-Modus für jedes Image, das im Slot gerendert wird. Zulässige Werte: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/ivs/latest/LowLatencyUserGuide/broadcast-mixed-devices.html) Standardwert: `Fit`  | 
| `fillColor` | Vec4 | Füllfarbe, die mit `aspect Fit` verwendet wird, wenn die Seitenverhältnisse von Slot und Bild nicht übereinstimmen. Das Format ist (rot, grün, blau, alpha). Gültiger Wert (für jeden Kanal): 0 bis 1. Standard: 0.0.0.0 | 
| `position` | Vec2 | Position des Slots (in Pixel) relativ zur linken oberen Ecke der Bildfläche. Der Ursprung des Slots ist ebenfalls oben links. | 
| `size` | Vec2 | Größe des Slots in Pixel. Ein Festlegen dieses Wertes setzt `matchCanvasSize` außerdem auf `false`. Standard: (0, 0); weil `matchCanvasSize` jedoch standardmäßig `true` ist, ist die gerenderte Slotgröße gleich der Bildflächengröße, nicht (0, 0). | 
| `zIndex` | Gleitkommazahl | Relative Reihenfolge der Slots. Slots mit höherem `zIndex`-Wert werden über Slots mit niedrigerem `zIndex`-Wert gelegt. | 

## Erstellen und Konfigurieren eines gemischten Bildgerätes
<a name="broadcast-mixed-image-device-creating-configuring"></a>

![\[Konfigurieren einer Broadcast-Sitzung zum Mischen\]](http://docs.aws.amazon.com/de_de/ivs/latest/LowLatencyUserGuide/images/Broadcast_SDK_Mixer_Configuring.png)


Hier erstellen wir eine Szene, die der am Anfang dieses Handbuchs ähnelt, mit drei Bildschirmelementen:
+ Slot unten links für eine Kamera.
+ Slot unten rechts für eine Logo-Überlagerung.
+ Slot oben rechts für einen Film.

Beachten Sie, dass der Ursprung für die Bildfläche die obere linke Ecke ist und dies für alle Slots gilt. Wenn Sie also einen Slot an (0, 0) positionieren, wird er in die obere linke Ecke gesetzt, wobei der gesamte Slot sichtbar ist.

### iOS
<a name="broadcast-mixed-image-device-creating-configuring-ios"></a>

```
let deviceDiscovery = IVSDeviceDiscovery()
let mixedImageConfig = IVSMixedImageDeviceConfiguration()
mixedImageConfig.size = CGSize(width: 1280, height: 720)
try mixedImageConfig.setTargetFramerate(60)
mixedImageConfig.isTransparencyEnabled = true
let mixedImageDevice = deviceDiscovery.createMixedImageDevice(with: mixedImageConfig)

// Bottom Left
let cameraConfig = IVSMixedImageDeviceSourceConfiguration()
cameraConfig.size = CGSize(width: 320, height: 180)
cameraConfig.position = CGPoint(x: 20, y: mixedImageConfig.size.height - cameraConfig.size.height - 20)
cameraConfig.zIndex = 2
let camera = deviceDiscovery.listLocalDevices().first(where: { $0 is IVSCamera }) as? IVSCamera
let cameraSource = IVSMixedImageDeviceSource(configuration: cameraConfig, device: camera)
mixedImageDevice.add(cameraSource)

// Top Right
let streamConfig = IVSMixedImageDeviceSourceConfiguration()
streamConfig.size = CGSize(width: 640, height: 320)
streamConfig.position = CGPoint(x: mixedImageConfig.size.width - streamConfig.size.width - 20, y: 20)
streamConfig.zIndex = 1
let streamDevice = deviceDiscovery.createImageSource(withName: "stream")
let streamSource = IVSMixedImageDeviceSource(configuration: streamConfig, device: streamDevice)
mixedImageDevice.add(streamSource)

// Bottom Right
let logoConfig = IVSMixedImageDeviceSourceConfiguration()
logoConfig.size = CGSize(width: 320, height: 180)
logoConfig.position = CGPoint(x: mixedImageConfig.size.width - logoConfig.size.width - 20,
                              y: mixedImageConfig.size.height - logoConfig.size.height - 20)
logoConfig.zIndex = 3
let logoDevice = deviceDiscovery.createImageSource(withName: "logo")
let logoSource = IVSMixedImageDeviceSource(configuration: logoConfig, device: logoDevice)
mixedImageDevice.add(logoSource)
```

### Android
<a name="broadcast-mixed-image-device-creating-configuring-android"></a>

```
val deviceDiscovery = DeviceDiscovery(this /* context */)
val mixedImageConfig = MixedImageDeviceConfiguration().apply {
    setSize(BroadcastConfiguration.Vec2(1280f, 720f))
    setTargetFramerate(60)
    setEnableTransparency(true)
}
val mixedImageDevice = deviceDiscovery.createMixedImageDevice(mixedImageConfig)

// Bottom Left
val cameraConfig = MixedImageDeviceSourceConfiguration().apply {
    setSize(BroadcastConfiguration.Vec2(320f, 180f))
    setPosition(BroadcastConfiguration.Vec2(20f, mixedImageConfig.size.y - size.y - 20))
    setZIndex(2)
}
val camera = deviceDiscovery.listLocalDevices().firstNotNullOf { it as? CameraSource }
val cameraSource = MixedImageDeviceSource(cameraConfig, camera)
mixedImageDevice.addSource(cameraSource)

// Top Right
val streamConfig = MixedImageDeviceSourceConfiguration().apply {
    setSize(BroadcastConfiguration.Vec2(640f, 320f))
    setPosition(BroadcastConfiguration.Vec2(mixedImageConfig.size.x - size.x - 20, 20f))
    setZIndex(1)
}
val streamDevice = deviceDiscovery.createImageInputSource(streamConfig.size)
val streamSource = MixedImageDeviceSource(streamConfig, streamDevice)
mixedImageDevice.addSource(streamSource)

// Bottom Right
val logoConfig = MixedImageDeviceSourceConfiguration().apply {
    setSize(BroadcastConfiguration.Vec2(320f, 180f))
    setPosition(BroadcastConfiguration.Vec2(mixedImageConfig.size.x - size.x - 20, mixedImageConfig.size.y - size.y - 20))
    setZIndex(1)
}
val logoDevice = deviceDiscovery.createImageInputSource(logoConfig.size)
val logoSource = MixedImageDeviceSource(logoConfig, logoDevice)
mixedImageDevice.addSource(logoSource)
```

## Entfernen von Quellen
<a name="broadcast-mixed-devices-removing-sources"></a>

Um eine Quelle zu entfernen, rufen Sie `MixedDevice.remove` mit dem `Source`-Objekt auf, das Sie entfernen möchten.

## Animationen mit Übergängen
<a name="broadcast-mixed-devices-animations-transitions"></a>

Die Übergangsmethode ersetzt die Konfiguration einesr Quelle durch eine neue Konfiguration. Dieser Ersatz kann zeitlich animiert werden, indem eine Dauer von mehr als 0 Sekunden festgelegt wird. 

### Welche Eigenschaften können animiert werden?
<a name="broadcast-mixed-devices-animations-properties"></a>

Nicht alle Eigenschaften in der Slot-Struktur können animiert werden. Alle Eigenschaften, die auf Float-Typen basieren, können animiert werden; andere Eigenschaften werden entweder am Anfang oder am Ende der Animation wirksam.


| Name | Kann es animiert werden? | Auswirkungspunkt | 
| --- | --- | --- | 
| `Audio.gain` | Ja | Interpoliert | 
| `Image.alpha` | Ja | Interpoliert | 
| `Image.aspect` | Nein | Ende | 
| `Image.fillColor` | Ja | Interpoliert | 
| `Image.position` | Ja | Interpoliert | 
| `Image.size` | Ja | Interpoliert | 
| `Image.zIndex` Hinweis: `zIndex` verschiebt 2D-Ebenen durch den 3D-Raum, so dass der Übergang stattfindet, wenn sich die beiden Ebenen irgendwann in der Mitte der Animation kreuzen. Dies könnte berechnet werden, hängt aber des `zIndex`-Start- und -Endwertes ab. Kombinieren Sie dies für einen reibungsloseren Übergang mit `alpha`.  | Ja | Unbekannt | 

### Einfache Beispiele:
<a name="broadcast-mixed-devices-animations-examples"></a>

Im Folgenden finden Sie Beispiele für eine Vollbild-Kameraübernahme unter Verwendung der oben unter [Erstellen und Konfigurieren eines gemischten Bildgeräts definierten Konfiguration](#broadcast-mixed-image-device-creating-configuring). Dies wird 0,5 Sekunden lang animiert.

#### iOS
<a name="broadcast-mixed-devices-animations-examples-ios"></a>

```
// Continuing the example from above, modifying the existing cameraConfig object.
cameraConfig.size = CGSize(width: 1280, height: 720)
cameraConfig.position = CGPoint.zero
cameraSource.transition(to: cameraConfig, duration: 0.5) { completed in
    if completed {
        print("Animation completed")
    } else {
        print("Animation interrupted")
    }
}
```

#### Android
<a name="broadcast-mixed-devices-animations-examples-android"></a>

```
// Continuing the example from above, modifying the existing cameraConfig object.
cameraConfig.setSize(BroadcastConfiguration.Vec2(1280f, 720f))
cameraConfig.setPosition(BroadcastConfiguration.Vec2(0f, 0f))
cameraSource.transitionToConfiguration(cameraConfig, 500) { completed ->
    if (completed) {
        print("Animation completed")
    } else {
        print("Animation interrupted")
    }
}
```

## Spiegelung der Übertragung
<a name="broadcast-mixed-devices-mirroring"></a>


| Um ein angeschlossenes Bildgerät in der Übertragung in diese Richtung zu spiegeln ... | Verwenden Sie einen negativen Wert für … | 
| --- | --- | 
| Horizontal | Die Breite des Slots | 
| Vertikal | Die Höhe des Slots | 
| Sowohl horizontal als auch vertikal | Die Slot-Breite und -Höhe | 

Die Position muss um denselben Wert angepasst werden, damit der Slot beim Spiegeln in die richtige Position gebracht wird.

Im Folgenden finden Sie Beispiele für die horizontale und vertikale Spiegelung der Übertragung.

### iOS
<a name="broadcast-mixed-devices-mirroring-ios"></a>

Horizontale Spiegelung:

```
let cameraSource = IVSMixedImageDeviceSourceConfiguration()
cameraSource.size = CGSize(width: -320, height: 720)
// Add 320 to position x since our width is -320
cameraSource.position = CGPoint(x: 320, y: 0)
```

Vertikale Spiegelung:

```
let cameraSource = IVSMixedImageDeviceSourceConfiguration()
cameraSource.size = CGSize(width: 320, height: -720)
// Add 720 to position y since our height is -720
cameraSource.position = CGPoint(x: 0, y: 720)
```

### Android
<a name="broadcast-mixed-devices-mirroring-android"></a>

Horizontale Spiegelung:

```
val cameraConfig = MixedImageDeviceSourceConfiguration().apply {
    setSize(BroadcastConfiguration.Vec2(-320f, 180f))
   // Add 320f to position x since our width is -320f
    setPosition(BroadcastConfiguration.Vec2(320f, 0f))
}
```

Vertikale Spiegelung:

```
val cameraConfig = MixedImageDeviceSourceConfiguration().apply {
    setSize(BroadcastConfiguration.Vec2(320f, -180f))
    // Add 180f to position y since our height is -180f
    setPosition(BroadcastConfiguration.Vec2(0f, 180f))
}
```

Hinweis: Diese Spiegelung unterscheidet sich von der `setMirrored`-Methode in `ImagePreviewView` (Android) und `IVSImagePreviewView` (iOS). Diese Methode wirkt sich nur auf die lokale Vorschauansicht auf dem Gerät aus und hat keine Auswirkungen auf die Übertragung.

# IVS-Broadcast-SDK: Benutzerdefinierte Bildquellen \$1 Streaming mit niedriger Latenz
<a name="broadcast-custom-image-sources"></a>

Dieses Handbuch geht davon aus, dass Sie mit der Einrichtung einer Übertragungssitzung ([Android](broadcast-android.md),[iOS](broadcast-ios.md)) und mit der [Verwendung der Gemischte-Geräte-API](broadcast-mixed-devices.md) vertraut sind.

Benutzerdefinierte Image-Eingabequellen ermöglichen es einer Anwendung, eine eigene Image-Eingabe für das Broadcast-SDK bereitzustellen, anstatt sich auf die voreingestellten Kameras oder die Bildschirmfreigabe zu beschränken. Eine benutzerdefinierte Image-Quelle kann so einfach sein wie ein halbtransparentes Wasserzeichen oder eine statische „Bin gleich zurück“-Szene, oder es kann der App ermöglichen, zusätzliche benutzerdefinierte Verarbeitungen wie das Hinzufügen von Schönheitsfiltern zur Kamera durchzuführen.

Sie können mehrere benutzerdefinierte Image-Quellen haben, wie ein Wasserzeichen sowie eine Kamera mit Schönheitsfiltern. Wenn Sie eine benutzerdefinierte Image-Eingangsquelle zur benutzerdefinierten Steuerung der Kamera verwenden (z. B. die Verwendung von Schönheitsfilter-Bibliotheken, die Kamerazugriff erfordern), ist das Broadcast-SDK nicht mehr für die Verwaltung der Kamera verantwortlich. Stattdessen ist die Anwendung dafür verantwortlich, den Lebenszyklus der Kamera korrekt zu handhaben. Lesen Sie die offizielle Plattformdokumentation darüber, wie Ihre Anwendung die Kamera verwalten soll.

## Android
<a name="custom-image-sources-android"></a>

Erstellen Sie nach dem Erstellen einer Broadcast-Sitzung eine Image-Eingabequelle: 

```
SurfaceSource surfaceSource = broadcastSession.createImageInputSource();
```

Diese Methode gibt ein `SurfaceSource` zurück, welche eine Image-Quelle ist, die von einem Standard-Android-[Surface](https://developer.android.com/reference/android/view/Surface) unterstützt wird. Es wird automatisch an die Broadcast-Sitzung angehängt, sodass Sie die Methode `attachDevice(...)` danach nicht mehr verwenden müssen. Das `SurfaceSource` muss an einen Slot gebunden sein, dies wird weiter unten erläutert. Das `SurfaceSource` kann in der Größe geändert und gedreht werden. Sie können auch ein `ImagePreviewView` erstellen, um eine Vorschau seines Inhalts anzuzeigen.

So rufen Sie das zugrundeliegende ab `Surface`:

```
Surface surface = surfaceSource.getInputSurface();
```

Dieses `Surface` kann als Ausgabepuffer für Image-Produzenten wie Camera2, OpenGL ES und andere Bibliotheken verwendet werden. Der einfachste Anwendungsfall ist das direkte Zeichnen einer statischen Bitmap oder Farbe in den Canvas des Surface. Viele Bibliotheken (wie Schönheitsfilter-Bibliotheken) bieten jedoch eine Methode, mit der eine Anwendung ein externes `Surface` zum Rendern angeben kann. Sie können eine solche Methode verwenden, um dieses `Surface` an die Filterbibliothek zu übergeben, die es der Bibliothek ermöglicht, verarbeitete Frames für das Streamen der Broadcast-Sitzung auszugeben.

Schließlich muss die `SurfaceSource` an ein `Mixer.Slot` gebunden sein, um von der Broadcast-Sitzung gestreamt zu werden:

```
broadcastSession.getMixer().bind(surfaceSource, "customSlot");
```

Der [Android-Beispiel-Code](https://github.com/aws-samples/amazon-ivs-broadcast-android-sample) hat mehrere Beispiele, die eine benutzerdefinierte Image-Quelle auf verschiedene Arten verwenden:
+ Ein halbtransparentes Wasserzeichen wird in der hinzugefügt `MixerActivity`.
+ Eine MP4-Datei wird in der eingefügt `MixerActivity`.
+ Die Utility-Klasse [CameraManager](https://github.com/aws-samples/amazon-ivs-broadcast-android-sample/blob/main/app/src/main/java/com/amazonaws/ivs/basicbroadcast/common/CameraManager.kt) führt die benutzerdefinierte Verwaltung der Gerätekamera mit der Camera2-Methode in der `CustomActivity` durch, die einen einfachen Sepia-Filter anwendet. Dieses Beispiel ist besonders hilfreich, da es zeigt, wie Sie die Kamera verwalten und die benutzerdefinierte `SurfaceSource` der Broadcast-Sitzung an die Kameraaufnahmeanforderung übergeben. Wenn Sie andere externe Bibliotheken verwenden, folgen Sie deren Dokumentation zur Konfiguration der Bibliothek für die Ausgabe an Android `Surface`, bereitgestellt von der Broadcast-Sitzung.

## iOS
<a name="custom-image-sources-ios"></a>

Erstellen Sie nach dem Erstellen der Broadcast-Sitzung eine Image-Eingabequelle:

```
let customSource = broadcastSession.createImageSource(withName: "customSourceName")
```

Diese Methode gibt eine `IVSCustomImageSource` zurück, welche eine Image-Quelle ist, die es der Anwendung ermöglicht, `CMSampleBuffers` manuell abzusenden. Informationen zu unterstützten Pixelformaten finden Sie in der iOS-Broadcast-SDK-Referenz; ein Link zur aktuellsten Version befindet sich in den [Versionshinweisen zu Amazon IVS](release-notes.md) für die neueste Broadcast-SDK-Version. Die Quelle wird nicht automatisch an die Broadcast-Sitzung angehängt, daher müssen Sie die Image-Quelle an die Sitzung anhängen und an einen Slot binden, bevor die Quelle streamen wird:

```
broadcastSession.attach(customSource, toSlotWithName: "customSourceSlot", onComplete: nil)
```

Nachdem die benutzerdefinierte Quelle angehängt und gebunden ist, kann die Anwendung `CMSampleBuffers` direkt zur benutzerdefinierten Quelle absenden. Sie können wählen, ob Sie den `onComplete`-Rückruf verwenden, um damit zu beginnen.

An die benutzerdefinierte Quelle übermittelte Beispiele werden in der Broadcast-Sitzung gestreamt:

```
customSource.onSampleBuffer(sampleBuffer)
```

Verwenden Sie diese Methode zum Streamen von Videos in einem Rückruf. Wenn Sie beispielsweise die Kamera verwenden, kann die Anwendung jedes Mal, wenn ein neuer Beispielpuffer von einer `AVCaptureSession` erhalten wird, den Beispielpuffer an die benutzerdefinierte Image-Quelle weiterleiten. Falls gewünscht, kann die Anwendung eine weitere Verarbeitung (wie einen Schönheitsfilter) anwenden, bevor sie das Beispiel an die benutzerdefinierte Image-Quelle absendet.

Für ein statisches Image muss die Anwendung nach dem ersten Beispiel das Beispiel erneut absenden, wenn die Slot-Bindung der benutzerdefinierten Image-Quelle geändert wird oder die Quelle getrennt und wieder an die Broadcast-Sitzung angehängt wird. Wenn Sie beispielsweise den Slot aus dem Mixer entfernen und dann den Slot zum Mixer hinzufügen, müssen Sie das Beispiel erneut absenden.

Die [iOS-Beispiel-App](https://github.com/aws-samples/amazon-ivs-broadcast-ios-sample) hat mehrere Beispiele, die eine benutzerdefinierte Image-Quelle auf verschiedene Arten verwenden:
+ Ein halbtransparentes Wasserzeichen wird in hinzugefügt `MixerViewController`.
+ Eine MP4-Datei wird in eingefügt `MixerViewController`.
+ Eine CIFilter-Implementierung mit einer Gerätekamera wird in `CustomSourcesViewController` hinzugefügt. Dies ermöglicht es einer Anwendung, eine Gerätekamera unabhängig vom Amazon IVS Broadcast SDK zu verwalten. Sie verwendet `AVCaptureSession`, um ein Image von der Gerätekamera aufzunehmen, das Image mit einer CIFilter-Implementierung zu verarbeiten und `CMSampleBuffers` an `customSource` für Live-Streaming zu übermitteln.