Live Share-Medienfunktionen

Video und Audio sind wichtige Bestandteile der modernen Welt und des Arbeitsplatzes. Wir haben umfangreiches Feedback gehört, dass wir noch mehr tun können, um die Qualität, Barrierefreiheit und den Lizenzschutz für das gemeinsame Ansehen von Videos in Besprechungen zu erhöhen.

Das Live Share SDK ermöglicht eine stabile Mediensynchronisierung für alle HTML-Elemente <video> und <audio> Elemente mit nur wenigen Codezeilen. Durch die Mediensynchronisierung auf der Ebene des Playerstatus und der Transportsteuerelemente können Sie Ansichten und Lizenzen individuell zuweisen und gleichzeitig die bestmögliche Qualität bieten, die über Ihre Anwendung verfügbar ist.

Installieren

Live Share-Medien sind ein JavaScript-Paket, das auf npm veröffentlicht wird und sie über npm oder yarn herunterladen können. Sie müssen auch die Peerabhängigkeiten installieren, zu denen , fluid-framework und @fluidframework/azure-clientgehören@microsoft/live-share. Wenn Sie Live Share in Ihrer Registerkartenanwendung verwenden, müssen Sie auch version 2.11.0 oder höher installieren@microsoft/teams-js.

npm install @microsoft/live-share @microsoft/live-share-media fluid-framework @fluidframework/azure-client --save
npm install @microsoft/teams-js --save

ODER

So fügen Sie die neueste Version des SDK mit Yarn zu Ihrer Anwendung hinzu:

yarn add @microsoft/live-share @microsoft/live-share-media fluid-framework @fluidframework/azure-client
yarn add @microsoft/teams-js

Übersicht über die Mediensynchronisierung

Das Live Share-SDK verfügt über zwei primäre Klassen, die sich auf die Mediensynchronisation beziehen:

Klassen Beschreibung
LiveMediaSession Benutzerdefiniertes Liveobjekt, das entwickelt wurde, um Medientransportsteuerelemente und den Wiedergabezustand in unabhängigen Medienstreams zu koordinieren.
MediaPlayerSynchronizer Synchronisiert jedes Objekt, das die IMediaPlayer -Schnittstelle implementiert , einschließlich HTML5 <video> und <audio> -- mithilfe von LiveMediaSession.

Beispiel:

<body>
  <video id="player">
    <source src="YOUR_VIDEO_SRC" type="video/mp4" />
  </video>
</body>
import {
  LiveShareClient,
  UserMeetingRole,
  MediaPlayerSynchronizerEvents,
} from "@microsoft/live-share";
import { LiveMediaSession } from "@microsoft/live-share-media";
import { LiveShareHost } from "@microsoft/teams-js";

// Setup the Fluid container
const host = LiveShareHost.create();
const liveShare = new LiveShareClient(host);
const schema = {
  initialObjects: { mediaSession: LiveMediaSession },
};
const { container } = await liveShare.joinContainer(schema);
const { mediaSession } = container.initialObjects;

// Get the player from your document and create synchronizer
const player = document.getElementById("player");
const synchronizer = mediaSession.synchronize(player);

// Listen for groupaction events (optional)
synchronizer.addEventListener(MediaPlayerSynchronizerEvents.groupaction, async (evt) => {
  // See which user made the change (e.g., to display a notification)
  const clientInfo = await synchronizer.mediaSession.getClientInfo(evt.details.clientId);
});

// Define roles you want to allow playback control and start sync
const allowedRoles = [UserMeetingRole.organizer, UserMeetingRole.presenter];
await mediaSession.initialize(allowedRoles);

Der LiveMediaSession lauscht automatisch auf Änderungen am Wiedergabezustand der Gruppe. MediaPlayerSynchronizer lauscht auf Zustandsänderungen, die von LiveMediaSession ausgegeben werden, und wendet sie auf das bereitgestellte IMediaPlayer Objekt an, z. B. ein HTML5 <video> - oder <audio> -Element. Um Wiedergabestatusänderungen zu vermeiden, die ein Benutzer nicht absichtlich initiiert hat, z. B. ein Pufferereignis, müssen Transportsteuerelemente über den Synchronizer und nicht direkt über den Player aufgerufen werden.

Beispiel:

<body>
  <video id="player">
    <source src="YOUR_VIDEO_SRC" type="video/mp4" />
  </video>
  <div class="player-controls">
    <button id="play-button">Play</button>
    <button id="pause-button">Pause</button>
    <button id="restart-button">Restart</button>
    <button id="change-track-button">Change track</button>
  </div>
</body>
// ...

document.getElementById("play-button").onclick = async () => {
  // Will play for all users in the session.
  // If using role verification, this will throw an error if the user doesn't have the required role.
  await synchronizer.play();
};

document.getElementById("pause-button").onclick = async () => {
  // Will pause for all users in the session.
  // If using role verification, this will throw an error if the user doesn't have the required role.
  await synchronizer.pause();
};

document.getElementById("restart-button").onclick = async () => {
  // Will seek for all users in the session.
  // If using role verification, this will throw an error if the user doesn't have the required role.
  await synchronizer.seekTo(0);
};

