Как управлять аудио из AudioContext.createAnalyser()?

Я работаю с 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);

1 ответ

Я должен признать, что я не знаю библиотеку RTCMultiConnection, которую вы используете, и тем более ее потоковый обработчик, а также где 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., за исключением того, что вы добавите другой gainNode между mediaStreamSource и анализатором:

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: для кросс-браузерной работы вам нужно будет прослушивать volumechange и добавьте gainNode_in, как в 3.:

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>

Другие вопросы по тегам