Live Share 媒体功能

视频和音频是现代世界和工作场所的重要部分。 我们收到了广泛的反馈,即我们可以做更多工作来提高在会议中一起观看视频的质量、可访问性和许可证保护。

Live Share SDK 只需几行代码即可实现任何 HTML <video><audio>元素的可靠媒体同步。 通过在播放器状态和传输控件层同步媒体,可以单独赋予视图和许可证,同时提供通过应用可获得的最高质量。

安装

Live Share 媒体是在 npm 上发布的 JavaScript 包,可以通过 npm 或 yarn 下载。 还必须安装其对等依赖项,其中包括 @microsoft/live-sharefluid-framework@fluidframework/azure-client。 如果在选项卡应用程序中使用 Live Share,则还必须安装 @microsoft/teams-js 版本 2.11.0 或更高版本。

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

OR

若要使用 Yarn 将最新版本的 SDK 添加到应用程序,请执行以下操作:

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

媒体同步概述

Live Share SDK 有两个与媒体同步相关的主类:

课程 说明
LiveMediaSession 自定义实时对象,旨在协调独立媒体流中的媒体传输控件和播放状态。
MediaPlayerSynchronizer 使用 LiveMediaSession同步实现IMediaPlayer接口的任何对象(包括 HTML5 <video><audio> )。

示例:

<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);

自动 LiveMediaSession 侦听组播放状态的更改。 MediaPlayerSynchronizer 侦听 由 LiveMediaSession 发出的状态更改,并将其应用于提供 IMediaPlayer 的对象,例如 HTML5 <video><audio> 元素。 为了避免播放用户未有意启动的状态更改(如缓冲区事件),我们必须通过同步器调用传输控件,而不是直接通过播放器调用传输控件。

示例:

<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",
  });
};

注意

虽然可以使用 LiveMediaSession 对象手动同步媒体,但通常建议使用 MediaPlayerSynchronizer。 根据你在应用中使用的播放器,你可能需要创建一个委托填充码,以使 Web 播放器的界面与 IMediaPlayer 界面匹配。

挂起和等待点

显示暂停同步到演示者的屏幕截图。

如果要暂时挂起 LiveMediaSession 对象的同步,可以使用挂起功能。 MediaSessionCoordinatorSuspension默认情况下,对象是本地对象,这在用户可能想要赶上错过的内容、休息一下等情况时非常有用。 如果用户结束挂起,同步将自动恢复。

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

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

开始挂起时,还可以包含可选的 CoordinationWaitPoint 参数,该参数允许用户定义所有用户应在其中发生挂起的时间戳。 在所有用户结束该等待点的挂起之前,同步不会恢复。

下面是一些等待点特别有用的方案:

  • 在视频中的某些点添加测验或调查。
  • 等待每个人在视频开始前或缓冲时适当加载视频。
  • 允许演示者选择视频中的点进行群组讨论。
// 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();
};

音频闪避

Live Share SDK 支持智能音频闪避。 通过在代码中添加以下内容,可以在应用程序中使用此功能:

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;
  }
});

此外,将以下 RSC 权限添加到应用清单中:

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

注意

用于音频躲避的 registerSpeakingStateChangeHandler API 目前仅适用于 Microsoft Teams 桌面版以及计划会议类型和会议类型。

代码示例

示例名称 Description JavaScript TypeScript
React 视频 显示 LiveMediaSession 对象如何与 HTML5 视频配合使用的基本示例。 View 不适用
React 媒体模板 使所有连接的客户端能够一起观看视频、生成共享播放列表、转移在控制的人,并通过视频进行批注。 View View

后续步骤

另请参阅