Compartir pantalla - Web

Puedes publicar una retransmisión que utilice una captura de pantalla (en lugar de una cámara) como fuente.

Un cliente conectado a la sesión puede suscribirse a una transmisión compartida de pantalla (y verla), del mismo modo que se suscribiría a una transmisión que utilice una cámara como fuente. (No se necesita ninguna extensión del navegador para suscríbase a a un flujo de pantalla compartida).

Importante: A partir de Chrome 72+, Firefox 52+ y Opera 59+, ya no es necesaria una extensión para compartir la pantalla. El navegador solicita al usuario final el acceso a la pantalla como lo haría para acceder a la cámara.

En versiones anteriores de Opera y Chrome, para publicar un vídeo de pantalla compartida, el cliente necesita añadir una extensión que permita publicar flujos de pantalla compartida para su dominio. (Véase Desarrollar una extensión para compartir pantalla.)

Nota: En macOS 10.15+ (Catalina), para publicar un flujo de pantalla compartida el usuario debe conceder al navegador acceso a la pantalla en Preferencias del Sistema de macOS > Seguridad y privacidad > Privacidad > Grabación de pantalla. De lo contrario, el Editor enviará un accessDenied evento.

En Electron, se admite la función de compartir pantalla si el webPreferences.contextIsolation de Electron BrowserWindow se establece en false o si la aplicación utiliza un script de precarga para acceder al capturador de escritorio. Para obtener más información, consulte Cómo habilitar la función de compartir pantalla en Electron.

Actualmente, la publicación de transmisiones en las que se comparte pantalla es no compatible con Safari en iOS o con Safari 12 y versiones anteriores en macOS.

En todos los navegadores compatibles, la publicación de un flujo de pantalla compartida requiere que la página se cargue a través de HTTPS.

Este tema incluye las siguientes secciones:

Inicio rápido

La publicación de vídeos para compartir pantalla es compatible con Chrome, Firefox, Opera, las versiones de Edge basadas en Chromium (versiones 79+) y Safari 13+. Actualmente no compatible con navegadores móviles, Safari 12 y versiones anteriores en macOS. La publicación de un flujo de pantalla compartida solo es compatible cuando la página web se carga a través de HTTPS.

Nota: Para que la función de compartir pantalla sea compatible con versiones anteriores de Chrome y Opera, debes crear una extensión de compartir pantalla. Consulta el siguiente repositorio de GitHub: https://github.com/opentok/screensharing-extensions.

No se necesita ninguna extensión para suscribirse a una transmisión de vídeo con pantalla compartida, lo cual es posible en todos los navegadores compatibles con OpenTok.

Desarrollo de una extensión para compartir pantalla (obsoleta)

Importante: Las extensiones para compartir pantalla no son necesarias en las últimas versiones de Chrome, Firefox y Opera.

Para que la función de compartir pantalla sea compatible con versiones anteriores de Chrome y Opera, debes crear una extensión de compartir pantalla. Consulta el siguiente repositorio de GitHub para ver ejemplos de código de extensiones de compartir pantalla:

https://github.com/opentok/screensharing-extensions

Comprobación de la compatibilidad con la función de compartir pantalla

