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

У меня есть цель создать самое простое в мире программное обеспечение для записи экрана, и я последние несколько месяцев медленно слоняюсь по проекту (я имею в виду очень медленно).

В предыдущих постах я получил screen recording and a voice overlay , возившись с потоками из всех входных источников. Однако одной из проблем было то, что я не мог понять, как получить звук с рабочего стола * и * наложить звук из динамика. Я наконец-то понял, как это сделать.

Во-первых, getDisplayMedia в Chrome теперь позволяет захватывать звук, в Spec есть странный недосмотр, поскольку он не позволяет вам указывать audio: true в вызове функции, теперь вы можете это сделать.

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

Во-вторых, я изначально думал, что, создав две дорожки в аудиопотоке, я смогу получить то, что хотел, однако я узнал, что API-интерфейс MediaRecorder Chrome может выводить только одну дорожку, а во- MediaRecorder , это не сработало бы, потому что дорожки похожи на аудиофонограммы DVD, которые могут воспроизводить только одна.

Решение, вероятно, простое для многих людей, но для меня оно было новым: используйте Web Audio.

Оказывается, в API WebAudio есть createMediaStreamSource и createMediaStreamDestination , оба из которых необходимы API для решения проблемы. createMediaStreamSource может принимать потоки с моего настольного аудио и микрофона, и, соединяя их вместе в объект, созданный createMediaStreamDestination он дает мне возможность MediaRecorder этот поток в API 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.

Полный код можно найти на my glitch , а демоверсию можно найти здесь: 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.