

# Mit dem IVS Web Broadcast SDK veröffentlichen und abonnieren
<a name="getting-started-pub-sub-web"></a>

Dieser Abschnitt führt Sie durch die Schritte zur Veröffentlichung und zum Abonnieren einer Stage mithilfe Ihrer Web-App.

## HTML-Boilerplate erstellen
<a name="getting-started-pub-sub-web-html"></a>

Lassen Sie uns zunächst das HTML-Boilerplate erstellen und die Bibliothek als Script-Tag importieren:

```
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  <!-- Import the SDK -->
  <script src="https://web-broadcast.live-video.net/1.33.0/amazon-ivs-web-broadcast.js"></script>
</head>

<body>

<!-- TODO - fill in with next sections -->
<script src="./app.js"></script>

</body>
</html>
```

## Token-Eingabe akzeptieren und Schaltflächen zum Beitritten/Verlassen hinzufügen
<a name="getting-started-pub-sub-web-join"></a>

Hier füllen wir den Hauptteil mit unseren Eingabekontrollen aus. Diese nehmen das Token als Eingabe und richten Schaltflächen für **Beitreten** und **Verlassen** ein. Normalerweise fordern Anwendungen das Token von der API Ihrer Anwendung an, aber in diesem Beispiel kopieren Sie das Token und fügen es in die Token-Eingabe ein.

```
<h1>IVS Real-Time Streaming</h1>
<hr />

<label for="token">Token</label>
<input type="text" id="token" name="token" />
<button class="button" id="join-button">Join</button>
<button class="button" id="leave-button" style="display: none;">Leave</button>
<hr />
```

## Mediencontainer-Elemente hinzufügen
<a name="getting-started-pub-sub-web-media"></a>

Diese Elemente werden die Medien für unsere lokalen und externen Teilnehmer bereitstellen. Wir fügen ein Script-Tag hinzu, um die in `app.js` definierte Logik unserer Anwendung zu laden.

```
<!-- Local Participant -->
<div id="local-media"></div>

<!-- Remote Participants -->
<div id="remote-media"></div>

<!-- Load Script -->
<script src="./app.js"></script>
```

Damit ist die HTML-Seite fertig. Sie sollten sie sehen, wenn Sie `index.html` in einem Browser laden:

