Поделиться через


Возможности мультимедиа Live Share

Видео и аудио являются важной частью современного мира и рабочего места. Мы слышали широкие отзывы о том, что мы можем сделать больше, чтобы повысить качество, доступность и защиту лицензий при совместном просмотре видео на собраниях.

Пакет SDK Live Share обеспечивает надежную синхронизацию мультимедиа для любого HTML-кода <video> и <audio> любого элемента с помощью всего нескольких строк кода. Синхронизация мультимедиа на уровне состояния проигрывателя и элементов управления транспортировкой позволяет по отдельности атрибутировать представления и лицензию, обеспечивая при этом максимально возможное качество, доступное через ваше приложение.

Установка

Мультимедиа Live Share — это пакет JavaScript, опубликованный в npm, который можно скачать через npm или yarn. Также необходимо установить его одноранговые зависимости, в том числе @microsoft/live-share, fluid-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

ИЛИ

Чтобы добавить последнюю версию пакета SDK в приложение с помощью Yarn:

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

Общие сведения о синхронизации мультимедиа

Пакет Live Share SDK имеет два основных класса, связанных с синхронизацией мультимедиа:

Классы Описание
LiveMediaSession Пользовательский динамический объект, предназначенный для координации элементов управления транспортировкой мультимедиа и состояния воспроизведения в независимых потоках мультимедиа.
MediaPlayerSynchronizer Синхронизирует любой объект, реализующий IMediaPlayer интерфейс , включая HTML5 <video> и <audio> , с помощью LiveMediaSession.

Пример:

<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. В зависимости от проигрывателя, используемого в приложении, может потребоваться создать оболочку делегата, чтобы интерфейс веб-проигрывателя соответствовал интерфейсу 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();
};

Приглушение звука

Пакет SDK Live Share поддерживает интеллектуальное приглушение звука. Эту функцию можно использовать в приложении, добавив в код следующую команду:

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 и в запланированных типах собраний и собраний meet.

Примеры кода

Название примера Описание JavaScript TypeScript
Видео React Базовый пример, показывающий, как объект LiveMediaSession работает с видео HTML5. Просмотр Н/Д
Шаблон мультимедиа React Разрешите всем подключенным клиентам просматривать видео вместе, создавать общий список воспроизведения, передавать управление и добавлять заметки к видео. Просмотр Просмотр

Следующий этап

См. также