将音频元素混合到一个流目标中以与MediaRecorder一起使用

时间:2019-01-09 16:35:27

标签: javascript html5 html5-audio web-audio web-audio-api

MediaRecorder仅允许您记录每个轨道一种类型的媒体。因此,我使用JQuery来获取所有音频元素的列表,并将它们连接到相同的音频上下文目标,以便将所有音频轨道混合到一个音频流中,以便稍后由MediaRecorder记录。到目前为止,我的作品行之有效,但仅能捕捉到第一首曲目,而没有其他曲目。

知道为什么只有一条音轨通过吗?

我的代码:

function gettracks(stream){
    var i = 0;
    var audioTrack ;
    var audioctx = new AudioContext();
    var SourceNode = [];
    var  dest = audioctx.createMediaStreamDestination();
    $('audio').each( function() {

    //the audio element id
    var afid = $(this).attr('id');

    var audio = $('#'+afid)[0];
    console.log('audio id '+ afid+' Audio= '+audio);
    SourceNode[i] = audioctx.createMediaElementSource(audio);

    //dont forget to connect the wires!
    SourceNode[i].connect(audioctx.destination);
    SourceNode[i].connect(dest);


      audioTrack = dest.stream.getAudioTracks()[0];
    stream.addTrack(audioTrack);
    i++;
    });
    }


//from a mousedown event I call
stream = canvas.captureStream();
video.srcObject = stream;

gettracks(stream);
startRecording()
    function startRecording() {
          recorder = new MediaRecorder(stream, {
        mimeType: 'video/webm'
      });
      recorder.start();
    }

2 个答案:

答案 0 :(得分:0)

我会这样:

var ac = new AudioContext();
var mediaStreamDestination = new MediaStreamAudioDestinationNode(ac);
document.querySelectorAll("audio").forEach((e) => {
  var mediaElementSource = new MediaElementAudioSourceNode(ac, { mediaElement: e });
  mediaElementSource.connect(mediaStreamDestination);
});
console.log(mediaStreamDestination.stream.getAudioTracks()[0]); // give this to MediaRecorder

打破上述规定:

  • var ac = new AudioContext();:创建一个AudioContext,以便能够将音频路由到默认音频输出以外的其他地方。
  • 从此var mediaStreamDestination = new MediaStreamAudioDestinationNode(ac);中的
  • AudioContext,得到一种特殊类型的DestinationNode,该类型将AudioContext的输出发送到音频输出设备,而不是将其发送到音频输出设备。一个MediaStream,可保留单个音频轨道。
  • document.querySelectorAll("audio").forEach((e) => {,获取所有<audio>元素,然后对其进行迭代。
  • var mediaElementSource = new MediaElementAudioSourceNode(ac, { mediaElement: e });,对于每个媒体元素,捕获其输出并将其路由到AudioContext。这会给您AudioNode
  • mediaElementSource.connect(mediaStreamDestination);,连接具有媒体元素输出的AudioNode,然后将其连接到到达MediaStream的目的地。
  • mediaStreamDestination.stream.getAudioTracks()[0]从此MediaStreamTrack获得第一音频MediaStream。反正只有一个。

现在,我想您可以做类似stream.addTrack(mediaStreamDestination.stream.getAudioTracks()[0])的操作,并传入上面的音频轨道。

答案 1 :(得分:0)

如果您创建增益节点并将源节点连接到该节点,该怎么办?

var gain = audioctx.createGain();
gain.connect(dest);

并在循环中

SourceNode[i].connect(gain);

然后,您的源将流入一个增益节点,该节点将流向您的目的地。