Screen Recorder: recording microphone and the desktop audio at the same time

Tengo el objetivo de construir el software de grabación de pantalla más simple del mundo y he estado dando vueltas lentamente sobre el proyecto durante los últimos meses (quiero decir, muy lentamente).

En publicaciones anteriores, obtuve el screen recording and a voice overlay al analizar las transmisiones de todas las fuentes de entrada. Sin embargo, un área de frustración fue que no pude resolver cómo obtener el audio del escritorio * y * superponer el audio del altavoz. Finalmente resolví cómo hacerlo.

En primer lugar, getDisplayMedia en Chrome ahora permite la captura de audio, parece que hay un descuido extraño en la Especificación, ya que no le permitió especificar audio: true en la llamada de función, ahora puede audio: true .

const audio = audioToggle.checked || false;
desktopStream = await navigator.mediaDevices.getDisplayMedia({ video:true, audio: audio });

En segundo lugar, originalmente pensé que al crear dos pistas en la secuencia de audio podría obtener lo que quería, sin embargo, aprendí que la API MediaRecorder de Chrome solo puede generar una pista y, en segundo lugar, no habría funcionado de todos modos porque las pistas son como las múltiples pistas de audio de DVD en las que solo una puede reproducirse a la vez.

La solución es probablemente simple para muchas personas, pero era nueva para mí: usar Web Audio.

Resulta que WebAudio API tiene createMediaStreamSource y createMediaStreamDestination , los cuales son API necesarios para resolver el problema. createMediaStreamSource puede tomar secuencias desde el audio y el micrófono de mi escritorio, y al conectar las dos juntas al objeto creado por createMediaStreamDestination me da la capacidad de canalizar esta secuencia a la API de MediaRecorder .

const mergeAudioStreams = (desktopStream, voiceStream) => {
  const context = new AudioContext();
    
  // Create a couple of sources
  const source1 = context.createMediaStreamSource(desktopStream);
  const source2 = context.createMediaStreamSource(voiceStream);
  const destination = context.createMediaStreamDestination();
  
  const desktopGain = context.createGain();
  const voiceGain = context.createGain();
    
  desktopGain.gain.value = 0.7;
  voiceGain.gain.value = 0.7;
   
  source1.connect(desktopGain).connect(destination);
  // Connect source2
  source2.connect(voiceGain).connect(destination);
    
  return destination.stream.getAudioTracks();
};

Simples

El código completo se puede encontrar en my glitch , y la demostración se puede encontrar aquí: https://screen-record-voice.glitch.me/

{{<fast-youtube oGIdqcMFKlA>}}

About Me: Paul Kinlan

I lead the Chrome Developer Relations team at Google.

We want people to have the best experience possible on the web without having to install a native app or produce content in a walled garden.

Our team tries to make it easier for developers to build on the web by supporting every Chrome release, creating great content to support developers on web.dev, contributing to MDN, helping to improve browser compatibility, and some of the best developer tools like Lighthouse, Workbox, Squoosh to name just a few.