0

我使用 WebRTC,我正确接收流。如果我发送浏览器,一切正常,但是当我尝试使用 AudioContext-createAnalyser 检查频率时。它也继续工作,但我不再控制音频的音量。在这里我留下代码:

function startUserMedia(stream) {

var canvas, ctx, again, fbc_array, bars = 100, bar_x, bar_width, bar_height;
var context = new AudioContext();
var analyser = context.createAnalyser();


source = context.createMediaStreamSource(stream); 
source.connect(analyser);
analyser.connect(context.destination);

canvas = document.getElementById("analyser");
ctx = canvas.getContext("2d");

frameLooper();

function frameLooper(){

    window.requestAnimationFrame(frameLooper);
    fbc_array = new Uint8Array(analyser.frequencyBinCount);
    analyser.getByteFrequencyData(fbc_array);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "rgb(30, 180, 255)";

    for(var i = 0; i < bars; i++){
        bar_x = i * 3;
        bar_width = 2;
        bar_height = -(fbc_array[i] / 2);
        ctx.fillRect(bar_x, canvas.height, bar_width, bar_height);
    }
}
}

提前致谢

编辑:

var connection = new RTCMultiConnection();
connection.socketURL = 'URL...';

connection.socketMessageEvent = 'message';
connection.session = { audio: true, video: false, oneway: true };
connection.mediaConstraints = { audio: true, video: false }
connection.sdpConstraints.mandatory = { OfferToReceiveAudio: false, OfferToReceiveVideo: false };

connection.onstream = function(event){

    var mediaElement = event.mediaElement;

    mediaElement.muted = true;
    mediaElement.volume = 1;
    mediaElement.id = event.streamid;
    $("#elementHtml").append(mediaElement);

    startUserMedia(event.stream);
4

1 回答 1

0

我不得不承认我不知道您正在使用的RTCMultiConnection 库,更不用说它的onstream处理程序,也不知道它的event.mediaElement来源,所以您可能需要尝试一下。

但我会尝试列举一些基本的方法来做到这一点,不管它是如何event.MediaStream与 MediaStream 相关联的。

  1. 您希望通过屏幕内 MediaElement 的默认控件控制输出音量:在这种情况下,将此 MediaElement 设置srcObject为 MediaStream 并且不要将其静音,并且不要将分析器节点连接到音频上下文的目标:

starter.onclick = function(){
  this.parentNode.removeChild(this);
  getStream(onstream);
 };

function onstream(stream) {
  // Set our in-doc-audio as the audio output
  // I don't know if your event.MediaStream could work as-is... You will have to try.
  var audio = document.querySelector('audio');
  audio.srcObject = stream;
  startUserMedia(stream);
  audio.play();
}


function startUserMedia(stream) {
  var canvas, ctx, again, fbc_array, bars = 100,
    bar_x, bar_width, bar_height;
  var context = new (window.AudioContext || window.webkitAudioContext)();
  var analyser = context.createAnalyser(),

  source = context.createMediaStreamSource(stream);
  source.connect(analyser);
  // In this case we don't connect to the audioCtx destination
  //analyser.connect(context.destination);

  canvas = document.getElementById("analyser");
  ctx = canvas.getContext("2d");

  frameLooper();
  function frameLooper() {
    window.requestAnimationFrame(frameLooper);
    fbc_array = new Uint8Array(analyser.frequencyBinCount);
    analyser.getByteFrequencyData(fbc_array);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "rgb(30, 180, 255)";
    for (var i = 0; i < bars; i++) {
      bar_x = i * 3;
      bar_width = 2;
      bar_height = -(fbc_array[i] / 2);
      ctx.fillRect(bar_x, canvas.height, bar_width, bar_height);
    }
  }
}

// Snippet way to get a MediaStream
function getStream(callback) {
  var aud = new Audio('https://dl.dropboxusercontent.com/s/8c9m92u1euqnkaz/GershwinWhiteman-RhapsodyInBluePart1.mp3?dl=03');
  aud.crossOrigin = true;
  aud.onloadedmetadata = function() {
  	var ctx = new (window.AudioContext || window.webkitAudioContext)(),
    src = ctx.createMediaElementSource(this),
    streamNode = ctx.createMediaStreamDestination();
    src.connect(streamNode);
    callback(streamNode.stream);
  };
  aud.play();
}
#starter ~ *{
    visibility: hidden;
} 
<button id="starter">start</button>
<audio controls></audio>
<canvas id="analyser"></canvas>

  1. 您想通过自制输入来控制输出音量: 然后甚至不要使用 MediaElement,只需创建一个gainNode,您将在其上连接您的 AnalyserNode,并且您将连接到目的地。要控制输出音量,您只需设置gainNode.gain 即可 value

