变量为空(仅在 Mozilla 中)

Variable is null (only in Mozilla)

代码简历如下:

var client = new BinaryClient('ws://localhost:9001');
var context = null;
var store_data  = null;
//(.....)
if (!navigator.getUserMedia)
      navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
    navigator.mozGetUserMedia || navigator.msGetUserMedia;

if (navigator.getUserMedia) {
  navigator.getUserMedia({audio:true}, success, function(e) {
    alert('Error capturing audio.');
  });
} else alert('getUserMedia not supported in this browser.');

function success(e) {
      audioContext = window.AudioContext || window.webkitAudioContext;
      context = new audioContext();
      audioInput = context.createMediaStreamSource(e);
      var bufferSize = 2048;
      store_data = context.createScriptProcessor(bufferSize, 1, 1);
      //(...)
}

//(....)
client.on('open', function() {
    console.log("createStream");
    Stream = client.createStream(command_list);
    var recording = false;

    window.startRecording = function() {
      document.getElementById("startbutton").disabled = true;
      document.getElementById("stopbutton").disabled = false;

      recording = true;
      window.Stream.resume();
    }

    window.stopRecording = function() {
      document.getElementById("startbutton").disabled = false;
      document.getElementById("stopbutton").disabled = true;

      recording = false
      //window.Stream.end();
      window.Stream.pause();
    }

    store_data.onaudioprocess = function(e){ //<---line of the error
        if(!recording) return;
        console.log ('recording');
        var left = e.inputBuffer.getChannelData(0);
        window.Stream.write(convertoFloat32ToInt16(left));
      }
//(..events generated from server..)

在 chrome 中,我的代码工作正常。在 Mozilla 中,我总是得到错误 "store data is undefined"。知道为什么吗?因为我将 store_data 声明为全局的,而当 getusermediasucess 时,值会更改。

不知道是什么调用了 success 函数,因此很难准确地说出,但我相当确定您希望 client.on('open') 侦听器取决于成功函数 运行ning .

我不知道它会如何影响其余省略的代码,但我只会在成功函数具有 运行 并且您确定具有 store_data 已定义。

function success() {
  var client = new BinaryClient('ws://localhost:9001');
  var context = null;
  var store_data  = null;

  // do the original success code here

  // now create that listener.
  client.on('open', function() {
    // do original code here
  });
}

// you probably have a line of code that looks like this
navigator.getUserMedia({}, success);

将所有代码移到成功函数中可能会奏效,但不会很优雅。一旦流程开始工作,我建议重构代码,将每个逻辑位拆分成它自己的函数。

是的,这是一场比赛。您的代码必须等到 getUserMedia 成功 open 被触发。

Promises 是解决这个问题的好方法:

<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

(使用上面的 polyfill 在所有支持的浏览器中访问现代 getUserMedia。)

var client = new BinaryClient('ws://localhost:9001');
var context = null;
var store_data  = null;
//(.....)

var haveStoreData = navigator.mediaDevices.getUserMedia({audio:true})
  .then(function(stream) {
    audioContext = window.AudioContext || window.webkitAudioContext;
    context = new audioContext();
    audioInput = context.createMediaStreamSource(stream);
    var bufferSize = 2048;
    return context.createScriptProcessor(bufferSize, 1, 1);
  });

//(....)
client.on('open', function() {
  console.log("opened");

  haveStoreData.then(function(store_data) {
    console.log("createStream");
    Stream = client.createStream(command_list);
    var recording = false;

    window.startRecording = function() {
      document.getElementById("startbutton").disabled = true;
      document.getElementById("stopbutton").disabled = false;

      recording = true;
      window.Stream.resume();
    };

    window.stopRecording = function() {
      document.getElementById("startbutton").disabled = false;
      document.getElementById("stopbutton").disabled = true;

      recording = false;
      //window.Stream.end();
      window.Stream.pause();
    };

    store_data.onaudioprocess = function(e){
      if(!recording) return;
      console.log ('recording');
      var left = e.inputBuffer.getChannelData(0);
      window.Stream.write(convertoFloat32ToInt16(left));
    };
    //(..events generated from server..)
  })
  .catch(function(e) { console.error(e); });
});

这将使用户有时间在麦克风权限提示中选择 "Allow"(与 Chrome 不同,Firefox 每次都会询问用户权限,除非他们选择 "Always Allow")。

var client = new BinaryClient('ws://193.136.94.233:9001');
var context = null;
var gain = null;
var store_data  = null;
//(.....)

navigator.mediaDevices.getUserMedia({audio:true}) .then( function(stream){ 
context = new AudioContext(); 
audioInput = context.createMediaStreamSource(stream); 
var bufferSize = 4096; 
store_data = context.createScriptProcessor(bufferSize, 1, 1);
biquadFilter = context.createBiquadFilter();
biquadFilter.type = "lowpass";
biquadFilter.frequency.value = 11500;
biquadFilter.Q.value = 3;

ganho = context.createGain();
ganho.gain.value=0.5;

//audioInput.connect(ganho);//compresso
//ganho.connect(recorder);
//recorder.connect(context.destination); 

audioInput.connect(biquadFilter);
biquadFilter.connect(ganho);
ganho.connect(store_data);
store_data.connect(context.destination); 

store_data.onaudioprocess = function(e){
  if(!recording){
    //console.log("nada faz nada desta vida")
    return; 
 }
  console.log ('recording'); 
  var left = e.inputBuffer.getChannelData(0); 
  Stream.write(convertoFloat32ToInt16(left)); 
} 
  //audioInput.connect(store_data); 
} ) .catch( function(e){ console.log(e) } );

//(...)

client.on('open', function() {
    console.log("opened connection");


    //haveStoreData.then(function(store_data) {
    Stream = client.createStream(command_list);
    //recording = false;
//(........)
);

//Other function

这是使用 Chrome Mozilla 使用 BinaryJS 进行流式传输的解决方案。感谢@jib 和@Kaiido