document.getElementById("change-track-button").onclick = () => {
  // Will change the track for all users in the session.
  // If using role verification, this will throw an error if the user doesn't have the required role.
  synchronizer.setTrack({
    trackIdentifier: "SOME_OTHER_VIDEO_SRC",
  });
};

Hinweis

Sie können das LiveMediaSession -Objekt zwar verwenden, um Medien manuell zu synchronisieren, es wird jedoch im Allgemeinen empfohlen, die MediaPlayerSynchronizerzu verwenden. Abhängig von dem Player, den Sie in Ihrer App verwenden, müssen Sie möglicherweise einen Delegat-Shim erstellen, damit die Benutzeroberfläche Ihres Webplayers mit der IMediaPlayer-Schnittstelle übereinstimmt.

Unterbrechungen und Wartepunkte

Screenshot: Anhalten der Synchronisierung mit dem Referenten

Wenn Sie die Synchronisierung für das LiveMediaSession-Objekt vorübergehend anhalten möchten, können Sie Unterbrechungen verwenden. Ein MediaSessionCoordinatorSuspension Objekt ist standardmäßig lokal, was in Fällen hilfreich sein kann, in denen ein Benutzer etwas nachholen möchte, das er verpasst hat, eine Pause einlegen usw. Wenn der Benutzer die Unterbrechung beendet, wird die Synchronisierung automatisch fortgesetzt.

// Suspend the media session coordinator
const suspension = mediaSession.coordinator.beginSuspension();

// End the suspension when ready
suspension.end();

Wenn Sie eine Unterbrechung beginnen, können Sie auch einen optionalen CoordinationWaitPoint-Parameter einfügen, der es den Benutzern ermöglicht, die Zeitstempel zu definieren, in denen eine Unterbrechung für alle Benutzer erfolgen soll. Die Synchronisierung wird erst fortgesetzt, wenn alle Benutzer die Aussetzung für diesen Wartepunkt beenden.

Im Folgenden finden Sie einige Szenarien, in denen Wartepunkte besonders nützlich sind:

  • Hinzufügen eines Quiz oder einer Umfrage an bestimmten Punkten im Video.
  • Warten, bis jeder ein Video angemessen lädt, bevor es gestartet wird oder während der Pufferung.
  • Ermöglichen Sie es einem Referenten, Punkte im Video für gruppendiskssionen auszuwählen.
// Suspend the media session coordinator
const waitPoint = {
  position: 0,
  reason: "ReadyUp", // Optional.
};
const suspension = mediaSession.coordinator.beginSuspension(waitPoint);
// End the suspension when the user readies up
document.getElementById("ready-up-button").onclick = () => {
  // Sync will resume when everyone has ended suspension
  suspension.end();
};

Audio-Ducking

Das Live Share-SDK unterstützt intelligentes Audio-Ducking. Sie können das Feature in Ihrer Anwendung verwenden, indem Sie Ihrem Code Folgendes hinzufügen:

import { meeting } from "@microsoft/teams-js";

// ... set up MediaPlayerSynchronizer

// Register speaking state change handler through Microsoft Teams JavaScript client library (TeamsJS)
let volumeTimer;
meeting.registerSpeakingStateChangeHandler((speakingState) => {
  if (speakingState.isSpeakingDetected && !volumeTimer) {
    // If someone in the meeting starts speaking, periodically
    // lower the volume using your MediaPlayerSynchronizer's
    // VolumeLimiter.
    synchronizer.volumeLimiter?.lowerVolume();
    volumeTimer = setInterval(() => {
      synchronizer.volumeLimiter?.lowerVolume();
    }, 250);
  } else if (volumeTimer) {
    // If everyone in the meeting stops speaking and the
    // interval timer is active, clear the interval.
    clearInterval(volumeTimer);
    volumeTimer = undefined;
  }
});

Fügen Sie ihrem App-Manifest außerdem die folgenden RSC-Berechtigungen hinzu:

{
  // ...rest of your manifest here
  "authorization": {​
    "permissions": {​
      "resourceSpecific": [
        // ...other permissions here​
        {​
          "name": "OnlineMeetingIncomingAudio.Detect.Chat",​
          "type": "Delegated"
        },
        {​
          "name": "OnlineMeetingIncomingAudio.Detect.Group",​
          "type": "Delegated"​
        }​
      ]​
    }​
  }​
}

Hinweis

Die registerSpeakingStateChangeHandler für Audio-Ducking verwendete API funktioniert derzeit nur auf dem Microsoft Teams-Desktop und in den Besprechungstypen "Scheduled" und "Meet Now".

Codebeispiele

Beispielname Beschreibung JavaScript TypeScript
React-Video Einfaches Beispiel, das zeigt, wie das LiveMediaSession-Objekt mit HTML5-Video funktioniert. Anzeigen
React-Medienvorlage Ermöglichen Sie es allen angeschlossenen Clients, Videos gemeinsam anzusehen, eine gemeinsame Wiedergabeliste zu erstellen, zu übertragen, wer die Kontrolle hat und das Video mit Anmerkungen zu versehen. Anzeigen View

Nächster Schritt

Siehe auch