starter.onclick = function(){
  this.parentNode.removeChild(this);
  getStream(startUserMedia);
};

function startUserMedia(stream) {
  var canvas, ctx, again, fbc_array, bars = 100,
    bar_x, bar_width, bar_height;
  var context = new (window.AudioContext || window.webkitAudioContext)();
  var analyser = context.createAnalyser();
  // create a gainNode that will control our output volume
  var gainNode = context.createGain();
  // control it from our <input>
  vol.oninput = function(){
    gainNode.gain.value = this.value;
  };
  source = context.createMediaStreamSource(stream);
  source.connect(analyser);
  // In this case we do connect the analyser output to the gainNode
  analyser.connect(gainNode);
  // and the gainNode to the context's destination
  gainNode.connect(context.destination);

  canvas = document.getElementById("analyser");
  ctx = canvas.getContext("2d");

  frameLooper();
  function frameLooper() {
    window.requestAnimationFrame(frameLooper);
    fbc_array = new Uint8Array(analyser.frequencyBinCount);
    analyser.getByteFrequencyData(fbc_array);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "rgb(30, 180, 255)";
    for (var i = 0; i < bars; i++) {
      bar_x = i * 3;
      bar_width = 2;
      bar_height = -(fbc_array[i] / 2);
      ctx.fillRect(bar_x, canvas.height, bar_width, bar_height);
    }
  }
}

// Snippet way to get a MediaStream
function getStream(callback) {
  var aud = new Audio('https://dl.dropboxusercontent.com/s/8c9m92u1euqnkaz/GershwinWhiteman-RhapsodyInBluePart1.mp3?dl=03');
  aud.crossOrigin = true;
  aud.onloadedmetadata = function() {
  	var ctx = new (window.AudioContext || window.webkitAudioContext)(),
    src = ctx.createMediaElementSource(this),
    streamNode = ctx.createMediaStreamDestination();
    src.connect(streamNode);
    callback(streamNode.stream)
  };
  aud.play();
}
#starter ~ *{
    visibility: hidden;
}
<button id="starter">start</button>
<label>volume: <input type="range" min="0" max="1" value="1" step="0.05" id="vol"></label><br>
<canvas id="analyser"></canvas>

  1. 您想通过自制输入控制输入[和输出] 音量: 就像在2.中一样,除了您将在 mediaStreamSource 和分析器之间添加另一个 gainNode :

starter.onclick = function(){
  this.parentNode.removeChild(this);
  getStream(startUserMedia);
 };

function startUserMedia(stream) {
  var canvas, ctx, again, fbc_array, bars = 100,
    bar_x, bar_width, bar_height;
  var context = new (window.AudioContext || window.webkitAudioContext)();
  var analyser = context.createAnalyser();
  // create two gainNodes
  var gainNode_in = context.createGain();
  vol_in.oninput = function(){
    gainNode_in.gain.value = this.value;
  };
  var gainNode_out = context.createGain();
  vol_out.oninput = function(){
    gainNode_out.gain.value = this.value;
  };
  
  source = context.createMediaStreamSource(stream);
  source.connect(gainNode_in);  // connect to the input gainNode
  gainNode_in.connect(analyser);
  analyser.connect(gainNode_out);
  // and the gainNode to the context's destination
  gainNode_out.connect(context.destination);

  canvas = document.getElementById("analyser");
  ctx = canvas.getContext("2d");

  frameLooper();
  function frameLooper() {
    window.requestAnimationFrame(frameLooper);
    fbc_array = new Uint8Array(analyser.frequencyBinCount);
    analyser.getByteFrequencyData(fbc_array);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "rgb(30, 180, 255)";
    for (var i = 0; i < bars; i++) {
      bar_x = i * 3;
      bar_width = 2;
      bar_height = -(fbc_array[i] / 2);
      ctx.fillRect(bar_x, canvas.height, bar_width, bar_height);
    }
  }
}

