Compartilhar via


Recursos de mídia do Live Share

Vídeo e áudio são partes fundamentais do local de trabalho e do mundo modernos. Ouvimos comentários abrangentes de que podemos fazer mais para aumentar a qualidade, a acessibilidade e as proteções de licenças de visualização de vídeos em reuniões.

O SDK live share permite uma sincronização de multimédia robusta para qualquer HTML <video> e <audio> elemento com apenas algumas linhas de código. Ao sincronizar a mídia na camada de controles de transporte e estado do player, você pode atribuir visualizações e licenças individualmente, fornecendo a mais alta qualidade possível disponível por meio do seu aplicativo.

Instalar

O live share media é um pacote JavaScript publicado no npm e pode transferir através de npm ou yarn. Também tem de instalar as respetivas dependências de elemento da rede, que incluem @microsoft/live-share, fluid-framework e @fluidframework/azure-client. Se estiver a utilizar o Live Share na sua aplicação de separador, também tem de instalar @microsoft/teams-js a versão 2.11.0 ou posterior.

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

OU

Para adicionar a versão mais recente do SDK ao seu aplicativo usando Yarn:

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

Visão geral da sincronização de mídia

O SDK do Live Share tem duas classes principais relacionadas à sincronização de mídia:

Aulas Descrição
LiveMediaSession Objeto dinâmico personalizado concebido para coordenar controlos de transporte de multimédia e estado de reprodução em fluxos de multimédia independentes.
MediaPlayerSynchronizer Sincroniza qualquer objeto que implemente a IMediaPlayer interface , incluindo HTML5 <video> e <audio> , com LiveMediaSession.

Exemplo:

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

O LiveMediaSession escuta automaticamente as alterações ao estado de reprodução do grupo. MediaPlayerSynchronizer escuta as alterações de estado emitidas pelo LiveMediaSession e aplica-as ao objeto fornecido IMediaPlayer , como um HTML5 <video> ou <audio> elemento. Para evitar alterações de estado de reprodução que um usuário não iniciou intencionalmente, como um evento de buffering, devemos invocar os controles de transporte por meio do sincronizador, em vez de fazê-lo diretamente por meio do player.

Exemplo:

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

Observação

Embora possa utilizar o LiveMediaSession objeto para sincronizar o suporte de dados manualmente, geralmente é recomendável utilizar o MediaPlayerSynchronizer. Dependendo do jogador que utiliza na sua aplicação, poderá ter de criar um shim delegado para que a interface do seu leitor Web corresponda à interface do IMediaPlayer .

Suspensões e pontos de espera

Captura de ecrã a mostrar uma sincronização de suspensão com o apresentador.

Se quiser suspender temporariamente a sincronização do objeto LiveMediaSession, você pode usar as suspensões. Um MediaSessionCoordinatorSuspension objeto é local por predefinição, o que pode ser útil nos casos em que um utilizador possa querer recuperar algo que perdeu, fazer uma pausa e assim sucessivamente. Se o usuário terminar a suspensão, a sincronização será retomada automaticamente.

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

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

Ao iniciar uma suspensão, você também pode incluir um parâmetro CoordinationWaitPoint opcional que permita que os usuários definam carimbos de data/hora nos quais uma suspensão deve ocorrer para todos os usuários. A sincronização não é retomada até que todos os utilizadores acabem com a suspensão desse ponto de espera.

Eis alguns cenários em que os pontos de espera são especialmente úteis:

  • Adicionar um questionário ou inquérito em determinados pontos do vídeo.
  • A aguardar que todos carreguem adequadamente um vídeo antes de iniciar ou durante a colocação em memória intermédia.
  • Permitir que um apresentador escolha pontos no vídeo para debate de grupo.
// 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();
};

Redução de volume do áudio

O SDK do Live Share é compatível com a redução inteligente do volume de áudio. Pode utilizar a funcionalidade na sua aplicação ao adicionar o seguinte ao código:

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

Além disso, adicione as seguintes permissões RSC ao manifesto da aplicação:

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

Observação

A registerSpeakingStateChangeHandler API utilizada para utilização de chamadas de áudio só funciona no ambiente de trabalho do Microsoft Teams e em tipos de reuniões agendadas e agora em reunião.

Exemplos de código

Nome do exemplo Descrição JavaScript TypeScript
Vídeo de React Exemplo básico que mostra como o objeto LiveMediaSession funciona com vídeo HTML5. Exibir NA
Modelo de mídia de React Permita que todos os clientes conectados assistam a vídeos juntos, criem uma playlist compartilhada, transfiram quem está no controle e façam anotações no vídeo. View View

Próxima etapa

Confira também