En esta guía, se explican diferentes enfoques para grabar audio y video desde una pestaña, una ventana o una pantalla con APIs como browser.tabCapture o getDisplayMedia().
Grabación de pantalla
Para grabar la pantalla, llama a getDisplayMedia(), lo que activa el cuadro de diálogo que se muestra a continuación. Esto le permite al usuario seleccionar la pestaña, la ventana o la pantalla que desea compartir, y le indica claramente que se está realizando una grabación.
En el siguiente ejemplo, se solicita acceso para grabar audio y video.
const stream = await navigator.mediaDevices.getDisplayMedia({ audio: true, video: true });
Si se llama desde una secuencia de comandos de contenido, la grabación finalizará automáticamente cuando el usuario navegue a una página nueva. Para grabar en segundo plano y en todas las navegaciones, usa un documento fuera de pantalla con el motivo DISPLAY_MEDIA.
Captura de pestañas basada en el gesto del usuario
La llamada a getDisplayMedia() hace que el navegador muestre un diálogo en el que se le pregunta al usuario qué desea compartir. Sin embargo, en algunos casos, el usuario acaba de hacer clic en el botón de acción para invocar tu extensión en una pestaña específica, y te gustaría 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 browser.tabCapture en un service worker para obtener un ID de transmisión después del gesto del usuario. Luego, se puede pasar a un documento fuera de pantalla para iniciar la grabación.
En tu service worker:
browser.action.onClicked.addListener(async (tab) => {
const existingContexts = await browser.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 browser.offscreen.createDocument({
url: 'offscreen.html',
reasons: ['USER_MEDIA'],
justification: 'Recording from browser.tabCapture API',
});
}
// Get a MediaStream for the active tab.
const streamId = await browser.tabCapture.getMediaStreamId({
targetTabId: tab.id
});
// Send the stream ID to the offscreen document to start recording.
browser.runtime.sendMessage({
type: 'start-recording',
target: 'offscreen',
data: streamId
});
});
Luego, en tu documento fuera de pantalla, haz lo siguiente:
browser.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 record the MediaStream.
}
});
Para ver un ejemplo completo, consulta la muestra de Tab Capture - Recorder.
Graba audio y video en una pestaña nueva
Antes de Chrome 116, no era posible usar la API de browser.tabCapture en un service worker ni consumir un ID de transmisión creado por esa API en un documento fuera de pantalla. Ambos son requisitos para el enfoque anterior.
En cambio, puedes abrir una página de extensión en una pestaña o ventana nuevas y obtener una transmisión directamente. Establece la propiedad targetTabId para capturar la pestaña correcta.
Para comenzar, abre una página de extensión (quizás en tu ventana emergente o service worker):
browser.windows.create({ url: browser.runtime.getURL("recorder.html") });
Luego, en la página de la extensión, haz lo siguiente:
browser.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);
});
Como alternativa, considera usar el enfoque de grabación de pantalla, que te permite grabar en segundo plano con un documento fuera de la pantalla, pero le muestra al usuario un diálogo para seleccionar una pestaña, una ventana o una pantalla desde la cual grabar.
Graba 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 browser.tabCapture.capture. Cuando se cierre la ventana emergente, se detendrá la grabación.
browser.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 en las navegaciones, considera usar el enfoque que se describe en la sección anterior.
Otras consideraciones
Para obtener más información sobre cómo grabar una transmisión, consulta la API de MediaRecorder.