Аудио из RTCPeerConnection не слышно после обработки в AudioContext

#javascript #google-chrome #webrtc #web-audio-api

#javascript #google-chrome #webrtc #web-audio-api

Вопрос:

У меня активен RTCPeerConnection . Я хочу обработать этот звук. Я создаю new AudioContext() , а затем новые узлы: MediaStreamAudioSourceNode для MediaStreamAudioDestinationNode

После подключения MediaStreamAudioSourceNode к MediaStreamAudioDestinationNode я не слышу аудио.

MediaStreamAudioDestinationNode подключено к Audio элементу.

  • Я попробовал подключиться напрямую MediaStream из RTCPeerConnection to Audio , и это работает
  • Я также пробовал подключиться MediaStreamAudioSourceNode.mediaStream к Audio элементу, и это тоже работает.
  • Я подключил MediaStream возвращенный, getUserMedia() и он работает даже с MediaStreamAudioDestinationNode

Похоже, что только MediaStream с помощью from RTCPeerConnection не работает MediaStreamAudioDestinationNode .

   function play(eventWebRtcPeerConnection) {
    const audio = new Audio()
    const ctx = new AudioContext();

    let mediaStream = new MediaStream();
    eventWebRtcPeerConnection.streams[0].getAudioTracks().forEach(track => mediaStream.addTrack(track));

    // create source and destination and connect them
    const msSource = ctx.createMediaStreamSource(mediaStream);
    const msDestination = ctx.createMediaStreamDestination();
    msSource.connect(msDestination);

    // play media stream on Audio object
    audio.srcObject = msDestination.stream; // does not work
    // audio.srcObject = msSource.mediaStream; // works

    audio.oncanplay = async () => {
      audio.muted = false;
      await audio.play();
    }

  }
 

Я ожидаю услышать звук после подключения MediaStreamAudioSourceNode MediaStreamAudioDestinationNode .

Комментарии:

1. Это известная проблема bugs.chromium.org/p/chromium/issues/detail?id=933677

Ответ №1:

Несколько запутанный ответ заключается в том, что, по крайней мере, Chrome требует, чтобы вы напрямую подключали медиапоток, поступающий из соединения WebRTC, к аудиоэлементу. Я не уверен, является ли это ошибкой или особенностью. Хорошей новостью является то, что вы можете отключить этот аудиоэлемент. Тогда ваш код будет выглядеть следующим образом:

 const mutedAudio = new Audio();
const outputAudio = new Audio();
const context = new AudioContext();
const mediaStream = new MediaStream();

peerConnection.streams[0].getAudioTracks().forEach(track => mediaStream.addTrack(track));

mutedAudio.muted = true;
mutedAudio.srcObject = mediaStream;
mutedAudio.play();

const source = context.createMediaStreamSource(mediaStream);
const destination = context.createMediaStreamDestination();

source.connect(destination);

outputAudio.muted = false;
outputAudio.srcObject = msDestination.stream;
outputAudio.play();
 

Вы также можете пропустить outputAudio элемент и подключить source непосредственно к destination context .

Комментарии:

1. У вас есть ссылка на что-нибудь, объясняющее обоснование этого ограничения? Ваш ответ спас меня от вопроса, почему это не работает. Является ли это лучшим решением для решения этой проблемы?

2. Эта проблема, по крайней мере, косвенно ссылается на проблему: bugs.chromium.org/p/chromium/issues/detail?id=687574 Я не знаю никакого другого обходного пути.

3. Вау. Спасибо @chrisguttandin. Вы только что спасли мне всю ночь!

4. для меня даже не нужно воспроизводить «поддельный» звук, просто нужно создать new MediaStream() , назначить его как a srcObject и добавить в него любую дорожку