次の方法で共有


Live Share メディア機能

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

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

インストール

Live Share メディアは npm で発行された JavaScript パッケージであり、 npm または yarn を使用してダウンロードできます。 また、ピアの依存関係 ( @microsoft/live-sharefluid-framework@fluidframework/azure-clientを含む) もインストールする必要があります。 タブ アプリケーションで 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を使用して、HTML5 <video><audio>など、IMediaPlayer インターフェイスを実装するオブジェクトを同期します。

例:

<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 () => {
  // Plays for all users in the session.
  // If using role verification, this throws an error if the user doesn't have the required role.
  await synchronizer.play();
};

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

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

document.getElementById("change-track-button").onclick = () => {
  // Changes the track for all users in the session.
  // If using role verification, this throws 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 resumes when everyone ends 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でのみ機能します。

コード サンプル

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

次の手順

関連項目