Para comprobar si la publicación de un flujo de pantalla compartida es compatible con el navegador cliente, llame a la función OT.checkScreenSharingCapability() método. Este método recibe un parámetro: una función de devolución de llamada. A la función de devolución de llamada se le pasa un response Este objeto tiene las siguientes propiedades Este objeto tiene las siguientes propiedades que indican el soporte para publicar flujos de pantalla compartida en el cliente:

  • supported - (Booleano) Indica si se puede compartir.
  • supportedSources— Obsoleto. En versiones anteriores del navegador, se podía seleccionar un tipo de fuente para compartir pantalla (como "application", "screen", o "window" estableciendo el videoSource de las opciones introducidas en el campo OT.initPublisher() método. Sin embargo, en los navegadores actuales que soportan la compartición de pantalla, pasar cualquiera de estos valores resulta en el mismo comportamiento - el navegador muestra un cuadro de diálogo en el que el usuario final selecciona la fuente de compartición de pantalla (que puede ser toda la pantalla o una ventana específica). En Electron, la pantalla compartida captura toda la pantalla, sin pedir permiso al usuario.

El parámetro de opciones también incluye las siguientes propiedades, que se aplican al soporte de pantalla compartida en versiones antiguas de Chrome y Opera, que requieren extensiones de pantalla compartida - en otros navegadores, no están definidas:

  • extensionRequired (Cadena) - Se establece en "chrome" en versiones antiguas de Chrome (anteriores a Chrome 72) y Opera (anteriores a Opera 59), que requieren la instalación de una extensión para compartir pantalla.
  • extensionRegistered (Boolean) - En versiones antiguas de Chrome (anteriores a Chrome 72) y Opera (anteriores a Opera 59), esta propiedad se establece en true si hay alguna extensión de pantalla compartida registrada; en caso contrario, se establece en false. Utilice el OT.registerScreenSharingExtension() para registrar una extensión en Chrome u Opera.
  • extensionInstalled (booleano) - Si se requiere una extensión, se establece en true si la extensión está instalada (y registrada, si es necesario); de lo contrario, se establece en false.

Nota: La función de compartir pantalla solo está disponible cuando la página web se carga a través de HTTPS.

El siguiente ejemplo muestra cómo comprobar la compatibilidad con la pantalla compartida:

OT.checkScreenSharingCapability(function(response) {
  if(!response.supported || response.extensionRegistered === false) {
    // This browser does not support screen sharing
  }
});

Publicar un flujo con una fuente de pantalla compartida

El videoSource del parámetro options del OT.initPublisher() define la fuente de vídeo del flujo que se va a publicar. Para compartir pantalla, establezca esta propiedad en "screen". En versiones anteriores del navegador, también se podía pasar en "application" o "window" para especificar un tipo de fuente de pantalla compartida. Sin embargo, en los navegadores actuales que admiten la función de pantalla compartida, al pasar cualquiera de estos valores se produce el mismo comportamiento: el navegador muestra un cuadro de diálogo en el que el usuario final selecciona la fuente de pantalla compartida (que puede ser toda la pantalla o una ventana concreta). En Electron, la función de compartir pantalla captura toda la pantalla sin solicitar permiso al usuario. En Safari, inicializar un editor de pantalla compartida sin un controlador de acciones del usuario puede provocar un InvalidAccessError error.

El siguiente código muestra cómo publicar una retransmisión que utiliza la función de compartir pantalla como fuente:

<div id="publisher"></div>
<div id="screen-preview"></div>

OT.checkScreenSharingCapability(function(response) {
  if(!response.supported || response.extensionRegistered === false) {
    // This browser does not support screen sharing.
  } else if (response.extensionInstalled === false) {
    // Prompt to install the extension.
  } else {
    // Screen sharing is available. Publish the screen.
    var publisher = OT.initPublisher('screen-preview',
      {videoSource: 'screen'},
      function(error) {
        if (error) {
          // Look at error.message to see what went wrong.
        } else {
          session.publish(publisher, function(error) {
            if (error) {
              // Look error.message to see what went wrong.
            }
          });
        }
      }
    );
  }
});

En caso de error, el gestor de finalización de OT.initPublisher() se le puede pasar un objeto de error con uno de los siguientes códigos de error:

  • 1550 - "No se admite compartir pantalla".
  • 1551 — «Para compartir pantalla se necesita un tipo pero no hay ninguna extensión registrada para tipo."
  • 1552 — «Para compartir pantalla se necesita un tipo «extensión, pero no está instalada».

Cuando se publica un flujo de pantalla compartida, se establecen los siguientes valores por defecto para los parámetros options del OT.initPublisher() método:

  • maxResolution - { width: 1920, height: 1920 }
  • mirror - false
  • fitMode - "contain"
  • publishAudio - false

Además, los suscriptores del flujo resultante también utilizan por defecto el "contain" fitMode ajuste.

Para obtener información sobre maxResolution y fitModeconsulte las dos secciones siguientes.

Por defecto, vídeo escalable está desactivado para los flujos de pantalla compartida. Puede activar el vídeo escalable para los flujos de pantalla compartida configurando el parámetro scalableScreenshare opción para el OT.initPublisher() método. Nota: vídeo escalable para flujos de pantalla compartida es un beta característica.

Configuración de la resolución máxima de la transmisión

Puedes configurar un maxResolution cuando llame a la propiedad OT.initPublisher() método. Esta propiedad establece la resolución máxima del flujo. Cuando se comparte una ventana, la resolución del flujo coincidirá con las dimensiones de la ventana a menos que la ventana sea mayor que la propiedad maxResolution ajuste (cuando el usuario cambia el tamaño de la ventana).

El maxResolution es un objeto con dos propiedades: width y height. El valor máximo de cada uno es 1920 y el mínimo, 10.

var publishOptions = {};
publishOptions.maxResolution = { width: 1920, height: 1080 };
publishOptions.videoSource = 'screen';
OT.initPublisher('some-element-id', publishOptions);

Para compartir pantalla, no configure la opción resolution opción para el OT.initPublisher() método.

Es posible que no desee mostrar el vídeo de pantalla compartida en el DOM HTML de la página desde la que lo publica. Por ejemplo, si está compartiendo toda la pantalla e incluye el vídeo en el DOM HTML, verá un efecto recursivo de "sala de espejos". Para evitarlo, cree un elemento HTML DOM para el elemento editor y no muestre el elemento en el HTML DOM:

var publishOptions = {videoSource: 'screen'};
var screenPublisherElement = document.createElement('div');
OT.initPublisher(screenPublisherElement, publishOptions);

Recortar o aplicar el formato «letterbox» a los vídeos compartidos en pantalla

Puedes configurar un fitMode propiedad del options que se pasa al parámetro OT.initPublisher() y Session.subscribe() métodos. El sitio fitMode determina cómo se muestra el vídeo si sus dimensiones no coinciden con las del elemento DOM. Puede establecer esta propiedad en uno de los siguientes valores:

  • "cover" - El vídeo se recorta si sus dimensiones no coinciden con las del elemento DOM. Esta es la configuración predeterminada para los vídeos que publican un feed de cámara.
  • "contain" - El vídeo aparece en buzón si sus dimensiones no coinciden con las del elemento DOM. Esta es la configuración predeterminada para los vídeos de pantalla compartida.

Determinar el tipo de vídeo ("pantalla" o "cámara") para un flujo

El objeto Stream contiene un videoType propiedad. Se puede establecer en uno de los siguientes valores

  • "camera" — una transmisión de vídeo estándar que utiliza una cámara como fuente de vídeo
  • "screen" - un flujo de vídeo de pantalla compartida
  • "custom" - un flujo publicado por un cliente web que utiliza un elemento HTML VideoTrack como fuente de vídeo
  • undefined - un flujo es sólo de voz (véase el Guía solo de voz)

Esta propiedad puede cambiar si un flujo publicado desde un dispositivo móvil cambia de un tipo de vídeo de cámara a uno de pantalla compartida. Cuando cambia el tipo de vídeo, el objeto Session envía un comando streamPropertyChanged evento.

El siguiente código se suscribe a streams y los añade a diferentes elementos contenedores HTML DIV, en función del tipo de vídeo:

<div id="people"></div>
<div id="screens"></div>

session.on('streamCreated', function(event) {
  var subOptions = {insertMode: 'append'};
  if(event.stream.videoType === 'screen') {
    session.subscribe(event.stream, 'screens', subOptions);
  } else {
    session.subscribe(event.stream, 'people', subOptions);
  }
});

Detectar cuándo cambian las dimensiones del vídeo

Tanto el objeto «Publisher» que está transmitiendo una sesión compartida de pantalla como el objeto «Subscriber» que está suscrito a dicha sesión pueden enviar un videoDimensionsChanged evento. Este evento se activa cuando el cliente emisor cambia el tamaño de una ventana que se está compartiendo.

El videoDimensionsChanged El evento tiene las siguientes propiedades:

  • newValue — Un objeto con las propiedades «width» y «height» que definen la nueva anchura y altura del vídeo.
  • oldValue - Un objeto con propiedades de anchura y altura que definen la anchura y altura previas del vídeo.
  • target - El objeto Editor o Abonado.

Puedes utilizar el newValue.width y newValue.height para ajustar el tamaño del editor en el DOM HTML:

var publisher = OT.initPublisher('some-element',
  {videoSource: 'screen'});

publisher.on('videoDimensionsChanged', function(event) {
  publisher.element.style.width = event.newValue.width + 'px';
  publisher.element.style.height = event.newValue.height + 'px';
});

Determinar cuándo el usuario deja de compartir la pantalla

Cuando el usuario deja de compartir la pantalla, el objeto Editor envía un comando mediaStopped evento.

Si el Editor también estaba publicando el flujo en una sesión, también enviará un evento streamDestroyed con la propiedad reason con el valor "mediaStopped". Además, el objeto «Session» de todos los clientes conectados a la sesión envía un streamDestroyed evento con el reason con el valor "mediaStopped".

El comportamiento predeterminado tanto para el mediaStopped y el evento streamDestroyed es eliminar el editor (o el suscriptor en el caso de un flujo suscrito). Llame al evento preventDefault() método del objeto de evento para evitar que se elimine el editor o el suscriptor.

publisher.on('mediaStopped', function(event) {
  // The user clicked stop.
});

publisher.on('streamDestroyed', function(event) {
  if (event.reason === 'mediaStopped') {
    // User clicked stop sharing
  } else if (event.reason === 'forceUnpublished') {
    // A moderator forced the user to stop sharing.
  }
});

Suscribirse a las retransmisiones con pantalla compartida

Puede suscribirse a una transmisión que utilice una fuente de vídeo de pantalla compartida del mismo modo que se suscribe a una transmisión que utiliza una cámara como fuente. Consulte Suscripción a flujos.

Puede detectar que un flujo es un flujo de pantalla compartida, comprobando la opción videoType Propiedad del objeto Stream. En el caso de una transmisión para compartir pantalla, esta propiedad se establece en «screen».

El siguiente código se suscribe a las transmisiones y las añade a diferentes elementos contenedores del DOM HTML, en función del tipo de vídeo («pantalla» o «cámara»):

session.on('streamCreated', function(event) {
  var subOptions = {
    appendMode: 'append'
  };

  var parentElementId = event.stream.videoType === 'screen' ?
    'sub-screen-sharing-container' :
    'sub-camera-container';
  subscriber = session.subscribe(event.stream, parentElement, subOptions);
});

Las dimensiones de una transmisión compartida de pantalla pueden variar si el usuario que la publica cambia el tamaño de la ventana que sirve de fuente para la transmisión. Cuando cambian las dimensiones del vídeo, el objeto «Subscriber» envía un videoDimensionsChanged evento.

El siguiente código ajusta el tamaño de un suscriptor cuando cambian las dimensiones del vídeo de la transmisión:

subscriber.on('videoDimensionsChanged', function(event) {
  subscriber.element.style.width = event.newValue.width + 'px';
  subscriber.element.style.height = event.newValue.height + 'px';
  // You may want to adjust other UI.
});

Cómo habilitar la función de compartir pantalla en Electron

En Electron, se admite la función de compartir pantalla si el webPreferences.contextIsolation de Electron BrowserWindow se establece en false o si la aplicación utiliza un script de precarga para acceder al capturador de escritorio. El valor predeterminado de webPreferences.contextIsolation es la opción true en Electrón 12+ y false en versiones anteriores. En Electron 17+, un cambio que afecta a la compatibilidad que hacía que la pantalla compartida sólo estuviera disponible tras utilizar un script de precarga.

Cómo habilitar el uso compartido de pantalla mediante un script de precarga en las versiones 12 a 16 de Electron

Para habilitar la pantalla compartida en las versiones Electron 12-16 utilizando un script de precarga, añada lo siguiente al archivo preload.js:

const {
  contextBridge,
  desktopCapturer
} = require('electron');
// Expose the desktopCapturer so that OpenTok.js can access it
// via window.electron.desktopCapturer
contextBridge.exposeInMainWorld(
  'electron', {
    desktopCapturer,
  }
);

A continuación, incluye la referencia a preload.js al instanciar un BrowserWindow en Electron:

mainWindow = new BrowserWindow({
  webPreferences: {
    nodeIntegration: true,
    preload: path.join(__dirname, 'preload.js'), // use the preload script
  }
});

Cómo habilitar el uso compartido de pantalla mediante un script de precarga en las versiones 17 y posteriores de Electron

Para habilitar la pantalla compartida en las versiones 17+ de Electron, añade lo siguiente al archivo preload.js:


const {
  contextBridge,
  ipcRenderer
} = require('electron');

// Event emitter to send asynchronous messages to the main process. The
// corresponding ipcMain handler listens for the 'DESKTOP_CAPTURER_GET_SOURCES'
// channel and returns an array of the available DesktopCapturerSource objects.
const desktopCapturer = {
  getSources: (opts) => ipcRenderer.invoke('DESKTOP_CAPTURER_GET_SOURCES', opts)
};

// Expose desktopCapturer so that the SDK can access it.
contextBridge.exposeInMainWorld(
  'electron', {
    desktopCapturer
  }
);

A continuación, incluye la referencia a preload.js al instanciar un BrowserWindow en Electron:


// Event emitter to handle messages sent from the renderer process. This handler
// will be called whenever a renderer calls
// ipcRenderer.invoke('DESKTOP_CAPTURER_GET_SOURCES', ...args)
electron.ipcMain.handle(
  'DESKTOP_CAPTURER_GET_SOURCES',
  (event, opts) => electron.desktopCapturer.getSources(opts)
);

mainWindow = new BrowserWindow({
  webPreferences: {
    preload: path.join(__dirname, 'preload.js') // use a preload script
  }
});

Optimización del rendimiento de vídeo de determinadas transmisiones con pantalla compartida

Puede definir una sugerencia de contenido de vídeo para mejorar la calidad y el rendimiento de un vídeo para compartir pantalla que contenga principalmente texto o vídeo. Para más información, consulte Configuración de sugerencias de contenido de vídeo para mejorar el rendimiento del vídeo en determinadas situaciones.