Live Share メディア機能

ビデオとオーディオは、現代の世界と職場の重要な部分です。 会議でビデオを一緒に視聴する品質、アクセシビリティ、ライセンス保護を向上させるために、さらに多くのことを行うことができるという幅広いフィードバックが寄せられています。

Live Share SDK を使用すると、任意の HTML <video><audio>要素に対して、わずか数行のコードで堅牢なメディア同期が可能になります。 プレイヤーの状態とトランスポート コントロール レイヤーでメディアを同期することにより、アプリで利用できる最高の品質を提供しながら、ビューとライセンスを個別に関連付けることができます。

インストール

Live Share メディアは npm で発行された JavaScript パッケージであり、 npm または yarn を使用してダウンロードできます。 また、ピアの依存関係 (、、 @fluidframework/azure-clientを含む fluid-framework@microsoft/live-share) もインストールする必要があります。 タブ アプリケーションで Live Share を使用している場合は、バージョン2.11.0以降もインストール@microsoft/teams-jsする必要があります。

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

または

Yarn を使用して SDK の最新バージョンをアプリケーションに追加するには:

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

メディア同期の概要

Live Share SDK には、メディア同期に関連する 2 つの主要なクラスがあります。

クラス 説明
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生成された状態の変更をリッスンし、HTML5 <video><audio>要素などの指定されたIMediaPlayerオブジェクトに適用します。 バッファー イベントなど、ユーザーが意図的に開始しなかった再生状態の変更を回避するには、プレイヤーから直接ではなく、シンクロナイザーを通じてトランスポート コントロールを呼び出す必要があります。

例:

<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 インターフェイスと一致するようにデリゲート shim を作成する必要がある場合があります。

一時停止と待機ポイント

発表者への中断同期を示すスクリーンショット。

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"​
        }​
      ]​
    }​
  }​
}

注:

オーディオ ダッキングに使用される API は registerSpeakingStateChangeHandler 、現在、Microsoft Teams デスクトップでのみ機能し、スケジュールされ、会議の種類に対応しています。

コード サンプル

サンプルの名前 説明 JavaScript TypeScript
React ビデオ LiveMediaSession オブジェクトが HTML5 ビデオでどのように動作するかを示す基本的な例。 表示 該当なし
React メディア テンプレート 接続されているすべてのクライアントが一緒にビデオを視聴し、共有プレイリストを作成し、誰が管理しているのかを転送し、ビデオに注釈を付けることができるようにします。 表示 表示

次の手順

関連項目