【问题标题】:WebRTC - How to adjust microphone volume on a video stream?WebRTC - 如何调整视频流的麦克风音量?
【发布时间】:2020-09-29 01:32:12
【问题描述】:

我正在尝试调整 WebRTC 聊天应用程序中的麦克风音量,该应用程序使用 2 个视频进行流式传输。 可以修改麦克风的增益吗?如果是,我该如何处理我正在使用的以下流?

/*********************** video call ***************************/
var localStream;

var localVideo = document.getElementById("localVideo");
var remoteVideo = document.getElementById("remoteVideo");
var callButton = document.getElementById("callButton");

var inputLevelSelector = document.getElementById('mic-volume');
var outputLevelSelector = document.getElementById('speaker-volume');
inputLevelSelector.addEventListener('change', changeMicrophoneLevel);
outputLevelSelector.addEventListener('change', changeSpeakerLevel);

callButton.disabled = true;
callButton.onclick = call;

navigator.getUserMedia = navigator.getUserMedia ||
    navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
navigator.getUserMedia({
        audio: true,
        video: true
    }, gotStream, //note that we are adding both audio and video
    function (error) {
        console.log(error);
    });

var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var SessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription;
var pc = new RTCPeerConnection({
    "iceServers": []
});

function gotStream(stream) {
    // localVideo.src = window.URL.createObjectURL(stream); // DEPRECATED
    localVideo.srcObject = stream; // UPDATED
    localStream = stream;
    callButton.disabled = false;
    pc.addStream(stream);
}

pc.onicecandidate = function (event) {
    console.log(event);
    if (!event || !event.candidate) {
        return;
    } else {
        socket.emit("video call", {
            type: "iceCandidate",
            "candidate": event.candidate
        });
    }
};

var remoteStream;
pc.onaddstream = function (event) {
    remoteStream = event.stream;
    var remoteVideo = document.getElementById("remoteVideo");
    // remoteVideo.src = window.URL.createObjectURL(event.stream); // DEPRECATED
    remoteVideo.srcObject = event.stream; // UPDATED
    remoteVideo.play();
};

请注意我是新手,所以放轻松! :)

【问题讨论】:

  • 好像是这样。我怎样才能让它适应 WebRTC?如果我只使用 peerConnection.addStream(dest.stream); 它会抛出以下错误 peerConnection is not defined
  • 这是因为您将对等连接变量命名为 pc 而不是 peerConnection 而引发错误。尽管peerConnection 会是更好的选择,因为每个人都可以通过读取变量的名称来判断值是什么。

标签: javascript google-chrome web web-applications webrtc


【解决方案1】:

在下面,我实现了我在 cmets 中分享的帖子。设置相同,但包含您的代码。

您首先从 Web Audio API 创建节点。因为你想控制流的音量,所以需要MediaStreamAudioSourceNodeMediaStreamAudioDestinationNodeGainNodeMediaStreamAudioSourceNode 是流的入口点。通过在此处注入它,我们可以通过增益连接它。流将通过GainNode 控制音量,然后传递到MediaStreamAudioDestinationNode,您可以在RTC 客户端中再次使用流。

从那里使用您从MediaStreamAudioDestinationNode.stream 属性获得的流。

编辑:

原来MediaStreamAudioDestinationNode.stream 是一个只有一个音轨的MediaStream 对象。因此视频已从流中删除,必须重新加入。

因此,当您能够访问流时,请从流中获取视频轨道并将它们存储在一个变量中。然后在通过 Web Audio API 传递流后,将视频轨道与通过 GainNode 的音频轨道连接起来。

var inputLevelSelector = document.getElementById('mic-volume');

// Renamed the variable after your comment.
var peerConnection = new RTCPeerConnection({
    "iceServers": []
});

function gotStream(stream) {

  // Get the videoTracks from the stream.
  const videoTracks = stream.getVideoTracks();

  /**
   * Create a new audio context and build a stream source,
   * stream destination and a gain node. Pass the stream into 
   * the mediaStreamSource so we can use it in the Web Audio API.
   */
  const context = new AudioContext();
  const mediaStreamSource = context.createMediaStreamSource(stream);
  const mediaStreamDestination = context.createMediaStreamDestination();
  const gainNode = context.createGain();

  /**
   * Connect the stream to the gainNode so that all audio
   * passes through the gain and can be controlled by it.
   * Then pass the stream from the gain to the mediaStreamDestination
   * which can pass it back to the RTC client.
   */
  mediaStreamSource.connect(gainNode);
  gainNode.connect(mediaStreamDestination);

  /**
   * Change the gain levels on the input selector.
   */
  inputLevelSelector.addEventListener('input', event => {
    gainNode.gain.value = event.target.value;
  });

  /**
   * The mediaStreamDestination.stream outputs a MediaStream object
   * containing a single AudioMediaStreamTrack. Add the video track
   * to the new stream to rejoin the video with the controlled audio.
   */
  const controlledStream = mediaStreamDestination.stream;
  for (const videoTrack of videoTracks) {
    controlledStream.addTrack(videoTrack);
  }

  /**
   * Use the stream that went through the gainNode. This
   * is the same stream but with altered input volume levels.
   */
  localVideo.srcObject = controlledStream;
  localStream = controlledStream;
  peerConnection.addStream(controlledStream);
  callButton.disabled = false;

}

【讨论】:

  • 感谢您的宝贵时间,非常感谢!虽然只是显示音频,但我希望同时拥有音频和视频。
  • 尝试将localVideo.srcObject 流改回原来的stream 值,就像以前一样。更改流可能会弄乱视频。 localVideo.srcObject = stream.
  • localStream 现在可以(视频),但 remoteStream 也只是音频而不是视频。
  • 我已经调查过了。似乎当您通过 Web Audio API 传递流时,只返回音轨。因此,您需要先获取视频轨道并将它们添加到音频轨道以重新创建流。换句话说:视频和音频被拆分,需要重新加入以形成一个包含音频和视频的流。试试看。我很好奇它是否能解决您的问题。
  • 我也在想同样的事情。似乎我必须从流中删除音频并添加获得的音频,尽管我不知道如何做到这一点:/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-23
  • 2021-05-12
  • 2014-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多