![\[Echtzeit-Streaming in einem Browser anzeigen: Die HTML-Setup ist abgeschlossen.\]](http://docs.aws.amazon.com/de_de/ivs/latest/RealTimeUserGuide/images/RT_Browser_View.png)


## Erstellen von app.js
<a name="getting-started-pub-sub-web-appjs"></a>

Gehen wir zur Definition des Inhalts unserer `app.js`-Datei. Importieren Sie zunächst alle erforderlichen Eigenschaften aus der globalen Version des SDK:

```
const {
  Stage,
  LocalStageStream,
  SubscribeType,
  StageEvents,
  ConnectionState,
  StreamType
} = IVSBroadcastClient;
```

## Anwendungsvariablen erstellen
<a name="getting-started-pub-sub-web-vars"></a>

Erstellen Sie Variablen, um Verweise auf unsere HTML-Elemente für die Schaltflächen **Beitreten** und **Verlassen** zu speichern und den Status für die Anwendung zu speichern:

```
let joinButton = document.getElementById("join-button");
let leaveButton = document.getElementById("leave-button");

// Stage management
let stage;
let joining = false;
let connected = false;
let localCamera;
let localMic;
let cameraStageStream;
let micStageStream;
```

## JoinStage 1 erstellen: Definieren Sie die Funktion und validieren Sie die Eingabe
<a name="getting-started-pub-sub-web-joinstage1"></a>

Die Funktion `joinStage` nimmt das Eingabe-Token, stellt eine Verbindung zur Stage her und beginnt mit der Veröffentlichung von Video- und Audiodaten, die von `getUserMedia` empfangen werden.

Zu Beginn definieren wir die Funktion und validieren den Status und die Token-Eingabe. Wir werden diese Funktion in den nächsten Abschnitten näher erläutern.

```
const joinStage = async () => {
  if (connected || joining) {
    return;
  }
  joining = true;

  const token = document.getElementById("token").value;

  if (!token) {
    window.alert("Please enter a participant token");
    joining = false;
    return;
  }

  // Fill in with the next sections
};
```

## JoinStage 2 erstellen: Medien zum Veröffentlichen abrufen
<a name="getting-started-pub-sub-web-joinstage2"></a>

Hier sind die Medien, die auf der Stage veröffentlicht werden:

```
async function getCamera() {
  // Use Max Width and Height
  return navigator.mediaDevices.getUserMedia({
    video: true,
    audio: false
  });
}

async function getMic() {
  return navigator.mediaDevices.getUserMedia({
    video: false,
    audio: true
  });
}

// Retrieve the User Media currently set on the page
localCamera = await getCamera();
localMic = await getMic();

// Create StageStreams for Audio and Video
cameraStageStream = new LocalStageStream(localCamera.getVideoTracks()[0]);
micStageStream = new LocalStageStream(localMic.getAudioTracks()[0]);
```

## JoinStage 3 erstellen: Definieren Sie die Stagestrategie und erstellen Sie die Stage
<a name="getting-started-pub-sub-web-joinstage3"></a>

Diese Stagestrategie ist das Herzstück der Entscheidungslogik, anhand derer das SDK entscheidet, was veröffentlicht und welche Teilnehmer abonniert werden sollen. Weitere Informationen zum Zweck der Funktion finden Sie unter [Strategie](web-publish-subscribe.md#web-publish-subscribe-concepts-strategy).

Diese Strategie ist einfach. Nachdem Sie die Stage betreten haben, veröffentlichen Sie die soeben abgerufenen Streams und abonnieren die Audio- und Videodaten aller Remote-Teilnehmer:

```
const strategy = {
  stageStreamsToPublish() {
    return [cameraStageStream, micStageStream];
  },
  shouldPublishParticipant() {
    return true;
  },
  shouldSubscribeToParticipant() {
    return SubscribeType.AUDIO_VIDEO;
  }
};

stage = new Stage(token, strategy);
```

## JoinStage 4 erstellen: Stageereignisse verarbeiten und Medien rendern
<a name="getting-started-pub-sub-web-joinstage4"></a>

Stages geben viele Ereignisse ab. Wir müssen auf die `STAGE_PARTICIPANT_STREAMS_ADDED` und `STAGE_PARTICIPANT_LEFT` hören, um Medien auf und von der Seite zu rendern und zu entfernen. Eine umfassendere Reihe von Ereignissen finden Sie unter [Ereignisse](web-publish-subscribe.md#web-publish-subscribe-concepts-events).

Beachten Sie, dass wir hier vier Hilfsfunktionen erstellen, die uns bei der Verwaltung der erforderlichen DOM-Elemente unterstützen:`setupParticipant`, `teardownParticipant`, `createVideoEl` und `createContainer`.

```
stage.on(StageEvents.STAGE_CONNECTION_STATE_CHANGED, (state) => {
  connected = state === ConnectionState.CONNECTED;

  if (connected) {
    joining = false;
    joinButton.style = "display: none";
    leaveButton.style = "display: inline-block";
  }
});

stage.on(
  StageEvents.STAGE_PARTICIPANT_STREAMS_ADDED,
  (participant, streams) => {
    console.log("Participant Media Added: ", participant, streams);

    let streamsToDisplay = streams;

    if (participant.isLocal) {
      // Ensure to exclude local audio streams, otherwise echo will occur
      streamsToDisplay = streams.filter(
        (stream) => stream.streamType === StreamType.VIDEO
      );
    }

    const videoEl = setupParticipant(participant);
    streamsToDisplay.forEach((stream) =>
      videoEl.srcObject.addTrack(stream.mediaStreamTrack)
    );
  }
);

stage.on(StageEvents.STAGE_PARTICIPANT_LEFT, (participant) => {
  console.log("Participant Left: ", participant);
  teardownParticipant(participant);
});


// Helper functions for managing DOM

function setupParticipant({ isLocal, id }) {
  const groupId = isLocal ? "local-media" : "remote-media";
  const groupContainer = document.getElementById(groupId);

  const participantContainerId = isLocal ? "local" : id;
  const participantContainer = createContainer(participantContainerId);
  const videoEl = createVideoEl(participantContainerId);

  participantContainer.appendChild(videoEl);
  groupContainer.appendChild(participantContainer);

  return videoEl;
}

function teardownParticipant({ isLocal, id }) {
  const groupId = isLocal ? "local-media" : "remote-media";
  const groupContainer = document.getElementById(groupId);
  const participantContainerId = isLocal ? "local" : id;

  const participantDiv = document.getElementById(
    participantContainerId + "-container"
  );
  if (!participantDiv) {
    return;
  }
  groupContainer.removeChild(participantDiv);
}

function createVideoEl(id) {
  const videoEl = document.createElement("video");
  videoEl.id = id;
  videoEl.autoplay = true;
  videoEl.playsInline = true;
  videoEl.srcObject = new MediaStream();
  return videoEl;
}

function createContainer(id) {
  const participantContainer = document.createElement("div");
  participantContainer.classList = "participant-container";
  participantContainer.id = id + "-container";

  return participantContainer;
}
```

## JoinStage 5 erstellen: Treten Sie der Stage bei
<a name="getting-started-pub-sub-web-joinstage5"></a>

Vervollständigen wir unsere Funktion `joinStage` , indem Sie endlich die Stage betreten\$1

```
try {
  await stage.join();
} catch (err) {
  joining = false;
  connected = false;
  console.error(err.message);
}
```

## LeaveStage erstellen
<a name="getting-started-pub-sub-web-leavestage"></a>

Definieren Sie die `leaveStage`-Funktion, die die Verlassen-Schaltfläche aufrufen wird.

```
const leaveStage = async () => {
  stage.leave();

  joining = false;
  connected = false;
};
```

## Input-Event-Handler initialisieren
<a name="getting-started-pub-sub-web-handlers"></a>

Wir fügen eine letzte Funktion zu unserer `app.js`-Datei hinzu. Diese Funktion wird sofort aufgerufen, wenn die Seite geladen wird, und richtet Event-Handler für den Beitritt und das Verlassen der Stage ein.

```
const init = async () => {
  try {
    // Prevents issues on Safari/FF so devices are not blank
    await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
  } catch (e) {
    alert(
      "Problem retrieving media! Enable camera and microphone permissions."
    );
  }

  joinButton.addEventListener("click", () => {
    joinStage();
  });

  leaveButton.addEventListener("click", () => {
    leaveStage();
    joinButton.style = "display: inline-block";
    leaveButton.style = "display: none";
  });
};

init(); // call the function
```

## Führen Sie die Anwendung aus und geben Sie ein Token an
<a name="getting-started-pub-sub-run-app"></a>

Jetzt können Sie die Webseite lokal oder mit anderen teilen, [die Seite öffnen](#getting-started-pub-sub-web-media), ein Teilnehmer-Token eingeben und der Stage beitreten.

## Die nächsten Themen
<a name="getting-started-pub-sub-next"></a>

Ausführlichere Beispiele für npm, React und mehr finden Sie in [IVS-Broadcast-SDK: Web-Leitfaden (Anleitung zu Echtzeit-Streaming)](broadcast-web.md).