// Snippet way to get a MediaStream
function getStream(callback) {
  var aud = new Audio('https://dl.dropboxusercontent.com/s/8c9m92u1euqnkaz/GershwinWhiteman-RhapsodyInBluePart1.mp3?dl=03');
  aud.crossOrigin = true;
  aud.onloadedmetadata = function() {
  	var ctx = new (window.AudioContext || window.webkitAudioContext)(),
    src = ctx.createMediaElementSource(this),
    streamNode = ctx.createMediaStreamDestination();
    src.connect(streamNode);
    callback(streamNode.stream)
  };
  aud.play();
}
#starter ~ *{
    visibility: hidden;
}
<button id="starter">start</button>
<label>volume in: <input type="range" min="0" max="1" value="1" step="0.05" id="vol_in"></label><br>
<label>volume out: <input type="range" min="0" max="1" value="1" step="0.05" id="vol_out"></label><br>
<canvas id="analyser"></canvas>

  1. 您想控制来自 MediaElement的输入音量: 为了获得跨浏览器体验,您将不得不收听元素的,并像3volumechange中一样添加 gainNode_in :

starter.onclick = function(){
  this.parentNode.removeChild(this);
  getStream(onstream);
};

function onstream(stream) {
  var audio = document.querySelector('audio');
  audio.srcObject = stream;
  startUserMedia(stream, audio);
  audio.play();
}


function startUserMedia(stream, audio) {
  var canvas, ctx, again, fbc_array, bars = 100,
    bar_x, bar_width, bar_height;
  var context = new (window.AudioContext || window.webkitAudioContext)();
  var analyser = context.createAnalyser(),
  source = context.createMediaStreamSource(stream),
  gainNode = context.createGain();
  
  audio.onvolumechange = function(){
    gainNode.gain.value = this.volume;
  };
  
  source.connect(gainNode);
  gainNode.connect(analyser);

  canvas = document.getElementById("analyser");
  ctx = canvas.getContext("2d");

  frameLooper();
  function frameLooper() {
    window.requestAnimationFrame(frameLooper);
    fbc_array = new Uint8Array(analyser.frequencyBinCount);
    analyser.getByteFrequencyData(fbc_array);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "rgb(30, 180, 255)";
    for (var i = 0; i < bars; i++) {
      bar_x = i * 3;
      bar_width = 2;
      bar_height = -(fbc_array[i] / 2);
      ctx.fillRect(bar_x, canvas.height, bar_width, bar_height);
    }
  }
}

// Snippet way to get a MediaStream
function getStream(callback) {
  var aud = new Audio('https://dl.dropboxusercontent.com/s/8c9m92u1euqnkaz/GershwinWhiteman-RhapsodyInBluePart1.mp3?dl=03');
  aud.crossOrigin = true;
  aud.onloadedmetadata = function() {
  	var ctx = new (window.AudioContext || window.webkitAudioContext)(),
    src = ctx.createMediaElementSource(this),
    streamNode = ctx.createMediaStreamDestination();
    src.connect(streamNode);
    callback(streamNode.stream)
  };
  aud.play();
}
#starter ~ *{
    visibility: hidden;
} 
<button id="starter">start</button>
<audio controls></audio>
<canvas id="analyser"></canvas>

于 2017-11-07T04:56:17.470 回答