Grabación de audio y captura de pantalla

En esta guía, se explican diferentes enfoques para grabar audio y video desde una pestaña, ventana o pantalla con APIs como chrome.tabCapture o getDisplayMedia()

Grabación de pantalla

Para la grabación de pantalla, llama a getDisplayMedia(), que activa el cuadro de diálogo. que se muestra a continuación. Esto permite al usuario seleccionar la pestaña, ventana o pantalla que desee. compartir y proporciona una indicación clara de que se está grabando.

Diálogo para compartir pantalla para example.com
Diálogo para compartir pantalla para example.com.

En el siguiente ejemplo, se solicita acceso para grabar audio y video.

const stream = await navigator.mediaDevices.getDisplayMedia({ audio: true, video: true });

Si se la llama dentro de un guion de contenido, la grabación finalizará automáticamente cuando el usuario navegue a un nuevo . Para grabar en segundo plano y entre navegaciones, usa un documento fuera de pantalla con el motivo DISPLAY_MEDIA.

Captura de pestañas basada en gestos del usuario

Si llamas a getDisplayMedia(), el navegador muestra un diálogo con el siguiente comando al usuario lo que le gustaría compartir. Sin embargo, en algunos casos, el usuario acaba de hacer clic botón de acción para invocar tu extensión para una pestaña específica y deseas comenzar a capturar la pestaña de inmediato sin este mensaje.

Graba audio y video en segundo plano.

A partir de Chrome 116, puedes llamar a la API de chrome.tabCapture en un service worker para obtener un ID de transmisión después de un gesto del usuario. Esta información puede pasarse a un documento fuera de pantalla para comenzar a grabar.

En tu service worker:

chrome.action.onClicked.addListener(async (tab) => {
  const existingContexts = await chrome.runtime.getContexts({});

  const offscreenDocument = existingContexts.find(
    (c) => c.contextType === 'OFFSCREEN_DOCUMENT'
  );

  // If an offscreen document is not already open, create one.
  if (!offscreenDocument) {
    // Create an offscreen document.
    await chrome.offscreen.createDocument({
      url: 'offscreen.html',
      reasons: ['USER_MEDIA'],
      justification: 'Recording from chrome.tabCapture API',
    });
  }

  // Get a MediaStream for the active tab.
  const streamId = await chrome.tabCapture.getMediaStreamId({
    targetTabId: tab.id
  });

  // Send the stream ID to the offscreen document to start recording.
  chrome.runtime.sendMessage({
    type: 'start-recording',
    target: 'offscreen',
    data: streamId
  });
});

Luego, en el documento fuera de pantalla, haz lo siguiente:

chrome.runtime.onMessage.addListener(async (message) => {
  if (message.target !== 'offscreen') return;
  
  if (message.type === 'start-recording') {
    const media = await navigator.mediaDevices.getUserMedia({
      audio: {
        mandatory: {
          chromeMediaSource: "tab",
          chromeMediaSourceId: message.data,
        },
      },
      video: {
        mandatory: {
          chromeMediaSource: "tab",
          chromeMediaSourceId: message.data,
        },
      },
    });

    // Continue to play the captured audio to the user.
    const output = new AudioContext();
    const source = output.createMediaStreamSource(media);
    source.connect(output.destination);

    // TODO: Do something to recording the MediaStream.
  }
});

Para ver un ejemplo completo, consulta el ejemplo Captura de pestaña: Grabadora.

Graba audio y video en una pestaña nueva

Antes de Chrome 116, no era posible usar la API de chrome.tabCapture en una o consumir un ID de transmisión creado por esa API en un documento fuera de pantalla. Ambos son requisitos del enfoque anterior.

En su lugar, puedes abrir la página de una extensión en una pestaña o ventana nueva, y obtener directamente una transmisión. Definir la propiedad targetTabId para capturar la pestaña correcta

Primero, abre una página de la extensión (quizá en tu ventana emergente o service worker):

chrome.windows.create({ url: chrome.runtime.getURL("recorder.html") });

Luego, haz lo siguiente en la página de tu extensión:

chrome.tabCapture.getMediaStreamId({ targetTabId: tabId }, async (id) => {
  const media = await navigator.mediaDevices.getUserMedia({
    audio: {
      mandatory: {
        chromeMediaSource: "tab",
        chromeMediaSourceId: id,
      },
    },
    video: {
      mandatory: {
        chromeMediaSource: "tab",
        chromeMediaSourceId: id,
      },
    },
  });

  // Continue to play the captured audio to the user.
  const output = new AudioContext();
  const source = output.createMediaStreamSource(media);
  source.connect(output.destination);
});

También puedes usar el enfoque de grabación de pantalla, que te permite grabar en segundo plano usando un documento fuera de pantalla, pero le muestra al usuario un diálogo para seleccionar una pestaña desde una ventana o pantalla para grabar.

Grabar audio en una ventana emergente

Si solo necesitas grabar audio, puedes obtener directamente una transmisión en la ventana emergente de la extensión con chrome.tabCapture.capture Cuando se cierre la ventana emergente, se detendrá la grabación.

chrome.tabCapture.capture({ audio: true }, (stream) => {
  // Continue to play the captured audio to the user.
  const output = new AudioContext();
  const source = output.createMediaStreamSource(stream);
  source.connect(output.destination);

  // TODO: Do something with the stream (e.g record it)
});

Si necesitas que la grabación persista a lo largo de las navegaciones, considera utilizar el enfoque descrito en la sección anterior.

Otras consideraciones

Si quieres obtener más información para grabar una transmisión, consulta la API de MediaRecorder.