WebRTC中合并多路音频源

chrome中获取系统和麦克风声音并将他们合并到同一个媒体源中。

最近在做webRTC交互时,遇到在屏幕共享中添加声音的需求——需要同时添加系统声音以及麦克风的声音。本文记录一下是如何解决这个问题的。

获取chrome中的媒体

获取摄像头和麦克风:

navigator.mediaDevices.getUserMedia({
    video: true,
    audio: true
}).then(function(stream){
    // ...
})

看一下结果:

获取抓取屏幕(2018年底开始支持):

// chrome中,这里的声音指的是系统声音
navigator.mediaDevices.getDisplayMedia({
    video: true,
    audio: true
}).then(function(stream){
    // ...
})

以下是浏览器获取的结果:

将系统声音和麦克风声音添加到视频中并通过WebRTC传输

一开始想的是想很暴力的直接添加audioTrack来解决:

screen.addTrack(webcam.getAudioTracks()[0]);

添加很成功,然后浏览器获取一个包含两个audiotrack和一个videoTrack的MediaStream对象,浏览器也可以播放:

  var video = document.querySelector('video');
  // 旧的浏览器可能没有srcObject
  if ("srcObject" in video) {
    video.srcObject = stream;
  } else {
    // 防止在新的浏览器里使用它,应为它已经不再支持了
    video.src = window.URL.createObjectURL(stream);
  }
  video.onloadedmetadata = function(e) {
    video.play();
  };

但是通过WebRTC传输时就报错了。

然后就想到能不能将两个audioTrack合并,看了下浏览器的API,于是就有了第二种方案:

const mergeTracks = (baseStrem, extraStream) => {
    if (!baseStrem.getAudioTracks().length){
        baseStrem.addTrack(extraStream.getAudioTracks()[0])
        return baseStrem;
    }
    var context = new AudioContext();
    var baseSource = context.createMediaStreamSource(baseStrem);
    var extraSource = context.createMediaStreamSource(extraStream);
    var dest = context.createMediaStreamDestination();

    var baseGain = context.createGain();
    var extraGain = context.createGain();
    baseGain.gain.value = 0.8;
    extraGain.gain.value = 0.8;

    baseSource.connect(baseGain).connect(dest);
    extraSource.connect(extraGain).connect(dest);

    return new MediaStream([baseStrem.getVideoTracks()[0], dest.stream.getAudioTracks()[0]]);
}

主要就是createMediaStreamSource()createMediaStreamDestination()两个函数,具体介绍可以看啊可能官网,简单的看一下合流的结果:

然后就可以通过WebRTC传输了。
a simple demo

建议不要用于商业用途, 转载请注明原文地址: https://Soo-Q6.github.io/blog/2020-03-29-audiotracks/


© 2019. All rights reserved.

Powered by shouqin v1.0